def getMemberGood(name) -> HtmlSanitizedStr: """ Sanitizes while maintaining functionality. This should get a pass from type checker and semgrep """ out: HtmlSanitizedStr = sanitize_for_html(name) + LiteralStr('</string:name>') return out
def getMemberBad5(name) -> HtmlSanitizedStr: """ partial sanitization, this should be caught by type checker """ out = sanitize_for_html(name) + str(Flask) + LiteralStr('</string:name>') # Python lets you run code that doesn't type check. We can raise an error at runtime if we want to prevent this. # assert isinstance(out, HtmlSanitizedStr) return out
def getMemberBad4(name) -> HtmlSanitizedStr: """ Violates usage requirement of LiteralStr. This should be caught by semgrep. """ fake_literal_str = LiteralStr(str(Flask)) out = sanitize_for_html(name) + fake_literal_str + LiteralStr('</string:name>') return out
def getMemberBad3(name) -> HtmlSanitizedStr: """ sanitizes, but loses functionality. """ return sanitize_for_html(f"{name}</string:name>")
# in IntelliJ IDEA / PyCharm, use View -> Type Info to resolve and show types a_normal_str = 'x' + LiteralStr('y') # type checker should resolve to normal str assert type(a_normal_str) == str, type(a_normal_str) a_literal_str = LiteralStr('x') + LiteralStr('y') # type checker should resolve to LiteralStr assert type(a_literal_str) == LiteralStr # type checker should resolve to SanitizedStr a_sanitized_str = LiteralStr('x') + SanitizedStr('y') assert type(a_sanitized_str) == SanitizedStr a_sanitized_str_2 = SanitizedStr('x') + LiteralStr('y') assert type(a_sanitized_str_2) == SanitizedStr # type checker should resolve to HtmlSanitizedStr an_html_sanitized_str_a = LiteralStr('x') + sanitize_for_html('y') assert type(an_html_sanitized_str_a) == HtmlSanitizedStr an_html_sanitized_str_b = sanitize_for_html('x') + LiteralStr('y') assert type(an_html_sanitized_str_b) == HtmlSanitizedStr # Should emit double sanitization warning. # Also does not type check if not `issubclass(HtmlSanitizedStr, str)`. (You can decide in `base_str.py`.) sanitize_for_html(sanitize_for_html('a')) # Note that semgrep rule should flag this call to `HtmlSanitizedStr`. HtmlSanitizedStr('x') # You can try running the app if you really want by setting environment var `REALLY_RUN_APP=True`. if environ.get('REALLY_RUN_APP', 'False') == 'True': app.run()