@@ -33,8 +33,28 @@ def _add_field_value(self, field_name: str, value: Union[str, bytes]) -> None:
3333 else :
3434 self ._storage [field_name ].append (value )
3535
36- def get (self , field_name : str , default : Any = None ) -> Union [str , bytes , None ]:
36+ @staticmethod
37+ def _encode_html_entities (value ):
38+ """Encodes unsafe HTML characters."""
39+ return (
40+ str (value )
41+ .replace ("&" , "&" )
42+ .replace ("<" , "<" )
43+ .replace (">" , ">" )
44+ .replace ('"' , """ )
45+ .replace ("'" , "'" )
46+ )
47+
48+ def get (
49+ self , field_name : str , default : Any = None , * , safe = True
50+ ) -> Union [str , bytes , None ]:
3751 """Get the value of a field."""
52+ if safe :
53+ return self ._encode_html_entities (
54+ self ._storage .get (field_name , [default ])[0 ]
55+ )
56+
57+ _debug_warning_nonencoded_output ()
3858 return self ._storage .get (field_name , [default ])[0 ]
3959
4060 def get_list (self , field_name : str ) -> List [Union [str , bytes ]]:
@@ -348,3 +368,12 @@ def _parse_headers(header_bytes: bytes) -> Headers:
348368 for name , value in [header_line .split (": " , 1 )]
349369 }
350370 )
371+
372+
373+ def _debug_warning_nonencoded_output ():
374+ """Warns about XSS risks."""
375+ print (
376+ "WARNING: Setting safe to False makes XSS vulnerabilities possible by "
377+ "allowing access to raw untrusted values submitted by users. If this data is reflected "
378+ "or shown within HTML without proper encoding it could enable Cross-Site Scripting."
379+ )
0 commit comments