problem-based-packs.insecure-transport.go-stdlib.http-request.http-request

profile photo of semgrepsemgrep
Author
6,272
Download Count*

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

Run Locally

Run in CI

Defintion

rules:
  - id: http-request
    message: Checks for requests sent via http.$FUNC to http:// URLS. This is
      dangerous because the server is attempting to connect to a website that
      does not encrypt traffic with TLS. Instead, send requests only 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://golang.org/pkg/net/http/#Get
      subcategory:
        - vuln
      technology:
        - go
      vulnerability: Insecure Transport
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Mishandled Sensitive Information
    languages:
      - go
    fix-regex:
      regex: "[Hh][Tt][Tt][Pp]://"
      replacement: https://
      count: 1
    patterns:
      - pattern-either:
          - pattern: |
              http.$FUNC("=~/[hH][tT][tT][pP]://.*/", ...)
          - patterns:
              - pattern-inside: |
                  $CLIENT := &http.Client{...}
                  ...
              - pattern: |
                  client.$FUNC("=~/[hH][tT][tT][pP]://.*/", ...)
      - pattern-not: http.$FUNC("=~/[hH][tT][tT][pP]://127.0.0.1.*/", ...)
      - pattern-not: client.$FUNC("=~/[hH][tT][tT][pP]://127.0.0.1.*/", ...)
      - pattern-not: http.$FUNC("=~/[hH][tT][tT][pP]://localhost.*/", ...)
      - pattern-not: client.$FUNC("=~/[hH][tT][tT][pP]://localhost.*/", ...)
      - metavariable-regex:
          metavariable: $FUNC
          regex: (Get|Post|Head|PostForm)

Examples

http-request.go

func bad1() {
    // ruleid: http-request
    resp, err := http.Get("http://example.com/")
    // ruleid: http-request
    resp, err := http.Post("http://example.com/", val, val)
    // ruleid: http-request
    resp, err := http.Head("http://example.com/")
    // ruleid: http-request
    resp, err := http.PostForm("http://example.com/", form)
}

func bad2() {
    client := &http.Client{
	    CheckRedirect: redirectPolicyFunc,
    }

    // ruleid: http-request
    resp, err := client.Get("http://example.com")
}

func ok1() {
    // ok: http-request
    resp, err := http.Get("https://example.com/")
    // ok: http-request
    resp, err := http.Post("https://example.com/", val, val)
    // ok: http-request
    resp, err := http.Head("https://example.com/")
    // ok: http-request
    resp, err := http.PostForm("https://example.com/", form)
    // ok: http-request
    resp, err := http.PostForm("http://127.0.0.1/", form)
    // ok: http-request
    resp, err := http.Head("http://127.0.0.1/path/to/x")
    // ok: http-request
    resp, err := http.Head("http://localhost/path/to/x")
}

func ok2() {
    client := &http.Client{
	    CheckRedirect: redirectPolicyFunc,
    }

    // ok: http-request
    resp, err := client.Get("https://example.com")

    // ok: http-request
    resp, err := client.Post("https://127.0.0.1/path/to/x", form)

    // ok: http-request
    resp, err := client.Get("https://127.0.0.1")

    // ok: http-request
    resp, err := client.Get("https://localhost/asdf/path")
}