python.requests.security.no-auth-over-http.no-auth-over-http

Verifed by r2c
Community Favorite
profile photo of semgrepsemgrep
Author
121,839
Download Count*

Authentication detected over HTTP. HTTP does not provide any encryption or protection for these authentication credentials. This may expose these credentials to unauthorized parties. Use 'https://' instead.

Run Locally

Run in CI

Defintion

rules:
  - id: no-auth-over-http
    fix-regex:
      regex: http:\/\/
      replacement: https://
      count: 1
    message: Authentication detected over HTTP. HTTP does not provide any encryption
      or protection for these authentication credentials. This may expose these
      credentials to unauthorized parties. Use 'https://' instead.
    metadata:
      cwe:
        - "CWE-523: Unprotected Transport of Credentials"
      owasp:
        - A02:2017 - Broken Authentication
        - A02:2021 - Cryptographic Failures
      source-rule-url: https://pypi.org/project/flake8-flask/
      references:
        - https://semgrep.dev/blog/2020/bento-check-no-auth-over-http/
        - https://bento.dev/checks/requests/no-auth-over-http/
      category: security
      technology:
        - requests
      subcategory:
        - audit
      likelihood: LOW
      impact: LOW
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Mishandled Sensitive Information
    languages:
      - python
    severity: ERROR
    pattern-either:
      - pattern: requests.$W("=~/http:\/\/.*/", ..., auth=$X, ...)
      - pattern: |
          $URL = "=~/http:\/\/.../"
          ...
          requests.$W($URL, ..., auth=$X, ...)

Examples

no-auth-over-http.py

import requests

# ok:no-auth-over-http
good_url = "https://www.github.com"
bad_url = "http://www.github.com"

# ruleid:no-auth-over-http
r = requests.post("http://www.github.com", auth=('user', 'pass'))

# ok:no-auth-over-http
r = requests.post(good_url, auth=('user', 'pass'))

# ok:no-auth-over-http
r = requests.get(bad_url, timeout=50)

def test1():
    # ruleid:no-auth-over-http
    bad_url = "http://www.github.com"
    print("something")
    # ruleid:no-auth-over-http
    r = requests.get(bad_url, auth=('user', 'pass'))

def test2():
    # ok:no-auth-over-http
    bad_url = "http://www.github.com"
    print("something")
    r = requests.post(bad_url)

def test3():
    # ok:no-auth-over-http
    good_url = "https://www.github.com"
    r = requests.get(good_url, auth=('user', 'pass'))

def from_import_test1(url):
    from requests import get, post
    # ok:no-auth-over-http
    good_url = "https://www.github.com"
    bad_url = "http://www.github.com"
    r = get(good_url, timeout=3)
    r = post(bad_url)

def from_import_test1(url):
    from requests import get, post
    # ruleid:no-auth-over-http
    bad_url = "http://www.github.com"
    # ruleid:no-auth-over-http
    r = get(bad_url, timeout=3, auth=('user', 'pass'))