problem-based-packs.insecure-transport.js-node.http-request.http-request

profile photo of semgrepsemgrep
Author
2,021
Download Count*

Checks for requests sent to http:// URLs. This is dangerous as the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, only send requests to https:// URLs.

Run Locally

Run in CI

Defintion

rules:
  - id: http-request
    message: Checks for requests sent to http:// URLs. This is dangerous as the
      server is attempting to connect to a website that does not encrypt traffic
      with TLS. Instead, only send requests to https:// URLs.
    severity: WARNING
    metadata:
      likelihood: MEDIUM
      impact: MEDIUM
      confidence: MEDIUM
      category: security
      cwe: "CWE-319: Cleartext Transmission of Sensitive Information"
      owasp: A03:2017 - Sensitive Data Exposure
      references:
        - https://nodejs.org/api/http.html#http_http_request_options_callback
      subcategory:
        - vuln
      technology:
        - node.js
      vulnerability: Insecure Transport
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Mishandled Sensitive Information
    languages:
      - javascript
    patterns:
      - pattern-inside: |
          $HTTP = require('http');
          ...
      - pattern-either:
          - pattern: |
              $HTTP.request("=~/http://.*/",...);
          - pattern: |
              $HTTP.get("=~/http://.*/", ...)
          - pattern: |
              $VAR = new URL("=~/http://.*/");
              ...
              $HTTP.request($VAR, ...);
          - pattern: |
              $VAR = {...,hostname: "..."};
              ...
              $HTTP.request(..., $VAR, ...);
          - pattern: |
              $HTTP.request(..., {...,hostname: "..."}, ...);
      - pattern-not: |
          $VAR = {...,protocol: "https"};
          ...
          $HTTP.request(..., $VAR, ...);
      - pattern-not: |
          $HTTP.request(..., {...,protocol: "https"}, ...);

Examples

http-request.js

const http = require('http');

function bad_http() {
    // ruleid: http-request
    http.get('http://nodejs.org/dist/index.json', (res) => {
    const { statusCode } = res;})

    // ok: http-request
    https.get('http://nodejs.org/dist/index.json', (res) => {
    const { statusCode } = res;})

    // ruleid: http-request
    const options = {
        port: 80,
        hostname: 'www.google.com',
        path: '/upload'
    }

    const req = http.request(options, (res) => {
    console.log(`STATUS: ${res.statusCode}`);})

    // ok: http-request
    const options = {
        port: 80,
        hostname: 'www.google.com',
        path: '/upload'
    }

    const req = https.request(options, (res) => {
    console.log(`STATUS: ${res.statusCode}`);})

    // ruleid: http-request
    const options = new URL('http://abc:xyz@example.com');

    const req = http.request(options, (res) => {
    });

    // ok: http-request
    const options = new URL('http://abc:xyz@example.com');

    const req = https.request(options, (res) => {
    });
};

function more_bad_http() {
    console.log("what");
    // ok: http-request
    const req = https.request('http://google.com', options, (res) => {
    });

    // ruleid: http-request
    const req = http.request('http://google.com', options, (res) => {
    });
};

function ok_http() {
    // ok: http-request
    const options = {
        port: 80,
        hostname: 'www.google.com',
        path: '/upload',
        protocol: 'https'
    }

    const req = http.request(options, (res) => {
    console.log(`STATUS: ${res.statusCode}`);})

    // ok: http-request
    const options = {
        port: 80,
        hostname: 'www.google.com',
        path: '/upload',
        protocol: 'https'
    }

    const req = https.request(options, (res) => {
    console.log(`STATUS: ${res.statusCode}`);})
}