python.lang.security.audit.insecure-transport.urllib.insecure-urlretrieve-ftp.insecure-urlretrieve-ftp

profile photo of semgrepsemgrep
Author
7,311
Download Count*

Detected 'urllib.urlretrieve()' using 'ftp://'. This request will not be encrypted. Use SFTP instead. urllib does not support SFTP, so consider switching to a library which supports SFTP.

Run Locally

Run in CI

Defintion

rules:
  - id: insecure-urlretrieve-ftp
    message: Detected 'urllib.urlretrieve()' using 'ftp://'. This request will not
      be encrypted. Use SFTP instead. urllib does not support SFTP, so consider
      switching to a library which supports SFTP.
    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.urlretrieve
      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
    pattern-either:
      - pattern: urllib.request.urlretrieve("=~/^[Ff][Tt][Pp]://.*/", ...)
      - pattern: |
          $URL = "=~/^[Ff][Tt][Pp]://.*/"
          ...
          urllib.request.urlretrieve($URL, ...)
      - pattern: |-
          def $FUNC(..., $URL = "=~/^[Ff][Tt][Pp]://.*/", ...):
            ...
            urllib.request.urlretrieve($URL, ...)

Examples

insecure-urlretrieve-ftp.py

from urllib.request import urlretrieve

def test1():
    # ruleid: insecure-urlretrieve-ftp
    urlretrieve("ftp://example.com")

def test1_ok():
    # ok: insecure-urlretrieve-ftp
    urlretrieve("sftp://example.com")

def test2():
    # ruleid: insecure-urlretrieve-ftp
    url = "ftp://example.com"
    # ruleid: insecure-urlretrieve-ftp
    urlretrieve(url)

def test2_ok():
    # ok: insecure-urlretrieve-ftp
    url = "sftp://example.com"
    urlretrieve(url)

# ruleid: insecure-urlretrieve-ftp
def test3(url = "ftp://example.com"):
    urlretrieve(url)

# ok: insecure-urlretrieve-ftp
def test3_ok(url = "sftp://example.com"):
    urlretrieve(url)