contrib.nodejsscan.header_xss_protection.header_xss_generic

profile photo of returntocorpreturntocorp
Author
99
Download Count*
License

X-XSS-Protection header is set to 0. This will disable the browser's XSS Filter.

Run Locally

Run in CI

Defintion

rules:
  - id: header_xss_generic
    message: X-XSS-Protection header is set to 0. This will disable the browser's
      XSS Filter.
    severity: ERROR
    metadata:
      likelihood: LOW
      impact: LOW
      confidence: LOW
      category: security
      cwe:
        - "CWE-693: Protection Mechanism Failure"
      technology:
        - web
      references:
        - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
      subcategory:
        - audit
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
    languages:
      - javascript
    patterns:
      - pattern-either:
          - pattern-inside: function ($REQ, $RES, ...) {...}
          - pattern-inside: function $FUNC($REQ, $RES, ...) {...}
          - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
          - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
          - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
      - pattern-either:
          - pattern: |
              $RES.header("=~/x-xss-protection/i", 0, ...)
          - pattern: |
              $RES.set("=~/x-xss-protection/i", 0, ...)
          - pattern: |
              $RES.set(..., { "=~/x-xss-protection/i" : 0 }, ...)
          - pattern: |
              $RES.writeHead(..., {"=~/x-xss-protection/i": 0 }, ...)

Examples

header_xss_protection.js

const express = require('express');
const lusca = require('lusca');

const app = express();

// ruleid:header_xss_lusca
app.use(lusca({
    csrf: true,
    csp: { policy: "referrer no-referrer" },
    xframe: 'SAMEORIGIN',
    p3p: 'ABCDEF',
    hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
    xssProtection: false,
    nosniff: true,
    referrerPolicy: 'same-origin'
}));

app.use(lusca.csrf());
app.use(lusca.csp({ policy: [{ "img-src": "'self' http:" }, "block-all-mixed-content"], reportOnly: false }));
app.use(lusca.xframe('SAMEORIGIN'));
app.use(lusca.p3p('ABCDEF'));
app.use(lusca.hsts({ maxAge: 31536000 }));
// ruleid:header_xss_lusca
app.use(lusca.xssProtection(false));
app.use(lusca.nosniff());
app.use(lusca.referrerPolicy('same-origin'));

app.get('/', function (req, res) {
    var x = 0;
    // ruleid:header_xss_generic
    res.writeHead(200, { 'x-xss-protection': 0 });

    // ruleid:header_xss_generic
    res.set('x-xss-protection', 0);
    //do not match
    res.set('x-xss-protection', 1);
    // ruleid:header_xss_generic
    res.set('X-XSS-Protection', 0);
    //sgrep bug - https://github.com/returntocorp/sgrep/issues/512
    // ruleid:header_xss_generic
    res.set({
        'Content-Length': req.query.foo,
        'x-xss-protection': 0,
        'ETag': '12345'
    })
    //sgrep bug - https://github.com/returntocorp/sgrep/issues/512
    // ruleid:header_xss_generic
    res.writeHead(200, { 'x-xss-protection': 0 })
    // ruleid:header_xss_generic
    res.set('X-XSS-Protection', x);

    // do not detect
    res.set(ffff)
});