@@ -271,10 +271,18 @@ private function convertSwooleRequestToSymfony($swooleRequest): Request
271271 $ headers = $ swooleRequest ->header ?? [];
272272 $ server = $ swooleRequest ->server ?? [];
273273
274+ // Validate and sanitize input to prevent header injection
275+ $ maxHeaderLength = 8192 ; // RFC 7230 limit
276+ $ maxUriLength = 8192 ; // RFC 7230 limit
277+
274278 // Convert Swoole server variables to PHP $_SERVER format
275279 $ serverVars = [];
276280 foreach ($ server as $ key => $ value ) {
277- $ serverVars [\strtoupper ($ key )] = $ value ;
281+ // Sanitize key
282+ $ key = \strtoupper ((string ) $ key );
283+ // Sanitize value - prevent header injection
284+ $ value = \is_string ($ value ) ? \substr ((string ) $ value , 0 , $ maxHeaderLength ) : $ value ;
285+ $ serverVars [$ key ] = $ value ;
278286 }
279287
280288 // Add headers to server vars
@@ -283,13 +291,19 @@ private function convertSwooleRequestToSymfony($swooleRequest): Request
283291 $ serverVars [$ key ] = $ value ;
284292 }
285293
286- // Set basic server vars
287- $ serverVars ['REQUEST_METHOD ' ] = $ server ['request_method ' ] ?? 'GET ' ;
288- $ serverVars ['REQUEST_URI ' ] = $ server ['request_uri ' ] ?? '/ ' ;
294+ // Set basic server vars with validation
295+ $ requestUri = $ server ['request_uri ' ] ?? '/ ' ;
296+ // Validate URI length
297+ if (\strlen ($ requestUri ) > $ maxUriLength ) {
298+ $ requestUri = \substr ($ requestUri , 0 , $ maxUriLength );
299+ }
300+
301+ $ serverVars ['REQUEST_METHOD ' ] = \strtoupper ($ server ['request_method ' ] ?? 'GET ' );
302+ $ serverVars ['REQUEST_URI ' ] = $ requestUri ;
289303 $ serverVars ['SERVER_PROTOCOL ' ] = $ server ['server_protocol ' ] ?? 'HTTP/1.1 ' ;
290304 $ serverVars ['SERVER_NAME ' ] = $ server ['server_name ' ] ?? 'localhost ' ;
291- $ serverVars ['SERVER_PORT ' ] = $ server ['server_port ' ] ?? 80 ;
292- $ serverVars ['QUERY_STRING ' ] = $ server ['query_string ' ] ?? '' ;
305+ $ serverVars ['SERVER_PORT ' ] = ( int ) ( $ server ['server_port ' ] ?? 80 ) ;
306+ $ serverVars ['QUERY_STRING ' ] = \substr (( string ) ( $ server ['query_string ' ] ?? '' ), 0 , $ maxHeaderLength ) ;
293307
294308 // Handle content type for POST requests
295309 if (isset ($ headers ['content-type ' ])) {
@@ -335,6 +349,22 @@ private function sendResponse($swooleResponse, Response $response): void
335349 }
336350 }
337351
352+ // Add security headers if not already set (only in production)
353+ if (!$ this ->kernel ->isDebug ()) {
354+ $ securityHeaders = [
355+ 'X-Content-Type-Options ' => 'nosniff ' ,
356+ 'X-Frame-Options ' => 'DENY ' ,
357+ 'X-XSS-Protection ' => '1; mode=block ' ,
358+ 'Referrer-Policy ' => 'strict-origin-when-cross-origin ' ,
359+ ];
360+
361+ foreach ($ securityHeaders as $ header => $ value ) {
362+ if (!$ response ->headers ->has ($ header )) {
363+ $ swooleResponse ->header ($ header , $ value );
364+ }
365+ }
366+ }
367+
338368 // Get content
339369 $ content = $ response ->getContent ();
340370
0 commit comments