javascript.browser.security.insufficient-postmessage-origin-validation.insufficient-postmessage-origin-validation

profile photo of semgrepsemgrep
Author
2,063
Download Count*

No validation of origin is done by the addEventListener API. It may be possible to exploit this flaw to perform Cross Origin attacks such as Cross-Site Scripting(XSS).

Run Locally

Run in CI

Defintion

rules:
  - id: insufficient-postmessage-origin-validation
    message: No validation of origin is done by the addEventListener API. It may be
      possible to exploit this flaw to perform Cross Origin attacks such as
      Cross-Site Scripting(XSS).
    metadata:
      owasp:
        - A08:2021 - Software and Data Integrity Failures
      cwe:
        - "CWE-345: Insufficient Verification of Data Authenticity"
      category: security
      technology:
        - browser
      subcategory:
        - audit
      likelihood: LOW
      impact: LOW
      confidence: LOW
      references:
        - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Improper Authentication
    languages:
      - javascript
      - typescript
    severity: WARNING
    pattern-either:
      - patterns:
          - pattern: |
              window.addEventListener('message', $FUNC, ...)
          - metavariable-pattern:
              patterns:
                - pattern: |
                    function($OBJ) { ... }
                - pattern-not: >
                    function($OBJ) { ... if (<... $OBJ.origin ...>) { ... } ... }
              metavariable: $FUNC
      - patterns:
          - pattern-either:
              - pattern-inside: |
                  function $FNAME($OBJ) { $CONTEXT }
                  ...
              - pattern-inside: |
                  $FNAME = (...) => { $CONTEXT }
                  ...
          - pattern: |
              window.addEventListener('message', $FNAME,...)
          - metavariable-pattern:
              patterns:
                - pattern-not: |
                    ... if (<... $OBJ.origin ...>) { ... } ...
              metavariable: $CONTEXT

Examples

insufficient-postmessage-origin-validation.js

// ruleid: insufficient-postmessage-origin-validation
window.addEventListener("message", function (evt) {
  console.log('Inline without origin check!');
});

function oldHandler(evt) {
  console.log('Normal function handler without origin check!');
};

// ruleid: insufficient-postmessage-origin-validation
window.addEventListener("message", oldHandler, false);

// ruleid: insufficient-postmessage-origin-validation
window.addEventListener('message', (evt) => {
  console.log('Inline arrow function without origin check!');
});

// ruleid: insufficient-postmessage-origin-validation
window.addEventListener('message', evt => {
  console.log('Inline arrow function without parenthesis & origin check!');
});

const handler = (evt) => {
  console.log('Arrow function handler without origin check!');
};

// ruleid: insufficient-postmessage-origin-validation
window.addEventListener("message", handler, false);

// ok: insufficient-postmessage-origin-validation
window.addEventListener("message", function (evt) {
  if (evt.origin == "http://example.com") {
    console.log('Normal inline function declaration with origin validation');
  }
});

// ok: insufficient-postmessage-origin-validation
function normalHandler(evt) {
  if (evt.origin == "http://example.com") {
    console.log('Normal function handler with origin validation');
  }
};

window.addEventListener('message', normalHandler, false);

// ok: insufficient-postmessage-origin-validation
window.addEventListener('message', (evt) => {
  if (evt.origin !== "http://example.com") {
    console.log('Inline arrow function declaration with origin validation');
  }
});

// ok: insufficient-postmessage-origin-validation
const arrowHandler = (evt) => {
  if (evt.origin == "http://example.com") {
    console.log('Arrow function handler with origin validation');
  }
};

window.addEventListener('message', arrowHandler, false);

const globalRegex = RegExp('/^http://www\.example\.com$/', 'g');

// ok: insufficient-postmessage-origin-validation
window.addEventListener("message", (evt) => {
  if (globalRegex.test(evt.origin)) {
    console.log(message.data);
  }
});