python.django.security.audit.xss.formathtml-fstring-parameter.formathtml-fstring-parameter

profile photo of semgrepsemgrep
Author
2,519
Download Count*

Passing a formatted string as first parameter to format_html disables the proper encoding of variables. Any HTML in the first parameter is not encoded. Using a formatted string as first parameter obscures which parameters are encoded. Correct use of format_html is passing a static format string as first parameter, and the variables to substitute as subsequent parameters.

Run Locally

Run in CI

Defintion

rules:
  - id: formathtml-fstring-parameter
    message: Passing a formatted string as first parameter to `format_html` disables
      the proper encoding of variables. Any HTML in the first parameter is not
      encoded. Using a formatted string as first parameter obscures which
      parameters are encoded. Correct use of `format_html` is passing a static
      format string as first parameter, and the variables to substitute as
      subsequent parameters.
    metadata:
      cwe:
        - "CWE-79: Improper Neutralization of Input During Web Page Generation
          ('Cross-site Scripting')"
      owasp:
        - A07:2017 - Cross-Site Scripting (XSS)
        - A03:2021 - Injection
      references:
        - https://docs.djangoproject.com/en/3.2/ref/utils/#django.utils.html.format_html
      category: security
      technology:
        - django
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - audit
      likelihood: LOW
      impact: MEDIUM
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Cross-Site-Scripting (XSS)
    languages:
      - python
    severity: WARNING
    pattern-either:
      - pattern: format_html(<... f"..." ...>, ...)
      - pattern: format_html("..." % ..., ...)
      - pattern: format_html("...".format(...), ...)

Examples

formathtml-fstring-parameter.py

from django.utils.html import format_html

planet = "world"
markup = "<marquee>" + planet

#############################################################

# ok: formathtml-fstring-parameter
print(format_html("hello {}", markup))
# ok: formathtml-fstring-parameter
print(format_html("hello {}", "<marquee>world"))
# ok: formathtml-fstring-parameter
print(format_html("hello {}", "<marquee>" "world"))
# ok: formathtml-fstring-parameter
print(format_html("hello {}", "<marquee>" + "world"))
# ok: formathtml-fstring-parameter
print(format_html("hello {}", f"<marquee>{planet}"))
# ok: formathtml-fstring-parameter
print(format_html("hello {}", "<marquee>%s" % planet))
# ok: formathtml-fstring-parameter
print(format_html("hello {}", "<marquee>{}".format(planet)))
# ok: formathtml-fstring-parameter
print(format_html("hello " "{}", "<marquee>world"))
# ok: formathtml-fstring-parameter
print(format_html("hello " + "{}", "<marquee>world"))

#############################################################

# ruleid: formathtml-fstring-parameter
print(format_html("hello %s" % markup))
# ruleid: formathtml-fstring-parameter
print(format_html(f"hello {markup}"))
# ruleid: formathtml-fstring-parameter
print(format_html("hello {}".format(markup)))
# ruleid: formathtml-fstring-parameter
print(format_html("hello %s {}" % markup, markup))
# ruleid: formathtml-fstring-parameter
print(format_html(f"hello {markup} {{}}", markup))
# ruleid: formathtml-fstring-parameter
print(format_html("hello {} {{}}".format(markup), markup))