Skip to content

Commit

Permalink
Merge Develop into Release (#3268)
Browse files Browse the repository at this point in the history
* Improve Flask-WTF CSRF rule (#3264)

* Improve Flask-WTF CSRF rules

* Add fixtest

* Add pattern-not for flask csrf tokens to django csrf rule (#3263)

---------

Co-authored-by: Pieter De Cremer (Semgrep) <[email protected]>
  • Loading branch information
r2c-argo[bot] and 0xDC0DE authored Jan 9, 2024
1 parent 15a47b7 commit a40e5fa
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 2 deletions.
14 changes: 14 additions & 0 deletions python/django/security/django-no-csrf-token.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,17 @@
</div>
</div>
</div>

<div class="container">
<div class="row">
<div class="col-6">
<!-- ok: django-no-csrf-token -->
<form method="POST" action="{{ url_for('web.organization_settings') }}">
{{ name_form.csrf_token }}
{{ render_form_row([name_form.organization_name], col_map={'organization_name': 'col-md-6'}) }}

<input type="submit" value="Submit" class="btn btn-primary">
</form>
</div>
</div>
</div>
3 changes: 2 additions & 1 deletion python/django/security/django-no-csrf-token.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ rules:
metavariable: $METHOD
regex: (?i)(post|put|delete|patch)
- pattern-not-inside: "<form...>...{% csrf_token %}...</form>"
- pattern-not-inside: "<form...>...{{ $VAR.csrf_token }}...</form>"
message: Manually-created forms in django templates should specify a csrf_token to prevent CSRF attacks
languages: [generic]
severity: WARNING
Expand All @@ -30,4 +31,4 @@ rules:
- django
paths:
include:
- "*.html"
- "*.html"
75 changes: 75 additions & 0 deletions python/flask/security/audit/wtf-csrf-disabled.fixed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import flask
from flask import response as r

app = flask.Flask(__name__)
# ruleid:flask-wtf-csrf-disabled
app.config['WTF_CSRF_ENABLED'] = True

# ruleid:flask-wtf-csrf-disabled
app.config["WTF_CSRF_ENABLED"] = True

# ok: flask-wtf-csrf-disabled
app.config["WTF_CSRF_ENABLED"] = True
# ok: flask-wtf-csrf-disabled
app.config["SESSION_COOKIE_SECURE"] = False

# ruleid: flask-wtf-csrf-disabled
app.config.WTF_CSRF_ENABLED = True
# ok: flask-wtf-csrf-disabled
app.config.WTF_CSRF_ENABLED = True

# DICT UPDATE
################

app.config.update(
SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf',
# ruleid: flask-wtf-csrf-disabled
WTF_CSRF_ENABLED = True,
TESTING=False
)

# It's okay to do this during testing
app.config.update(
SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf',
# ok: flask-wtf-csrf-disabled
WTF_CSRF_ENABLED = False,
TESTING=True
)

# FROM OBJECT
################

# custom class
appconfig = MyAppConfig()
# ruleid: flask-wtf-csrf-disabled
appconfig.WTF_CSRF_ENABLED = True

app.config.from_object(appconfig)

# this file itself
SECRET_KEY = 'development key'
# ruleid: flask-wtf-csrf-disabled
WTF_CSRF_ENABLED = True

app.config.from_object(__name__)

# FROM MAPPING
################

app.config.from_mapping(
SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf',
# ruleid: flask-wtf-csrf-disabled
WTF_CSRF_ENABLED = True,
)

# It's okay to do this during testing
app.config.from_mapping(
SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf',
# ok: flask-wtf-csrf-disabled
WTF_CSRF_ENABLED = False,
TESTING=True
)

@app.route("/index")
def index():
return 'hello world'
65 changes: 65 additions & 0 deletions python/flask/security/audit/wtf-csrf-disabled.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,71 @@
# ruleid:flask-wtf-csrf-disabled
app.config['WTF_CSRF_ENABLED'] = False

# ruleid:flask-wtf-csrf-disabled
app.config["WTF_CSRF_ENABLED"] = False

# ok: flask-wtf-csrf-disabled
app.config["WTF_CSRF_ENABLED"] = True
# ok: flask-wtf-csrf-disabled
app.config["SESSION_COOKIE_SECURE"] = False

# ruleid: flask-wtf-csrf-disabled
app.config.WTF_CSRF_ENABLED = False
# ok: flask-wtf-csrf-disabled
app.config.WTF_CSRF_ENABLED = True

# DICT UPDATE
################

app.config.update(
SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf',
# ruleid: flask-wtf-csrf-disabled
WTF_CSRF_ENABLED = False,
TESTING=False
)

# It's okay to do this during testing
app.config.update(
SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf',
# ok: flask-wtf-csrf-disabled
WTF_CSRF_ENABLED = False,
TESTING=True
)

# FROM OBJECT
################

# custom class
appconfig = MyAppConfig()
# ruleid: flask-wtf-csrf-disabled
appconfig.WTF_CSRF_ENABLED = False

app.config.from_object(appconfig)

# this file itself
SECRET_KEY = 'development key'
# ruleid: flask-wtf-csrf-disabled
WTF_CSRF_ENABLED = False

app.config.from_object(__name__)

# FROM MAPPING
################

app.config.from_mapping(
SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf',
# ruleid: flask-wtf-csrf-disabled
WTF_CSRF_ENABLED = False,
)

# It's okay to do this during testing
app.config.from_mapping(
SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf',
# ok: flask-wtf-csrf-disabled
WTF_CSRF_ENABLED = False,
TESTING=True
)

@app.route("/index")
def index():
return 'hello world'
48 changes: 47 additions & 1 deletion python/flask/security/audit/wtf-csrf-disabled.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ rules:
- id: flask-wtf-csrf-disabled
message: >-
Setting 'WTF_CSRF_ENABLED' to 'False' explicitly disables CSRF protection.
options:
symbolic_propagation: true
metadata:
cwe:
- 'CWE-352: Cross-Site Request Forgery (CSRF)'
Expand All @@ -25,4 +27,48 @@ rules:
severity: WARNING
languages:
- python
pattern: $APP.config['WTF_CSRF_ENABLED'] = False
patterns:
- pattern-either:
- patterns:
- pattern-either:
- pattern: $APP.config["WTF_CSRF_ENABLED"] = $FALSE
- pattern: $APP.config.WTF_CSRF_ENABLED = $FALSE
- patterns:
- pattern: |
$APP.config.$UPDATE(
...,
WTF_CSRF_ENABLED = $FALSE,
...
)
- pattern-not-inside: |
$APP.config.$UPDATE(
...,
TESTING=True,
...
)
- pattern-not-inside: |
$APP.config.$UPDATE(
...,
DEBUG=True,
...
)
- metavariable-regex:
metavariable: $UPDATE
regex: ^(update|from_mapping)$
- pattern: |
$OBJ = $CLASS()
...
$OBJ.WTF_CSRF_ENABLED = $FALSE
...
$APP.config.from_object($OBJ, ...)
- pattern: |
WTF_CSRF_ENABLED = $FALSE
...
$APP.config.from_object(__name__)
- metavariable-regex:
metavariable: $FALSE
regex: ^(False)$
- focus-metavariable: $FALSE
fix: 'True'


0 comments on commit a40e5fa

Please sign in to comment.