python.lang.security.audit.insecure-transport.urllib.insecure-urlopener-retrieve.insecure-urlopener-retrieve

profile photo of semgrepsemgrep
Author
7,311
Download Count*

Detected an unsecured transmission channel. 'URLopener.retrieve(...)' is being used with 'http://'. Use 'https://' instead to secure the channel.

Run Locally

Run in CI

Defintion

rules:
  - id: insecure-urlopener-retrieve
    message: Detected an unsecured transmission channel. 'URLopener.retrieve(...)'
      is being used with 'http://'. Use 'https://' instead to secure the
      channel.
    metadata:
      owasp:
        - A03:2017 - Sensitive Data Exposure
        - A02:2021 - Cryptographic Failures
      cwe:
        - "CWE-319: Cleartext Transmission of Sensitive Information"
      references:
        - https://docs.python.org/3/library/urllib.request.html#urllib.request.URLopener.retrieve
      category: security
      technology:
        - urllib
      subcategory:
        - audit
      likelihood: LOW
      impact: LOW
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Mishandled Sensitive Information
    severity: WARNING
    languages:
      - python
    fix-regex:
      regex: "[Hh][Tt][Tt][Pp]://"
      replacement: https://
      count: 1
    pattern-either:
      - pattern: urllib.request.URLopener(...).retrieve("=~/[Hh][Tt][Tt][Pp]://.*/",
          ...)
      - patterns:
          - pattern-inside: |
              $OPENERDIRECTOR = urllib.request.URLopener(...)
              ...
          - pattern: $OPENERDIRECTOR.retrieve("=~/[Hh][Tt][Tt][Pp]://.*/", ...)
      - patterns:
          - pattern-inside: |
              $OPENERDIRECTOR = urllib.request.URLopener(...)
              ...
          - pattern: |
              $URL = "=~/[Hh][Tt][Tt][Pp]://.*/"
              ...
              $OPENERDIRECTOR.retrieve($URL, ...)
      - pattern: |
          $URL = "=~/[Hh][Tt][Tt][Pp]://.*/"
          ...
          urllib.request.URLopener(...).retrieve($URL, ...)
      - patterns:
          - pattern-inside: |
              def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...):
                ...
          - pattern-either:
              - pattern: urllib.request.URLopener(...).retrieve($URL, ...)
              - patterns:
                  - pattern-inside: |
                      $OPENERDIRECTOR = urllib.request.URLopener(...)
                      ...
                  - pattern: $OPENERDIRECTOR.retrieve($URL, ...)

Examples

insecure-urlopener-retrieve.py

from urllib.request import URLopener

def test1():
    od = URLopener()
    # ruleid: insecure-urlopener-retrieve
    od.retrieve("http://example.com")

def test1_ok():
    od = URLopener()
    # ok: insecure-urlopener-retrieve
    od.retrieve("https://example.com")

def test2():
    od = URLopener()
    # ruleid: insecure-urlopener-retrieve
    url = "http://example.com"
    # ruleid: insecure-urlopener-retrieve
    od.retrieve(url)

def test2_ok():
    od = URLopener()
    # ok: insecure-urlopener-retrieve
    url = "https://example.com"
    od.retrieve(url)

def test3():
    # ruleid: insecure-urlopener-retrieve
    URLopener().retrieve("http://example.com")

def test3_ok():
    # ok: insecure-urlopener-retrieve
    URLopener().retrieve("https://example.com")

def test4():
    # ruleid: insecure-urlopener-retrieve
    url = "http://example.com"
    # ruleid: insecure-urlopener-retrieve
    URLopener().retrieve(url)

def test4_ok():
    # ok: insecure-urlopener-retrieve
    url = "https://example.com"
    URLopener().retrieve(url)

def test5(url = "http://example.com"):
    # ruleid: insecure-urlopener-retrieve
    URLopener().retrieve(url)

def test5_ok(url = "https://example.com"):
    # ok: insecure-urlopener-retrieve
    URLopener().retrieve(url)

def test6(url = "http://example.com"):
    od = URLopener()
    # ruleid: insecure-urlopener-retrieve
    od.retrieve(url)

def test6_ok(url = "https://example.com"):
    od = URLopener()
    # ok: insecure-urlopener-retrieve
    od.retrieve(url)