python.flask.security.hashids-with-flask-secret.hashids-with-flask-secret

profile photo of semgrepsemgrep
Author
unknown
Download Count*

The Flask secret key is used as salt in HashIDs. The HashID mechanism is not secure. By observing sufficient HashIDs, the salt used to construct them can be recovered. This means the Flask secret key can be obtained by attackers, through the HashIDs.

Run Locally

Run in CI

Defintion

rules:
  - id: hashids-with-flask-secret
    languages:
      - python
    message: The Flask secret key is used as salt in HashIDs. The HashID mechanism
      is not secure. By observing sufficient HashIDs, the salt used to construct
      them can be recovered. This means the Flask secret key can be obtained by
      attackers, through the HashIDs.
    metadata:
      category: security
      subcategory:
        - vuln
      cwe:
        - "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
      owasp:
        - A02:2021 – Cryptographic Failures
      references:
        - https://flask.palletsprojects.com/en/2.2.x/config/#SECRET_KEY
        - http://carnage.github.io/2015/08/cryptanalysis-of-hashids
      technology:
        - flask
      likelihood: LOW
      impact: HIGH
      confidence: HIGH
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Cryptographic Issues
    pattern-either:
      - pattern: hashids.Hashids(..., salt=flask.current_app.config['SECRET_KEY'], ...)
      - pattern: hashids.Hashids(flask.current_app.config['SECRET_KEY'], ...)
      - patterns:
          - pattern-inside: |
              $APP = flask.Flask(...)
              ...
          - pattern-either:
              - pattern: hashids.Hashids(..., salt=$APP.config['SECRET_KEY'], ...)
              - pattern: hashids.Hashids($APP.config['SECRET_KEY'], ...)
    severity: ERROR

Examples

hashids-with-flask-secret.py

from hashids import Hashids
from flask import Flask

from flask import current_app as app
# ruleid: hashids-with-flask-secret
hash_id = Hashids(salt=app.config['SECRET_KEY'], min_length=34)
# ruleid: hashids-with-flask-secret
hashids = Hashids(min_length=4, salt=app.config['SECRET_KEY'])

from flask import current_app
# ruleid: hashids-with-flask-secret
hashids = Hashids(min_length=5, salt=current_app.config['SECRET_KEY'])

foo = Flask(__name__)
# ruleid: hashids-with-flask-secret
hashids = Hashids(min_length=4, salt=foo.config['SECRET_KEY'])

app = Flask(__name__.split('.')[0])
# ruleid: hashids-with-flask-secret
app._hashids = Hashids(salt=app.config['SECRET_KEY'])