Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(python): add cwe-601 open redirect rule #416

Merged
merged 1 commit into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions rules/python/django/open_redirect.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
imports:
- python_shared_common_user_input
- python_shared_lang_import2
patterns:
- pattern: $<RESPONSE_CLASS>($<USER_INPUT>$<...>)
filters:
- variable: FUNCTION
detection: python_shared_lang_import2
scope: cursor
filters:
- variable: MODULE1
values: [django]
- variable: MODULE2
values: [http]
- variable: NAME
values:
- HttpResponseRedirect
- HttpResponsePermanentRedirect
- variable: USER_INPUT
detection: python_shared_common_user_input
scope: result
- pattern: $<FUNCTION>($<USER_INPUT>$<...>)
filters:
- variable: FUNCTION
detection: python_shared_lang_import2
scope: cursor
filters:
- variable: MODULE1
values: [django]
- variable: MODULE2
values: [shortcuts]
- variable: NAME
values: [redirect]
- variable: USER_INPUT
detection: python_shared_common_user_input
scope: result
languages:
- python
severity: medium
metadata:
description: "Unsanitized user input in redirect"
remediation_message: |-
## Description

Using unsanitized user input to perform redirects can make your application vulnerable to phishing attacks. This occurs when user input is directly used to determine the destination of a redirect without proper validation or sanitization, allowing attackers to redirect users to malicious sites, potentially compromising their security.

## Remediations

- **Do not** use unsanitized user input when constructing URLs for redirects. Directly incorporating user input without validation can lead to phishing attacks and malicious site redirection.
- **Do** validate user input by employing a safe list or a mapping strategy for constructing URLs. This ensures that the redirection is to a known, safe location.
```python
paths = dict(
1="/planes",
2="/trains",
3="/automobiles"
)

transport = request.GET["transport"]
redirect(paths[transport]);
```

## References

- [OWASP Unvalidated Redirects and Forwards Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html)
cwe_id:
- 601
id: python_django_open_redirect
documentation_url: https://docs.bearer.com/reference/rules/python_django_open_redirect
20 changes: 20 additions & 0 deletions tests/python/django/open_redirect/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const {
createNewInvoker,
getEnvironment,
} = require("../../../helper.js")
const { ruleId, ruleFile, testBase } = getEnvironment(__dirname)

describe(ruleId, () => {
const invoke = createNewInvoker(ruleId, ruleFile, testBase)

test("open_redirect", () => {
const testCase = "main.py"

const results = invoke(testCase)

expect(results).toEqual({
Missing: [],
Extra: []
})
})
})
18 changes: 18 additions & 0 deletions tests/python/django/open_redirect/testdata/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
user_input = form.cleaned_data["path"]

from django.shortcuts import redirect

redirect("ok", False)
# bearer:expected python_django_open_redirect
redirect(user_input, False)


from django.http import HttpResponsePermanentRedirect, HttpResponseRedirect

HttpResponseRedirect("ok", headers={})
# bearer:expected python_django_open_redirect
HttpResponseRedirect(user_input, headers={})

HttpResponsePermanentRedirect("ok", headers={})
# bearer:expected python_django_open_redirect
HttpResponsePermanentRedirect(user_input, headers={})
Loading