javascript.aws-lambda.security.tainted-html-string.tainted-html-string

profile photo of returntocorpreturntocorp
Author
unknown
Download Count*

Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates which will safely render HTML instead.

Run Locally

Run in CI

Defintion

rules:
  - id: tainted-html-string
    message: Detected user input flowing into a manually constructed HTML string.
      You may be accidentally bypassing secure methods of rendering HTML by
      manually constructing HTML and this could create a cross-site scripting
      vulnerability, which could let attackers steal sensitive user data. To be
      sure this is safe, check that the HTML is rendered safely. Otherwise, use
      templates which will safely render HTML instead.
    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
      category: security
      technology:
        - aws-lambda
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - vuln
      likelihood: MEDIUM
      impact: MEDIUM
      confidence: MEDIUM
      references:
        - https://owasp.org/Top10/A03_2021-Injection
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
    languages:
      - javascript
      - typescript
    severity: WARNING
    mode: taint
    pattern-sources:
      - patterns:
          - pattern-either:
              - pattern-inside: |
                  exports.handler = function ($EVENT, ...) {
                    ...
                  }
              - pattern-inside: |
                  function $FUNC ($EVENT, ...) {...}
                  ...
                  exports.handler = $FUNC
              - pattern-inside: |
                  $FUNC = function ($EVENT, ...) {...}
                  ...
                  exports.handler = $FUNC
          - pattern: $EVENT
    pattern-sinks:
      - patterns:
          - pattern-either:
              - patterns:
                  - pattern-either:
                      - pattern: |
                          "$HTMLSTR" + $EXPR
                      - pattern: |
                          "$HTMLSTR".concat(...)
                      - pattern: $UTIL.format($HTMLSTR, ...)
                      - pattern: format($HTMLSTR, ...)
                  - metavariable-pattern:
                      metavariable: $HTMLSTR
                      language: generic
                      pattern: <$TAG ...
              - patterns:
                  - pattern: |
                      `...${...}...`
                  - pattern-regex: |
                      .*<\w+.*
          - pattern-not-inside: |
              console.$LOG(...)

Examples

tainted-html-string.js

const {format} = require('util');

exports.handler = async function (event, context) {
  // ruleid: tainted-html-string
  await sendThisHtmlSomewhere(`<h1>message: ${event.name}</h1>`)
  
  // ruleid: tainted-html-string
  const htmlResult = "<h1>" + "message: " + event['message'] + "</h1>";

  let html = "<h1> message"
  // ruleid: tainted-html-string
  html = html.concat(event.message)
  html = html.concat("</h1>")
  doSmth(html)

  // ruleid: tainted-html-string
  foobar(format('<div>Message: %s</div>', event.body.name))

  // ok: tainted-html-string
  foobar(format('Message: %s', event.body.name))

  // ok: tainted-html-string
  console.log('<div>Message: %s</div>', event.body.name)
  
  // ok: tainted-html-string
  console.error(`<h1>message: ${event.name}</h1>`)

  return { body: htmlResult }
}