-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(python): eval injection (CWE-95)
- Loading branch information
Showing
3 changed files
with
89 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
imports: | ||
- python_shared_common_user_input | ||
patterns: | ||
- pattern: eval($<...>$<USER_INPUT>$<...>) | ||
filters: | ||
- variable: USER_INPUT | ||
detection: python_shared_common_user_input | ||
scope: result | ||
- pattern: $<LITERAL_EVAL>($<...>$<USER_INPUT>$<...>) | ||
filters: | ||
- variable: LITERAL_EVAL | ||
detection: python_lang_eval_using_user_input_literal_eval | ||
scope: result | ||
- variable: USER_INPUT | ||
detection: python_shared_common_user_input | ||
scope: result | ||
auxiliary: | ||
- id: python_lang_eval_using_user_input_literal_eval | ||
patterns: | ||
- pattern: $<AST_LITERAL_EVAL> | ||
filters: | ||
- variable: AST_LITERAL_EVAL | ||
regex: \A(ast\.)?literal_eval\z | ||
languages: | ||
- python | ||
severity: critical | ||
metadata: | ||
description: "Unsanitized user input in 'eval' type function" | ||
remediation_message: |- | ||
## Description | ||
Executing code with 'eval' or similar functions using unsanitized user input is risky and can lead to code injection vulnerabilities. This happens when external input is used directly in functions that execute code, allowing attackers to run malicious code within your application. | ||
## Remediations | ||
- **Do not** use `eval` or similar code execution functions with unsanitized user input. This can create a significant security risk by allowing code injection. | ||
- **Do not** use `ast.literal_eval()` with unsanitized user input. While `literal_eval` is often considered to be less risky than `eval` because it evaluates strings as Python data structures only (integers, strings, dictionaries,etc), an attacker could exploit this function with deeply nested structures that could cause excessive memory allocation or stack consumption. | ||
- **Do** use dynamic hardcoded values instead of direct user input to mitigate the risk of code injection. This approach allows for controlled execution of code without exposing your application to injected malicious code. For example, use a dictionary to store functions, and call these based on user input. | ||
```python | ||
def total_with_vat(a, b): | ||
total = a + b | ||
return total + total * 0.15 | ||
def total_without_vat(a, b): | ||
return a + b | ||
get_total = { | ||
"incl_vat": total_with_vat, | ||
"excl_vat": total_without_vat | ||
} | ||
if form.cleaned_data["include_vat"]: | ||
total_func = get_total["incl_vat"] | ||
total = total_func(a, b) | ||
# ... | ||
``` | ||
## References | ||
- [OWASP Code injection explained](https://owasp.org/www-community/attacks/Code_Injection) | ||
cwe_id: | ||
- 95 | ||
id: python_lang_eval_using_user_input | ||
documentation_url: https://docs.bearer.com/reference/rules/python_lang_eval_using_user_input |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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("eval_using_user_input", () => { | ||
const testCase = "main.py" | ||
|
||
const results = invoke(testCase) | ||
|
||
expect(results).toEqual({ | ||
Missing: [], | ||
Extra: [] | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
def bad(request): | ||
form = BadForm(request.POST) | ||
# bearer:expected python_lang_eval_using_user_input | ||
eval(form.cleaned_data["bad_eval"]) |