44 SubscribeMessage ,
55 WebSocketGateway ,
66} from "@nestjs/websockets" ;
7+ import { timingSafeEqual } from "crypto" ;
78import WebSocket from "ws" ;
89import { Request } from "express" ;
910import { ModuleRef } from "@nestjs/core" ;
@@ -29,37 +30,58 @@ export class MatchEventsGateway {
2930 private readonly cache : CacheService ,
3031 ) { }
3132
33+ private safeCompare ( a : string , b : string ) : boolean {
34+ if ( a . length !== b . length ) return false ;
35+ return timingSafeEqual ( Buffer . from ( a ) , Buffer . from ( b ) ) ;
36+ }
37+
3238 async handleConnection (
3339 @ConnectedSocket ( ) client : WebSocket . WebSocket ,
3440 request : Request ,
3541 ) {
3642 try {
3743 const authHeader = request . headers . authorization ;
3844
39- if ( authHeader && authHeader . startsWith ( "Basic " ) ) {
40- const base64Credentials = authHeader . split ( " " ) . at ( 1 ) ;
45+ if ( ! authHeader || ! authHeader . startsWith ( "Basic " ) ) {
46+ client . close ( ) ;
47+ return ;
48+ }
49+
50+ const base64Credentials = authHeader . split ( " " ) . at ( 1 ) ;
51+ if ( ! base64Credentials ) {
52+ client . close ( ) ;
53+ return ;
54+ }
55+
56+ const decoded = Buffer . from ( base64Credentials , "base64" ) . toString ( ) ;
57+ const colonIndex = decoded . indexOf ( ":" ) ;
58+ if ( colonIndex === - 1 ) {
59+ client . close ( ) ;
60+ return ;
61+ }
4162
42- const [ serverId , apiPassword ] = Buffer . from ( base64Credentials , "base64" )
43- . toString ( )
44- . split ( ":" ) ;
63+ const serverId = decoded . substring ( 0 , colonIndex ) ;
64+ const apiPassword = decoded . substring ( colonIndex + 1 ) ;
4565
46- const { servers_by_pk } = await this . hasura . query ( {
47- servers_by_pk : {
48- __args : {
49- id : serverId ,
50- } ,
51- id : true ,
52- api_password : true ,
66+ const { servers_by_pk } = await this . hasura . query ( {
67+ servers_by_pk : {
68+ __args : {
69+ id : serverId ,
5370 } ,
71+ id : true ,
72+ api_password : true ,
73+ } ,
74+ } ) ;
75+
76+ if (
77+ ! servers_by_pk ?. api_password ||
78+ ! this . safeCompare ( servers_by_pk . api_password , apiPassword )
79+ ) {
80+ client . close ( ) ;
81+ this . logger . warn ( "game server auth failure" , {
82+ serverId,
83+ ip : request . headers [ "cf-connecting-ip" ] ,
5484 } ) ;
55-
56- if ( servers_by_pk ?. api_password !== apiPassword ) {
57- client . close ( ) ;
58- this . logger . warn ( "game server auth failure" , {
59- serverId,
60- ip : request . headers [ "cf-connecting-ip" ] ,
61- } ) ;
62- }
6385 }
6486 } catch {
6587 client . close ( ) ;
0 commit comments