@@ -656,3 +656,40 @@ def test_binary_data_handling(self):
656656 dangerous_binary = b"dangerous\x00 data\x01 with\x02 control"
657657 with pytest .raises (ValueError , match = "dangerous" ):
658658 _validate_header_value (dangerous_binary , allow_binary = True )
659+
660+ def test_header_format_crlf_injection_protection (self ):
661+ """Test that header format strings with CRLF sequences are rejected."""
662+ from google .adk .tools .mcp_tool .mcp_toolset import create_session_state_header_provider
663+ from google .adk .tools .mcp_tool ._internal import validate_header_format
664+
665+ # Valid format strings should be accepted
666+ valid_formats = [
667+ "Bearer {value}" ,
668+ "Basic {value}" ,
669+ "key:{value}" ,
670+ "Token {value}" ,
671+ "{value}" ,
672+ ]
673+ for fmt in valid_formats :
674+ validate_header_format (fmt ) # Should not raise
675+
676+ # Format strings with CRLF should be rejected
677+ invalid_formats = [
678+ "Bearer {value}\r \n X-Injected: evil" ,
679+ "Bearer {value}\n Injected-Header: bad" ,
680+ "Bearer {value}\r Another: header" ,
681+ "Bearer {value}\r \n " ,
682+ "Bearer {value}\n " ,
683+ "Bearer {value}\r " ,
684+ ]
685+ for fmt in invalid_formats :
686+ with pytest .raises (ValueError , match = "CRLF" ):
687+ validate_header_format (fmt )
688+
689+ # Test that create_session_state_header_provider validates format
690+ with pytest .raises (ValueError , match = "CRLF" ):
691+ create_session_state_header_provider (
692+ state_key = "token" ,
693+ header_name = "Authorization" ,
694+ header_format = "Bearer {value}\r \n X-Injected: evil"
695+ )
0 commit comments