From cfa8c11db3dbda28eed0303a1617ebc151cea4e1 Mon Sep 17 00:00:00 2001 From: elsapet Date: Wed, 15 May 2024 15:55:44 +0200 Subject: [PATCH] feat(python): code injection (CWE-94) (#397) --- rules/python/lang/code_injection.yml | 62 +++++++++++++++++++ tests/python/lang/code_injection/test.js | 20 ++++++ .../lang/code_injection/testdata/main.py | 16 +++++ 3 files changed, 98 insertions(+) create mode 100644 rules/python/lang/code_injection.yml create mode 100644 tests/python/lang/code_injection/test.js create mode 100644 tests/python/lang/code_injection/testdata/main.py diff --git a/rules/python/lang/code_injection.yml b/rules/python/lang/code_injection.yml new file mode 100644 index 00000000..f3fd7b39 --- /dev/null +++ b/rules/python/lang/code_injection.yml @@ -0,0 +1,62 @@ +imports: + - python_shared_common_user_input + - python_shared_lang_import1 +patterns: + - pattern: exec($<...>$$<...>) + filters: + - variable: USER_INPUT + detection: python_shared_common_user_input + scope: result + - pattern: getattr($<_>, $<...>$$<...>) + filters: + - variable: USER_INPUT + detection: python_shared_common_user_input + scope: result + - pattern: setattr($<_>, $<_>, $<...>$$<...>) + filters: + - variable: USER_INPUT + detection: python_shared_common_user_input + scope: result + - pattern: $($<...>$$<...>) + filters: + - variable: OS + detection: python_shared_lang_import1 + scope: cursor + filters: + - variable: MODULE1 + values: [os] + - variable: NAME + values: + - execl + - execle + - execlp + - execlpe + - execv + - execve + - execvp + - execvpe + - variable: USER_INPUT + detection: python_shared_common_user_input + scope: result +languages: + - python +severity: critical +metadata: + description: Unsanitized user input in code generation + remediation_message: |- + ## Description + + Allowing user input to directly influence code generation or scripting functions without proper sanitization can lead to code injection vulnerabilities. This occurs when an attacker is able to insert malicious code into your application, which is then executed, potentially leading to unauthorized actions or data access. + + ## Remediations + + - **Do not** pass unsanitized user input to functions or methods that dynamically execute code. + - **Do** always validate or sanitize input to ensure it does not contain harmful code before using it in such contexts. + + ## References + + - [OWASP Code injection](https://owasp.org/www-community/attacks/Code_Injection) + cwe_id: + - 94 + id: python_lang_code_injection + documentation_url: https://docs.bearer.com/reference/rules/python_lang_code_injection diff --git a/tests/python/lang/code_injection/test.js b/tests/python/lang/code_injection/test.js new file mode 100644 index 00000000..bdbbe44b --- /dev/null +++ b/tests/python/lang/code_injection/test.js @@ -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("code_injection", () => { + const testCase = "main.py" + + const results = invoke(testCase) + + expect(results).toEqual({ + Missing: [], + Extra: [] + }) + }) +}) \ No newline at end of file diff --git a/tests/python/lang/code_injection/testdata/main.py b/tests/python/lang/code_injection/testdata/main.py new file mode 100644 index 00000000..fe56ca16 --- /dev/null +++ b/tests/python/lang/code_injection/testdata/main.py @@ -0,0 +1,16 @@ +# Use bearer:expected python_lang_code_injection to flag expected findings +def bad(request): + form = BadForm(request.POST) + # bearer:expected python_lang_code_injection + exec(form.cleaned_data["some_code"]) + +def bad2(): + username = input("what hack today?") + # bearer:expected python_lang_code_injection + setattr(current_user, "name", username) + +import os +def bad3(request): + unsafe = request.GET.get("some_code") + # bearer:expected python_lang_code_injection + os.execl("/bin/bash", "/bin/bash", "-c", unsafe) \ No newline at end of file