From b86f8b5664834c76a53eb11721a1526fcf8e2cd0 Mon Sep 17 00:00:00 2001 From: Pedro Pereira Date: Wed, 17 Sep 2025 09:38:54 +0100 Subject: [PATCH 1/2] fix: not recommended patterns are now included in semgrep config CF-1809 --- .codacy/codacy.yaml | 2 +- cmd/init_test.go | 2 +- .../config-discover/expected/codacy.yaml | 2 +- .../init-with-token/expected/codacy.yaml | 2 +- .../init-without-token/expected/codacy.yaml | 2 +- .../expected/tools-configs/semgrep.yaml | 123436 +++++++++++---- plugins/tools/trivy/plugin.yaml | 2 +- plugins/tools/trivy/test/expected.sarif | 37 +- tools/semgrepConfigCreator.go | 2 +- .../repositories/trivy/expected.sarif | 2 +- 10 files changed, 96538 insertions(+), 26951 deletions(-) diff --git a/.codacy/codacy.yaml b/.codacy/codacy.yaml index 2059314a..bed1d054 100644 --- a/.codacy/codacy.yaml +++ b/.codacy/codacy.yaml @@ -13,4 +13,4 @@ tools: - pylint@3.3.7 - revive@1.11.0 - semgrep@1.78.0 - - trivy@0.65.0 + - trivy@0.66.0 diff --git a/cmd/init_test.go b/cmd/init_test.go index 9168de09..aad466a4 100644 --- a/cmd/init_test.go +++ b/cmd/init_test.go @@ -25,7 +25,7 @@ func TestConfigFileTemplate(t *testing.T) { "node@22.2.0", "python@3.11.11", "eslint@8.57.0", - "trivy@0.65.0", + "trivy@0.66.0", "pylint@3.3.6", "pmd@7.11.0", }, diff --git a/integration-tests/config-discover/expected/codacy.yaml b/integration-tests/config-discover/expected/codacy.yaml index f54fe86a..199dd6da 100644 --- a/integration-tests/config-discover/expected/codacy.yaml +++ b/integration-tests/config-discover/expected/codacy.yaml @@ -10,4 +10,4 @@ tools: - pmd@7.11.0 - pylint@3.3.6 - semgrep@1.78.0 - - trivy@0.65.0 + - trivy@0.66.0 diff --git a/integration-tests/init-with-token/expected/codacy.yaml b/integration-tests/init-with-token/expected/codacy.yaml index d0b7994f..c36f2548 100644 --- a/integration-tests/init-with-token/expected/codacy.yaml +++ b/integration-tests/init-with-token/expected/codacy.yaml @@ -8,4 +8,4 @@ tools: - pmd@6.55.0 - pylint@3.3.7 - semgrep@1.78.0 - - trivy@0.65.0 + - trivy@0.66.0 diff --git a/integration-tests/init-without-token/expected/codacy.yaml b/integration-tests/init-without-token/expected/codacy.yaml index ac85c06c..15365c77 100644 --- a/integration-tests/init-without-token/expected/codacy.yaml +++ b/integration-tests/init-without-token/expected/codacy.yaml @@ -12,4 +12,4 @@ tools: - pylint@3.3.6 - revive@1.7.0 - semgrep@1.78.0 - - trivy@0.65.0 + - trivy@0.66.0 diff --git a/integration-tests/init-without-token/expected/tools-configs/semgrep.yaml b/integration-tests/init-without-token/expected/tools-configs/semgrep.yaml index bf5e218f..d79dcc00 100644 --- a/integration-tests/init-without-token/expected/tools-configs/semgrep.yaml +++ b/integration-tests/init-without-token/expected/tools-configs/semgrep.yaml @@ -1,4 +1,367 @@ rules: + - id: ai.csharp.detect-openai.detect-openai + languages: + - csharp + message: 'Possibly found usage of AI: OpenAI' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: using OpenAI + - pattern: (ChatClient $CLIENT) + - pattern: (ChatClient $CLIENT).$FUNC(...) + severity: INFO + - id: ai.dart.detect-gemini.detect-gemini + languages: + - dart + message: 'Possibly found usage of AI: Gemini' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import 'package:google_generative_ai'; + - pattern: final $MODEL = GenerativeModel(...); + severity: INFO + - id: ai.go.detect-gemini.detect-gemini + languages: + - go + message: 'Possibly found usage of AI: Gemini' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import "github.com/google/generative-ai-go" + - pattern: genai.NewClient(...) + severity: INFO + - id: ai.go.detect-openai.detect-openai + languages: + - go + message: 'Possibly found usage of AI: OpenAI' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import "github.com/sashabaranov/go-openai" + - pattern: gogpt.NewClient(...) + severity: INFO + - id: ai.kotlin.detect-gemini.detect-gemini + languages: + - kotlin + message: 'Possibly found usage of AI: Gemini' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import com.google.ai + - pattern: GenerativeModel(...) + severity: INFO + - id: ai.python.detect-anthropic.detect-anthropic + languages: + - python + message: 'Possibly found usage of AI: Anthropic' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import anthropic + - pattern: from anthropic import $ANYTHING + - pattern: Anthropic(...) + - pattern: anthropic.Anthropic(...) + - pattern: $CLIENT.messages.$FUNC(...,model=...,...) + severity: INFO + - id: ai.python.detect-gemini.detect-gemini + languages: + - python + message: 'Possibly found usage of AI: Gemini' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import google.generativeai + severity: INFO + - id: ai.python.detect-huggingface.detect-huggingface + languages: + - python + message: 'Possibly found usage of AI: HuggingFace' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import huggingface_hub + severity: INFO + - id: ai.python.detect-langchain.detect-langchain + languages: + - python + message: 'Possibly found usage of AI tooling: LangChain' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import langchain_openai + - pattern: ChatOpenAI(...) + - pattern: import langchain_community + - pattern: Ollama(...) + - pattern: import langchain_anthropic + - pattern: ChatAnthropic(...) + - pattern: import langchain_cohere + - pattern: ChatCohere(...) + - pattern: import langchain_core + - pattern: import langchain + severity: INFO + - id: ai.python.detect-mistral.detect-mistral + languages: + - python + message: 'Possibly found usage of AI: Mistral' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import mistralai + - pattern: MistralClient(...) + - pattern: $CLIENT.chat(...,model=...,...) + severity: INFO + - id: ai.python.detect-openai.detect-openai + languages: + - python + message: 'Possibly found usage of AI: OpenAI' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import openai + - pattern: from openai import $ANYTHING + - pattern: OpenAI(...) + - pattern: $CLIENT.chat.completions.$FUNC(...) + severity: INFO + - id: ai.python.detect-pytorch.detect-pytorch + languages: + - python + message: 'Possibly found usage of AI tooling: PyTorch' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import torch + - pattern: torch.$FUNC(...) + severity: INFO + - id: ai.python.detect-tensorflow.detect-tensorflow + languages: + - python + message: 'Possibly found usage of AI tooling: Tensorflow' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import tensorflow + severity: INFO + - id: ai.swift.detect-apple-core-ml.detect-apple-core-ml + languages: + - swift + message: 'Possibly found usage of AI: Apple CoreML' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: VNCoreMLModel(...) + - pattern: MLModelConfiguration(...) + severity: INFO + - id: ai.swift.detect-gemini.detect-gemini + languages: + - swift + message: 'Possibly found usage of AI: Gemini' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import GoogleGenerativeAI + - pattern: GenerativeModel(...) + severity: INFO + - id: ai.typescript.detect-anthropic.detect-anthropic + languages: + - js + - ts + message: 'Possibly found usage of AI: Anthropic' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import "@anthropic-ai" + - pattern: import $ANYTHING from "@anthropic-ai"; + - pattern: new Anthropic(...) + - pattern: anthropic.messages.$FUNC(...) + severity: INFO + - id: ai.typescript.detect-gemini.detect-gemini + languages: + - js + - ts + message: 'Possibly found usage of AI: Gemini' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import "@google/generative-ai" + - pattern: import $ANYTHING from "@google/generative-ai"; + - pattern: new GoogleGenerativeAI(...) + - pattern: $GENAI.getGenerativeModel(...) + severity: INFO + - id: ai.typescript.detect-mistral.detect-mistral + languages: + - js + - ts + message: 'Possibly found usage of AI: Mistral' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import "@mistralai" + - pattern: new MistralClient(...) + - pattern: '$CLIENT.chat({model: ...})' + severity: INFO + - id: ai.typescript.detect-openai.detect-openai + languages: + - js + - ts + message: 'Possibly found usage of AI: OpenAI' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import "openai" + - pattern: import $ANYTHING from "openai"; + - pattern: new OpenAI(...) + - pattern: $CLIENT.chat.completions.$FUNC(...) + severity: INFO + - id: ai.typescript.detect-promptfoo.detect-promptfoo + languages: + - js + - ts + message: 'Possibly found usage of AI tooling: promptfoo' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import "promptfoo" + - pattern: promptfoo.evaluate(...) + severity: INFO + - id: ai.typescript.detect-vercel-ai.detect-vercel-ai + languages: + - js + - ts + message: 'Possibly found usage of AI: VercelAI' + metadata: + category: maintainability + confidence: LOW + references: + - http://semgrep.dev/blog/2024/detecting-shadow-ai + technology: + - genAI + - LLMs + pattern-either: + - pattern: import "ai" + - pattern: import "@ai-sdk" + - pattern: generateText({model:...}) + - pattern: generateText({prompt:...}) + severity: INFO - id: bash.curl.security.curl-eval.curl-eval languages: - bash @@ -28,6 +391,310 @@ rules: - pattern: | `curl ...` severity: WARNING + - id: bash.curl.security.curl-pipe-bash.curl-pipe-bash + languages: + - bash + message: Data is being piped into `bash` from a `curl` command. An attacker with control of the server in the `curl` command could inject malicious code into the pipe, resulting in a system compromise. Avoid piping untrusted data into `bash` or any other shell if you can. If you must do this, consider checking the SHA sum of the content returned by the server to verify its integrity. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - bash + - curl + patterns: + - pattern-either: + - pattern: curl ... | ... bash ... + - pattern: curl ... | ... /bin/bash ... + - pattern: '... bash <(curl ...)' + - pattern: '... /bin/bash <(curl ...)' + - pattern: '... bash -c "$(curl ...)"' + - pattern: '... /bin/bash -c "$(curl ...)"' + severity: WARNING + - id: bash.lang.best-practice.iteration-over-ls-output.iteration-over-ls-output + languages: + - bash + message: Iterating over ls output is fragile. Use globs, e.g. 'dir/*' instead of '$(ls dir)'. + metadata: + category: best-practice + references: + - https://github.com/koalaman/shellcheck/wiki/SC2045 + technology: + - bash + patterns: + - pattern: | + for $VAR in $LIST; do + ... + done + - pattern: | + $(ls ...) + severity: WARNING + - id: bash.lang.best-practice.useless-cat.useless-cat + languages: + - bash + message: Useless call to 'cat' in a pipeline. Use '<' and '>' for any command to read from a file or write to a file. + metadata: + category: best-practice + references: + - https://github.com/koalaman/shellcheck/wiki/SC2002 + technology: + - bash + pattern-either: + - pattern: | + cat | ... + - patterns: + - pattern: | + cat $ARG | ... + - pattern-not: | + cat ${$SEVERAL_FILES} | ... + - pattern: | + ... | cat + - pattern: | + ... | cat | ... + severity: WARNING + - id: bash.lang.correctness.unquoted-expansion.unquoted-variable-expansion-in-command + languages: + - bash + message: Variable expansions must be double-quoted so as to prevent being split into multiple pieces according to whitespace or whichever separator is specified by the IFS variable. If you really wish to split the variable's contents, you may use a variable that starts with an underscore e.g. $_X instead of $X, and semgrep will ignore it. If what you need is an array, consider using a proper bash array. + metadata: + category: correctness + technology: + - bash + patterns: + - pattern-either: + - pattern: | + ... ${$VAR} ... + - pattern: | + ... ...${$VAR}... ... + - metavariable-regex: + metavariable: $VAR + regex: '[*@0-9]|[A-Za-z].*' + severity: INFO + - id: bash.lang.correctness.unquoted-expansion.unquoted-command-substitution-in-command + languages: + - bash + message: The result of command substitution $(...) or `...`, if unquoted, is split on whitespace or other separators specified by the IFS variable. You should surround it with double quotes to avoid splitting the result. + metadata: + category: correctness + technology: + - bash + patterns: + - pattern-either: + - pattern: | + ... $(...) ... + - pattern: | + ... ...$(...)... ... + - pattern-regex: | + .*(\$\([^\(]|`).+([^\)]\)|`).* + severity: INFO + - id: bash.lang.security.ifs-tampering.ifs-tampering + languages: + - bash + message: The special variable IFS affects how splitting takes place when expanding unquoted variables. Don't set it globally. Prefer a dedicated utility such as 'cut' or 'awk' if you need to split input data. If you must use 'read', set IFS locally using e.g. 'IFS="," read -a my_array'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-20: Improper Input Validation' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - bash + pattern: IFS=... + severity: WARNING + - fix: strcmp($X, $Y) == 0 + id: c.lang.correctness.c-string-equality.c-string-equality + languages: + - c + - cpp + message: Using == on char* performs pointer comparison, use strcmp instead + metadata: + category: correctness + technology: + - c + - cpp + patterns: + - pattern: (char *$X) == (char *$Y) + - metavariable-comparison: + comparison: $X != 0 + metavariable: $X + - metavariable-comparison: + comparison: $Y != 0 + metavariable: $Y + severity: ERROR + - id: c.lang.correctness.goto-fail.double_goto + languages: + - c + - cpp + message: The second goto statement will always be executed. + metadata: + category: correctness + technology: + - c + - cpp + pattern: | + if ($COND) + goto $FAIL; + goto $FAIL; + severity: WARNING + - id: c.lang.correctness.incorrect-use-ato-fn.incorrect-use-ato-fn + languages: + - c + - cpp + message: Avoid the 'ato*()' family of functions. Their use can lead to undefined behavior, integer overflows, and lack of appropriate error handling. Instead prefer the 'strtol*()' family of functions. + metadata: + category: correctness + references: + - https://stackoverflow.com/q/38393162 + - https://stackoverflow.com/q/14176123 + technology: + - c + - cpp + pattern-either: + - pattern: atoi(...) + - pattern: atol(...) + - pattern: atoll(...) + severity: WARNING + - id: c.lang.correctness.incorrect-use-sscanf-fn.incorrect-use-sscanf-fn + languages: + - c + - cpp + message: Avoid 'sscanf()' for number conversions. Its use can lead to undefined behavior, slow processing, and integer overflows. Instead prefer the 'strto*()' family of functions. + metadata: + category: correctness + references: + - https://stackoverflow.com/q/22865622 + - https://stackoverflow.com/q/7021725 + - https://www.mattkeeter.com/blog/2021-03-01-happen/ + technology: + - c + - cpp + patterns: + - pattern: sscanf($STR, $FMT, $PTR); + - metavariable-regex: + metavariable: $FMT + regex: '"%(l{0,2}|L)([fegEa]|[dDiouxX])"' + severity: WARNING + - id: c.lang.security.double-free.double-free + languages: + - c + - cpp + message: Variable '$VAR' was freed twice. This can lead to undefined behavior. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-415: Double Free' + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + - A01:2017 - Injection + references: + - https://cwe.mitre.org/data/definitions/415.html + - https://owasp.org/www-community/vulnerabilities/Doubly_freeing_memory + subcategory: + - vuln + technology: + - c + - cpp + patterns: + - pattern-not: | + free($VAR); + ... + $VAR = NULL; + ... + free($VAR); + - pattern-not: | + free($VAR); + ... + $VAR = malloc(...); + ... + free($VAR); + - pattern-inside: | + free($VAR); + ... + $FREE($VAR); + - metavariable-pattern: + metavariable: $FREE + pattern: free + - focus-metavariable: $FREE + severity: ERROR + - id: c.lang.security.function-use-after-free.function-use-after-free + languages: + - c + - cpp + message: Variable '$VAR' was passed to a function after being freed. This can lead to undefined behavior. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-416: Use After Free' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + references: + - https://cwe.mitre.org/data/definitions/416.html + - https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/use_after_free/ + subcategory: + - vuln + technology: + - c + - cpp + patterns: + - pattern-either: + - pattern: $FUNC(..., <... $VAR ...>, ...) + - pattern: $FUNC(..., <... $VAR->$ACCESSOR ...>, ...) + - pattern: $FUNC(..., <... (*$VAR).$ACCESSOR ...>, ...) + - pattern: $FUNC(..., <... $VAR[$NUM] ...>, ...) + - metavariable-regex: + metavariable: $FUNC + regex: (?!^free$) + - pattern-inside: free($VAR); ... + - pattern-not-inside: free($VAR); ... $VAR = NULL; ... + - pattern-not-inside: free($VAR); ... $VAR = malloc(...); ... + severity: WARNING + - id: c.lang.security.info-leak-on-non-formatted-string.info-leak-on-non-formated-string + languages: + - c + - cpp + message: Use %s, %d, %c... to format your variables, otherwise this could leak information. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-532: Insertion of Sensitive Information into Log File' + impact: MEDIUM + likelihood: LOW + owasp: + - A09:2021 - Security Logging and Monitoring Failures + references: + - http://nebelwelt.net/files/13PPREW.pdf + subcategory: + - audit + technology: + - c + - cpp + pattern: printf(argv[$NUM]); + severity: WARNING - id: c.lang.security.insecure-use-gets-fn.insecure-use-gets-fn languages: - c @@ -49,6 +716,164 @@ rules: - cpp pattern: gets(...) severity: ERROR + - fix: memset_s($...VARS) + id: c.lang.security.insecure-use-memset.insecure-use-memset + languages: + - c + - cpp + message: When handling sensitive information in a buffer, it's important to ensure that the data is securely erased before the buffer is deleted or reused. While `memset()` is commonly used for this purpose, it can leave sensitive information behind due to compiler optimizations or other factors. To avoid this potential vulnerability, it's recommended to use the `memset_s()` function instead. `memset_s()` is a standardized function that securely overwrites the memory with a specified value, making it more difficult for an attacker to recover any sensitive data that was stored in the buffer. By using `memset_s()` instead of `memset()`, you can help to ensure that your application is more secure and less vulnerable to exploits that rely on residual data in memory. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-14: Compiler Removal of Code to Clear Buffers' + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://cwe.mitre.org/data/definitions/14.html + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures/ + subcategory: + - audit + technology: + - c + - cpp + pattern: memset($...VARS) + severity: WARNING + - id: c.lang.security.insecure-use-printf-fn.insecure-use-printf-fn + languages: + - c + - cpp + message: Avoid using user-controlled format strings passed into 'sprintf', 'printf' and 'vsprintf'. These functions put you at risk of buffer overflow vulnerabilities through the use of format string exploits. Instead, use 'snprintf' and 'vsnprintf'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-134: Use of Externally-Controlled Format String' + impact: HIGH + likelihood: MEDIUM + references: + - https://doc.castsoftware.com/display/SBX/Never+use+sprintf%28%29+or+vsprintf%28%29+functions + - https://www.cvedetails.com/cwe-details/134/Uncontrolled-Format-String.html + subcategory: + - vuln + technology: + - c + - cpp + patterns: + - pattern-either: + - pattern: | + $FUNC($BUFFER, argv[$NUM], ...); + ... + vsprintf(..., $BUFFER, ...); + - pattern: vsprintf(..., argv[$NUM], ...) + - pattern: | + $FUNC($BUFFER, argv[$NUM], ...); + ... + sprintf(..., $BUFFER, ...); + - pattern: sprintf(...,argv[$NUM],...) + - pattern: | + $FUNC($BUFFER, argv[$NUM], ...); + ... + printf(..., $BUFFER, ...); + - pattern: printf(...,argv[$NUM],...) + - metavariable-comparison: + comparison: int($NUM) > 0 + metavariable: $NUM + severity: WARNING + - id: c.lang.security.insecure-use-scanf-fn.insecure-use-scanf-fn + languages: + - c + - cpp + message: Avoid using 'scanf()'. This function, when used improperly, does not consider buffer boundaries and can lead to buffer overflows. Use 'fgets()' instead for reading input. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-676: Use of Potentially Dangerous Function' + impact: HIGH + likelihood: LOW + references: + - http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html + subcategory: + - audit + technology: + - c + - cpp + pattern: scanf(...) + severity: WARNING + - id: c.lang.security.insecure-use-strcat-fn.insecure-use-strcat-fn + languages: + - c + - cpp + message: Finding triggers whenever there is a strcat or strncat used. This is an issue because strcat or strncat can lead to buffer overflow vulns. Fix this by using strcat_s instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-676: Use of Potentially Dangerous Function' + impact: HIGH + likelihood: LOW + references: + - https://nvd.nist.gov/vuln/detail/CVE-2019-12553 + - https://techblog.mediaservice.net/2020/04/cve-2020-2851-stack-based-buffer-overflow-in-cde-libdtsvc/ + subcategory: + - audit + technology: + - c + - cpp + pattern-either: + - pattern: strcat(...) + - pattern: strncat(...) + severity: WARNING + - id: c.lang.security.insecure-use-string-copy-fn.insecure-use-string-copy-fn + languages: + - c + - cpp + message: Finding triggers whenever there is a strcpy or strncpy used. This is an issue because strcpy does not affirm the size of the destination array and strncpy will not automatically NULL-terminate strings. This can lead to buffer overflows, which can cause program crashes and potentially let an attacker inject code in the program. Fix this by using strcpy_s instead (although note that strcpy_s is an optional part of the C11 standard, and so may not be available). + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-676: Use of Potentially Dangerous Function' + impact: HIGH + likelihood: LOW + references: + - https://cwe.mitre.org/data/definitions/676 + - https://nvd.nist.gov/vuln/detail/CVE-2019-11365 + subcategory: + - audit + technology: + - c + - cpp + pattern-either: + - pattern: strcpy(...) + - pattern: strncpy(...) + severity: WARNING + - id: c.lang.security.insecure-use-strtok-fn.insecure-use-strtok-fn + languages: + - c + - cpp + message: Avoid using 'strtok()'. This function directly modifies the first argument buffer, permanently erasing the delimiter character. Use 'strtok_r()' instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-676: Use of Potentially Dangerous Function' + impact: HIGH + likelihood: LOW + references: + - https://wiki.sei.cmu.edu/confluence/display/c/STR06-C.+Do+not+assume+that+strtok%28%29+leaves+the+parse+string+unchanged + - https://man7.org/linux/man-pages/man3/strtok.3.html#BUGS + - https://stackoverflow.com/a/40335556 + subcategory: + - audit + technology: + - c + - cpp + pattern: strtok(...) + severity: WARNING - id: c.lang.security.random-fd-exhaustion.random-fd-exhaustion languages: - c @@ -88,6 +913,72 @@ rules: ... $BYTES_READ = read($FD, ...); severity: WARNING + - id: c.lang.security.use-after-free.use-after-free + languages: + - c + - cpp + message: Variable '$VAR' was used after being freed. This can lead to undefined behavior. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-416: Use After Free' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + references: + - https://cwe.mitre.org/data/definitions/416.html + - https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/use_after_free/ + subcategory: + - vuln + technology: + - c + - cpp + patterns: + - pattern-either: + - pattern: $VAR->$ACCESSOR + - pattern: (*$VAR).$ACCESSOR + - pattern: $VAR[$NUM] + - pattern-inside: free($VAR); ... + - pattern-not-inside: $VAR = NULL; ... + - pattern-not-inside: free($VAR); ... $VAR = malloc(...); ... + severity: WARNING + - id: clojure.lang.security.command-injection-shell-call.command-injection-shell-call + languages: + - clojure + message: A call to clojure.java.shell has been found, this could lead to an RCE if the inputs are user-controllable. Please ensure their origin is validated and sanitized. + metadata: + author: Gabriel Marquet + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://clojuredocs.org/clojure.java.shell/sh + subcategory: + - audit + technology: + - clojure + patterns: + - pattern-either: + - pattern-inside: "(ns ...\n...\n(:require \n... \n[clojure.java.shell ... [sh]]\n...\n))\n...\n" + - pattern-inside: "(ns ...\n...\n(:use \n... \n[clojure.java.shell ... [sh]]\n...\n))\n...\n" + - pattern-either: + - patterns: + - pattern: (sh $BASH ...) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern: (sh $ARG ...) + - pattern-not: (sh "..." ...) + severity: ERROR - id: clojure.lang.security.documentbuilderfactory-xxe.documentbuilderfactory-xxe languages: - clojure @@ -210,18 +1101,56 @@ rules: metavariable: $ALGO regex: (((org\.apache\.commons\.codec\.digest\.)?MessageDigestAlgorithms/)?"?(SHA-1|SHA1)"?) severity: WARNING - - id: csharp.dotnet.security.audit.ldap-injection.ldap-injection + - id: clojure.security.clojure-read-string.read-string-unsafe.read-string-unsafe languages: - - csharp - message: LDAP queries are constructed dynamically on user-controlled input. This vulnerability in code could lead to an arbitrary LDAP query execution. + - clojure + message: The default core Clojure read-string method is dangerous and can lead to deserialization vulnerabilities. Use the edn/read-string instead. metadata: + author: Gabriel Marquet category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2020-top25: true + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - http://www.learningclojure.com/2013/02/clojures-reader-is-unsafe.html#post-body-2898830171141471587 + - https://ericnormand.me/article/clojure-web-security + - https://github.com/jafingerhut/jafingerhut.github.com/blob/master/clojure-info/using-edn-safely.md#vulnerabilities-in-clojurecores-read-and-read-string + source-rule-url: https://github.com/clj-holmes/clj-holmes-rules/tree/main/security/clojure-read-string + subcategory: + - audit + technology: + - clojure + patterns: + - pattern-not-inside: | + (ns ... + (... :exclude [read read-string])) + ... + (defn $VAR [$X]...) + - pattern-inside: | + (defn $VAR [$X]...) + - pattern: | + (read-string $X) + severity: ERROR + - id: csharp.dotnet.security.audit.ldap-injection.ldap-injection + languages: + - csharp + message: LDAP queries are constructed dynamically on user-controlled input. This vulnerability in code could lead to an arbitrary LDAP query execution. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: - A01:2017 - Injection - A03:2021 - Injection references: @@ -298,6 +1227,37 @@ rules: } - focus-metavariable: $ARG severity: WARNING + - id: csharp.dotnet.security.audit.misconfigured-lockout-option.misconfigured-lockout-option + languages: + - csharp + message: A misconfigured lockout mechanism allows an attacker to execute brute-force attacks. Account lockout must be correctly configured and enabled to prevent these attacks. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-307: Improper Restriction of Excessive Authentication Attempts' + impact: HIGH + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + - https://cwe.mitre.org/data/definitions/307.html + subcategory: + - audit + technology: + - dotnet + patterns: + - pattern-either: + - pattern: | + $SIGNIN.PasswordSignInAsync(...,lockoutOnFailure: false,...); + - pattern: | + $SIGNIN.CheckPasswordSignInAsync(...,lockoutOnFailure: false,...); + - pattern-inside: | + public async $TYPE $METHOD(...) { + ... + } + severity: WARNING - id: csharp.dotnet.security.audit.missing-or-broken-authorization.missing-or-broken-authorization languages: - csharp @@ -384,6 +1344,39 @@ rules: ... } severity: INFO + - id: csharp.dotnet.security.audit.razor-use-of-htmlstring.razor-use-of-htmlstring + languages: + - generic + message: ASP.NET Core MVC provides an HtmlString class which isn't automatically encoded upon output. This should never be used in combination with untrusted input as this will expose an XSS vulnerability. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-116: Improper Encoding or Escaping of Output' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://cwe.mitre.org/data/definitions/116.html + - https://owasp.org/Top10/A03_2021-Injection/ + - https://docs.microsoft.com/en-us/aspnet/core/security/cross-site-scripting?view=aspnetcore-6.0#html-encoding-using-razor + subcategory: + - audit + technology: + - .net + paths: + include: + - '*.cshtml' + patterns: + - pattern-either: + - pattern: new ...HtmlString(...) + - pattern: '@(new ...HtmlString(...))' + - pattern-not-inside: '@(new ...HtmlString(...HtmlEncode(...)))' + - pattern-not-inside: '@(new ...HtmlString(...Encode(...)))' + - pattern-not-inside: new ...HtmlString(...HtmlEncode(...)) + - pattern-not-inside: new ...HtmlString(...Encode(...)) + severity: WARNING - id: csharp.dotnet.security.audit.xpath-injection.xpath-injection languages: - csharp @@ -422,6 +1415,113 @@ rules: string $INPUT; } severity: ERROR + - id: csharp.dotnet.security.mvc-missing-antiforgery.mvc-missing-antiforgery + languages: + - csharp + message: $METHOD is a state-changing MVC method that does not validate the antiforgery token or do strict content-type checking. State-changing controller methods should either enforce antiforgery tokens or do strict content-type checking to prevent simple HTTP request types from bypassing CORS preflight controls. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://cheatsheetseries.owasp.org/cheatsheets/DotNet_Security_Cheat_Sheet.html#cross-site-request-forgery + - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests + subcategory: + - audit + technology: + - .net + - mvc + patterns: + - pattern: | + [$HTTPMETHOD] + public IActionResult $METHOD(...){ + ... + } + - pattern-inside: | + using Microsoft.AspNetCore.Mvc; + ... + - pattern-not: | + [ValidateAntiForgeryToken] + public IActionResult $METHOD(...){ + ... + } + - pattern-not: | + [Consumes(...)] + public IActionResult $METHOD(...){ + ... + } + - metavariable-regex: + metavariable: $HTTPMETHOD + regex: Http(Post|Put|Delete|Patch) + severity: WARNING + - id: csharp.dotnet.security.net-webconfig-debug.net-webconfig-debug + languages: + - generic + message: ASP.NET applications built with `debug` set to true in production may leak debug information to attackers. Debug mode also affects performance and reliability. Set `debug` to `false` or remove it from `` + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-11: ASP.NET Misconfiguration: Creating Debug Binary' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://web.archive.org/web/20190919105353/https://blogs.msdn.microsoft.com/prashant_upadhyay/2011/07/14/why-debugfalse-in-asp-net-applications-in-production-environment/ + - https://msdn.microsoft.com/en-us/library/e8z01xdh.aspx + subcategory: + - audit + technology: + - .net + paths: + include: + - '*web.config*' + patterns: + - pattern: | + + - pattern-inside: | + + ... + + severity: WARNING + - id: csharp.dotnet.security.net-webconfig-trace-enabled.net-webconfig-trace-enabled + languages: + - generic + message: OWASP guidance recommends disabling tracing for production applications to prevent accidental leakage of sensitive application information. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-1323: Improper Management of Sensitive Trace Data' + impact: MEDIUM + likelihood: LOW + owasp: A05:2021 - Security Misconfiguration + references: + - https://cheatsheetseries.owasp.org/cheatsheets/DotNet_Security_Cheat_Sheet.html#asp-net-web-forms-guidance + - https://msdn.microsoft.com/en-us/library/e8z01xdh.aspx + subcategory: + - audit + technology: + - .net + paths: + include: + - '*web.config*' + patterns: + - pattern: | + + - pattern-inside: | + + ... + + severity: WARNING - id: csharp.dotnet.security.razor-template-injection.razor-template-injection languages: - csharp @@ -595,6 +1695,89 @@ rules: - pattern: (RSAPKCS1KeyExchangeFormatter $FORMATER).CreateKeyExchange(...); - pattern: (RSAPKCS1KeyExchangeDeformatter $DEFORMATER).DecryptKeyExchange(...); severity: WARNING + - id: csharp.dotnet.security.web-config-insecure-cookie-settings.web-config-insecure-cookie-settings + languages: + - generic + message: Cookie Secure flag is explicitly disabled. You should enforce this value to avoid accidentally presenting sensitive cookie values over plaintext HTTP connections. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/http-cookies + - https://docs.microsoft.com/en-us/dotnet/api/system.web.security.formsauthentication.requiressl?redirectedfrom=MSDN&view=netframework-4.8#System_Web_Security_FormsAuthentication_RequireSSL + - https://docs.microsoft.com/en-us/dotnet/api/system.web.security.roles.cookierequiressl?redirectedfrom=MSDN&view=netframework-4.8#System_Web_Security_Roles_CookieRequireSSL + subcategory: + - audit + technology: + - .net + - asp + - webforms + paths: + include: + - '*web.config' + patterns: + - pattern-either: + - pattern: | + requireSSL="false" + - pattern: | + cookieRequireSSL="false" + - pattern-either: + - pattern-inside: | + + - pattern-inside: | + + - pattern-inside: | + + severity: WARNING + - id: csharp.lang.best-practice.structured-logging.structured-logging + languages: + - csharp + message: String interpolation in log message obscures the distinction between variables and the log message. Use structured logging instead, where the variables are passed as additional arguments and the interpolation is performed by the logging library. This reduces the possibility of log injection and makes it easier to search through logs. + metadata: + category: best-practice + confidence: LOW + cwe: + - 'CWE-117: Improper Output Neutralization for Logs' + impact: LOW + likelihood: LOW + owasp: + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://github.com/NLog/NLog/wiki/How-to-use-structured-logging + - https://softwareengineering.stackexchange.com/questions/312197/benefits-of-structured-logging-vs-basic-logging + subcategory: + - audit + technology: + - .net + - serilog + - nlog + patterns: + - pattern-either: + - pattern: $LOG.Debug($"...") + - pattern: $LOG.Error($"...") + - pattern: $LOG.Fatal($"...") + - pattern: $LOG.Information($"...") + - pattern: $LOG.Verbose($"...") + - pattern: $LOG.Warning($"...") + - pattern: $LOG.LogCritical($"...") + - pattern: $LOG.LogDebug($"...") + - pattern: $LOG.LogError($"...") + - pattern: $LOG.LogInformation($"...") + - pattern: $LOG.LogTrace($"...") + - pattern: $LOG.LogWarning($"...") + - pattern: $LOG.Info($"...") + - pattern: $LOG.Trace($"...") + - pattern: $LOG.Warn($"...") + - metavariable-regex: + metavariable: $LOG + regex: .*(log|LOG|Log) + severity: INFO - id: csharp.lang.correctness.double.double-epsilon-equality.correctness-double-epsilon-equality languages: - csharp @@ -795,6 +1978,38 @@ rules: - pattern: $CERT.SubjectName.Name - pattern: $CERT.GetNameInfo(...) severity: WARNING + - id: csharp.lang.security.cryptography.x509certificate2-privkey.x509certificate2-privkey + languages: + - C# + message: 'X509Certificate2.PrivateKey is obsolete. Use a method such as GetRSAPrivateKey() or GetECDsaPrivateKey(). Alternatively, use the CopyWithPrivateKey() method to create a new instance with a private key. Further, if you set X509Certificate2.PrivateKey to `null` or set it to another key without deleting it first, the private key will be left on disk. ' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-310: CWE CATEGORY: Cryptographic Issues' + impact: LOW + likelihood: LOW + owasp: + - A02:2021 - Cryptographic Failures + references: + - https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate2.privatekey + subcategory: + - audit + technology: + - .net + patterns: + - pattern-inside: | + using System.Security.Cryptography; + ... + - pattern-either: + - pattern-inside: | + X509Certificate2Collection $COLLECTION = ...; + ... + - pattern-inside: | + X509Certificate2 $CERT = ...; + ... + - pattern: $CERT.PrivateKey + severity: WARNING - fix: RequireSignedTokens = true id: csharp.lang.security.cryptography.unsigned-security-token.unsigned-security-token languages: @@ -910,6 +2125,93 @@ rules: metavariable: $PREFIX regex: (http|https)://(\*|\+)(.[a-zA-Z]{2,})?:[0-9]+ severity: WARNING + - id: csharp.lang.security.injections.os-command.os-command-injection + languages: + - csharp + message: The software constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/Command_Injection + subcategory: + - audit + technology: + - .net + patterns: + - pattern-inside: | + using System.Diagnostics; + ... + - pattern-inside: | + public $T $F(..., $ARG, ...) + { + ... + } + - pattern-either: + - patterns: + - pattern: | + Process.Start($ARG, ...); + - focus-metavariable: $ARG + - patterns: + - pattern-inside: | + Process $PROC = new Process(); + ... + - pattern-either: + - pattern-inside: | + $PROC.StartInfo.FileName = $ARG; + ... + - pattern-inside: | + $PROC.StartInfo.Arguments = <... $ARG ...>; + ... + - pattern: | + $PROC.Start(); + - patterns: + - patterns: + - pattern-inside: | + ProcessStartInfo $PSINFO = new ProcessStartInfo() + { + ... + }; + ... + - pattern-either: + - pattern-inside: | + FileName = $ARG; + ... + - pattern-inside: | + Arguments = <... $ARG ...>; + ... + - pattern: | + Process.Start($PSINFO); + - focus-metavariable: $PSINFO + - patterns: + - pattern-inside: | + Process $PROC = new Process() + { + StartInfo = new ProcessStartInfo() + { + ... + } + }; + ... + - pattern-either: + - pattern-inside: | + FileName = $ARG; + ... + - pattern-inside: | + Arguments = $ARG; + ... + - pattern: | + $PROC.Start(); + severity: ERROR - id: csharp.lang.security.insecure-deserialization.binary-formatter.insecure-binaryformatter-deserialization languages: - C# @@ -939,6 +2241,64 @@ rules: - pattern: | new BinaryFormatter(); severity: WARNING + - id: csharp.lang.security.insecure-deserialization.data-contract-resolver.data-contract-resolver + languages: + - C# + message: Only use DataContractResolver if you are completely sure of what information is being serialized. Malicious types can cause unexpected behavior. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide + subcategory: + - audit + technology: + - .net + patterns: + - pattern: | + class $MYDCR : DataContractResolver { ... } + severity: WARNING + - id: csharp.lang.security.insecure-deserialization.fast-json.insecure-fastjson-deserialization + languages: + - C# + message: $type extension has the potential to be unsafe, so use it with common sense and known json sources and not public facing ones to be safe + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://github.com/mgholam/fastJSON#security-warning-update + subcategory: + - audit + technology: + - .net + patterns: + - pattern-inside: | + using fastJSON; + ... + - pattern: | + new JSONParameters + { + BadListTypeChecking = false + } + severity: WARNING - id: csharp.lang.security.insecure-deserialization.fs-pickler.insecure-fspickler-deserialization languages: - C# @@ -968,6 +2328,80 @@ rules: - pattern: | FsPickler.CreateJsonSerializer(); severity: WARNING + - id: csharp.lang.security.insecure-deserialization.insecure-typefilterlevel-full.insecure-typefilterlevel-full + languages: + - C# + message: Using a .NET remoting service can lead to RCE, even if you try to configure TypeFilterLevel. Recommended to switch from .NET Remoting to WCF https://docs.microsoft.com/en-us/dotnet/framework/wcf/migrating-from-net-remoting-to-wcf + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.typefilterlevel?view=net-6.0 + - https://www.synacktiv.com/en/publications/izi-izi-pwn2own-ics-miami.html + subcategory: + - audit + technology: + - .net + pattern-either: + - patterns: + - pattern-either: + - pattern: new BinaryServerFormatterSinkProvider { TypeFilterLevel = $LEVEL } + - patterns: + - pattern-inside: | + $TYPE $SP = new BinaryServerFormatterSinkProvider(...); + ... + - pattern: | + $SP.TypeFilterLevel = $LEVEL + - metavariable-regex: + metavariable: $LEVEL + regex: (.*)TypeFilterLevel\.(Full|Low) + - patterns: + - pattern-inside: | + $DICT["typeFilterLevel"] = $VAL; + ... + - pattern: new BinaryServerFormatterSinkProvider(..., $DICT, ...) + - metavariable-regex: + metavariable: $VAL + regex: (\"Full\"|\"Low\") + severity: WARNING + - id: csharp.lang.security.insecure-deserialization.javascript-serializer.insecure-javascriptserializer-deserialization + languages: + - C# + message: The SimpleTypeResolver class is insecure and should not be used. Using SimpleTypeResolver to deserialize JSON could allow the remote client to execute malicious code within the app and take control of the web server. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.microsoft.com/en-us/dotnet/api/system.web.script.serialization.simpletyperesolver?view=netframework-4.8#remarks + subcategory: + - audit + technology: + - .net + patterns: + - pattern-inside: | + using System.Web.Script.Serialization; + ... + - pattern: | + new JavaScriptSerializer((SimpleTypeResolver $RESOLVER)) + severity: ERROR - id: csharp.lang.security.insecure-deserialization.los-formatter.insecure-losformatter-deserialization languages: - C# @@ -1026,6 +2460,48 @@ rules: - pattern: | new NetDataContractSerializer(); severity: WARNING + - id: csharp.lang.security.insecure-deserialization.newtonsoft.insecure-newtonsoft-deserialization + languages: + - csharp + message: TypeNameHandling $TYPEHANDLER is unsafe and can lead to arbitrary code execution in the context of the process. Use a custom SerializationBinder whenever using a setting other than TypeNameHandling.None. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_TypeNameHandling.htm#remarks + subcategory: + - audit + technology: + - .net + - newtonsoft + - json + patterns: + - pattern-either: + - pattern: TypeNameHandling = TypeNameHandling.$TYPEHANDLER + - pattern: | + $SETTINGS.TypeNameHandling = TypeNameHandling.$TYPEHANDLER; + ... + JsonConvert.DeserializeObject<$TYPE>(...,$SETTINGS); + - pattern: | + $SETTINGS.TypeNameHandling = TypeNameHandling.$TYPEHANDLER; + ... + JsonConvert.DeserializeObject(...,$SETTINGS); + - pattern-inside: | + using Newtonsoft.Json; + ... + - metavariable-regex: + metavariable: $TYPEHANDLER + regex: (All|Auto|Objects|Arrays) + severity: WARNING - id: csharp.lang.security.insecure-deserialization.soap-formatter.insecure-soapformatter-deserialization languages: - C# @@ -1055,6 +2531,115 @@ rules: - pattern: | new SoapFormatter(); severity: WARNING + - id: csharp.lang.security.memory.memory-marshal-create-span.memory-marshal-create-span + languages: + - C# + message: MemoryMarshal.CreateSpan and MemoryMarshal.CreateReadOnlySpan should be used with caution, as the length argument is not checked. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-125: Out-of-bounds Read' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.memorymarshal.createspan?view=net-6.0 + - https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.memorymarshal.createreadonlyspan?view=net-6.0 + subcategory: + - audit + technology: + - .net + pattern-either: + - pattern: MemoryMarshal.CreateSpan(...) + - pattern: MemoryMarshal.CreateReadOnlySpan(...) + severity: WARNING + - id: csharp.lang.security.missing-hsts-header.missing-hsts-header + languages: + - csharp + message: The HSTS HTTP response security header is missing, allowing interaction and communication to be sent over the insecure HTTP protocol. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-346: Origin Validation Error' + impact: LOW + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://cwe.mitre.org/data/definitions/346.html + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures/ + subcategory: + - audit + technology: + - dotnet + pattern-either: + - patterns: + - pattern-inside: | + public void Configure(...) { + ... + (IApplicationBuilder $APP). ...; + ... + } + - focus-metavariable: $APP + - pattern-not-inside: | + public void Configure(...) { + ... + (IApplicationBuilder $APP).UseHsts(...); + ... + } + - patterns: + - pattern-inside: | + public void ConfigureServices(...) { + ... + (IServiceCollection $SERVICES). ...; + ... + } + - focus-metavariable: $SERVICES + - pattern-not-inside: | + public void ConfigureServices(...) { + ... + (IServiceCollection $SERVICES).AddHsts(...); + ... + } + severity: WARNING + - id: csharp.lang.security.open-redirect.open-redirect + languages: + - csharp + message: A query string parameter may contain a URL value that could cause the web application to redirect the request to a malicious website controlled by an attacker. Make sure to sanitize this parameter sufficiently. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://cwe.mitre.org/data/definitions/601.html + subcategory: + - vuln + technology: + - csharp + mode: taint + pattern-sinks: + - patterns: + - pattern: Redirect(...) + - pattern-not-inside: "if (IsLocalUrl(...)) { \n ... \n Redirect(...); \n ...\n}\n" + - pattern-not-inside: "if ($URL.IsLocalUrl(...)) { \n ... \n Redirect(...); \n ...\n}\n" + pattern-sources: + - patterns: + - focus-metavariable: $PARAM + - pattern-inside: | + public $TYPE $FUNCNAME (..., string $PARAM, ...) { + ... + } + severity: ERROR - id: csharp.lang.security.regular-expression-dos.regular-expression-dos-infinite-timeout.regular-expression-dos-infinite-timeout languages: - C# @@ -1191,6 +2776,243 @@ rules: - pattern-not: | "..." severity: ERROR + - id: csharp.lang.security.ssrf.http-client.ssrf + languages: + - csharp + message: SSRF is an attack vector that abuses an application to interact with the internal/external network or the machine itself. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - .net + patterns: + - pattern-inside: | + using System.Net.Http; + ... + - pattern-either: + - pattern: | + $T $F(..., $X, ...) + { + ... + HttpClient $Y = new HttpClient(); + ... + ... $Y.GetAsync(<... $X ...>, ...); + } + - pattern: | + $T $F(..., $X, ...) + { + ... + $A $B = <... $X ...>; + ... + HttpClient $Y = new HttpClient(); + ... + ... $Y.GetAsync($B, ...); + } + - pattern: | + $T $F(..., $X, ...) + { + ... + HttpClient $Y = new HttpClient(); + ... + ... $Y.GetStringAsync(<... $X ...>); + } + - pattern: | + $T $F(..., $X, ...) + { + ... + $A $B = <... $X ...>; + ... + HttpClient $Y = new HttpClient(); + ... + ... $Y.GetStringAsync($B); + } + severity: ERROR + - id: csharp.lang.security.ssrf.rest-client.ssrf + languages: + - csharp + message: SSRF is an attack vector that abuses an application to interact with the internal/external network or the machine itself. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - .net + patterns: + - pattern-inside: | + using RestSharp; + ... + - pattern-either: + - pattern: | + $T $F(..., $X, ...) + { + ... + ... new RestClient(<... $X ...>); + } + - pattern: | + $T $F(..., $X, ...) + { + ... + $A $B = <... $X ...>; + ... + ... new RestClient($B); + } + severity: ERROR + - id: csharp.lang.security.ssrf.web-client.ssrf + languages: + - csharp + message: SSRF is an attack vector that abuses an application to interact with the internal/external network or the machine itself. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - .net + patterns: + - pattern-inside: | + using System.Net; + ... + - pattern-either: + - pattern: | + $T $F(..., $X, ...) + { + ... + WebClient $Y = new WebClient(); + ... + ... $Y.OpenRead(<... $X ...>); + } + - pattern: | + $T $F(..., $X, ...) + { + ... + $A $B = <... $X ...>; + ... + WebClient $Y = new WebClient(); + ... + ... $Y.OpenRead($B); + } + - pattern: | + $T $F(..., $X, ...) + { + ... + WebClient $Y = new WebClient(); + ... + ... $Y.OpenReadAsync(<... $X ...>, ...); + } + - pattern: | + $T $F(..., $X, ...) + { + ... + $A $B = <... $X ...>; + ... + WebClient $Y = new WebClient(); + ... + ... $Y.OpenReadAsync($B, ...); + } + - pattern: | + $T $F(..., $X, ...) + { + ... + WebClient $Y = new WebClient(); + ... + ... $Y.DownloadString(<... $X ...>); + } + - pattern: | + $T $F(..., $X, ...) + { + ... + $A $B = <... $X ...>; + ... + WebClient $Y = new WebClient(); + ... + ... $Y.DownloadString($B); + } + severity: ERROR + - id: csharp.lang.security.ssrf.web-request.ssrf + languages: + - csharp + message: The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. Many different options exist to fix this issue depending the use case (Application can send request only to identified and trusted applications, Application can send requests to ANY external IP address or domain name). + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cwe.mitre.org/data/definitions/918.html + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - .net + patterns: + - pattern-inside: | + using System.Net; + ... + - pattern-either: + - pattern: | + $T $F(..., $X, ...) + { + ... + ... WebRequest.Create(<... $X ...>); + } + - pattern: | + $T $F($X) + { + ... + $A $B = <... $X ...>; + ... + ... WebRequest.Create($B); + } + - pattern: | + $T $F($X) + { + ... + $A $B = <... $X ...>; + ... + $C $D = <... $B ...>; + ... + ... WebRequest.Create($D); + } + severity: ERROR - id: csharp.lang.security.stacktrace-disclosure.stacktrace-disclosure languages: - csharp @@ -1329,2211 +3151,1612 @@ rules: - pattern-inside: | public $T $M(...,string $ARG,...){...} severity: WARNING - - id: dockerfile.security.last-user-is-root.last-user-is-root + - id: csharp.razor.security.html-raw-json.html-raw-json languages: - - dockerfile - message: The last user in the container is 'root'. This is a security hazard because if an attacker gains control of the container they will have root access. Switch back to another user after running commands as 'root'. + - generic + message: Unencoded JSON in HTML context is vulnerable to cross-site scripting, because `` is not properly encoded. metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-269: Improper Privilege Management' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A04:2021 - Insecure Design + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://github.com/hadolint/hadolint/wiki/DL3002 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3002 + - https://owasp.org/Top10/A03_2021-Injection subcategory: - audit technology: - - dockerfile + - razor + paths: + include: + - '*.cshtml' patterns: - - pattern: USER root - - pattern-not-inside: - patterns: - - pattern: | - USER root - ... - USER $X - - metavariable-pattern: - metavariable: $X - patterns: - - pattern-not: root + - pattern-either: + - pattern: '@Html.Raw(Json.Encode(...))' + - pattern: '@Html.Raw(JsonConvert.SerializeObject(...))' + - pattern: '@Html.Raw(...ToJson(...))' severity: ERROR - - fix: | - USER non-root - ENTRYPOINT $...VARS - id: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint + - id: dockerfile.audit.dockerfile-source-not-pinned.dockerfile-source-not-pinned languages: - dockerfile - message: By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. + message: To ensure reproducible builds, pin Dockerfile `FROM` commands to a specific hash. You can find the hash by running `docker pull $IMAGE` and then specify it with `$IMAGE:$VERSION@sha256:` metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-269: Improper Privilege Management' - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2021 - Insecure Design + category: best-practice references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit + - https://stackoverflow.com/a/33511811/4965 technology: - - dockerfile + - docker patterns: - - pattern: | - ENTRYPOINT $...VARS - - pattern-not-inside: | - USER $USER - ... - severity: ERROR - - fix: | - USER non-root - CMD $...VARS - id: dockerfile.security.missing-user.missing-user + - pattern-either: + - patterns: + - pattern: FROM $IMAGE:$VERSION@$HASH + - metavariable-regex: + metavariable: $HASH + regex: (?!sha256:) + - patterns: + - pattern: FROM $IMAGE + - pattern: FROM $IMAGE:$VERSION + - pattern-not-inside: FROM $IMAGE:$VERSION@$HASH + severity: INFO + - id: dockerfile.best-practice.avoid-apk-upgrade.avoid-apk-upgrade languages: - dockerfile - message: By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. + message: Packages in base images should be up-to-date, removing the need for 'apk upgrade'. If packages are out-of-date, consider contacting the base image maintainer. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-269: Improper Privilege Management' - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2021 - Insecure Design + category: best-practice references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3017 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3017 technology: - dockerfile - patterns: - - pattern: | - CMD $...VARS - - pattern-not-inside: | - USER $USER - ... - severity: ERROR - - id: dockerfile.security.no-sudo-in-dockerfile.no-sudo-in-dockerfile + pattern: RUN ... apk upgrade ... + severity: INFO + - id: dockerfile.best-practice.avoid-apt-get-upgrade.avoid-apt-get-upgrade languages: - dockerfile - message: Avoid using sudo in Dockerfiles. Running processes as a non-root user can help reduce the potential impact of configuration errors and security vulnerabilities. + message: Packages in base containers should be up-to-date, removing the need to upgrade or dist-upgrade. If a package is out of date, contact the maintainers. metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration + category: best-practice references: - - https://cwe.mitre.org/data/definitions/250.html - - https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3005 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3005 technology: - dockerfile - patterns: - - pattern: | - RUN sudo ... + pattern-either: + - pattern: RUN ... apt-get upgrade ... + - pattern: RUN ... apt-get dist-upgrade ... severity: WARNING - - id: generic.secrets.security.detected-stripe-restricted-api-key.detected-stripe-restricted-api-key + - id: dockerfile.best-practice.avoid-dnf-update.avoid-dnf-update languages: - - regex - message: Stripe Restricted API Key detected + - dockerfile + message: Packages in base images should be up-to-date, removing the need for 'dnf update'. If packages are out-of-date, consider contacting the base image maintainer. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + category: best-practice references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3039 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3039 technology: - - secrets - - stripe - pattern-regex: rk_live_[0-9a-zA-Z]{24} - severity: ERROR - - id: generic.secrets.security.detected-username-and-password-in-uri.detected-username-and-password-in-uri + - dockerfile + pattern: dnf update + severity: INFO + - id: dockerfile.best-practice.avoid-latest-version.avoid-latest-version languages: - - generic - message: Username and password in URI detected + - dockerfile + message: Images should be tagged with an explicit version to produce deterministic container images. The 'latest' tag may change the base container without warning. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A07:2021 - Identification and Authentication Failures + category: best-practice references: - - https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go - subcategory: - - vuln + - https://github.com/hadolint/hadolint/wiki/DL3007 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3007 technology: - - secrets - patterns: - - pattern: $PROTOCOL://$...USERNAME:$...PASSWORD@$END - - metavariable-regex: - metavariable: $...USERNAME - regex: \A({?)([A-Za-z])([A-Za-z0-9_-]){5,31}(}?)\Z - - metavariable-regex: - metavariable: $...PASSWORD - regex: (?!.*[\s])(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]){6,32} - - metavariable-regex: - metavariable: $PROTOCOL - regex: (.*http.*)|(.*sql.*)|(.*ftp.*)|(.*smtp.*) - severity: ERROR - - id: generic.secrets.security.google-maps-apikeyleak.google-maps-apikeyleak + - dockerfile + pattern: FROM $FROM:latest + severity: WARNING + - fix: FROM $IMAGE + id: dockerfile.best-practice.avoid-platform-with-from.avoid-platform-with-from languages: - - generic - message: Detects potential Google Maps API keys in code + - dockerfile + message: Using '--platform' with FROM restricts the image to build on a single platform. Further, this must be the same as the build platform. If you intended to specify the target platform, use the utility 'docker buildx --platform=' instead. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-538: Insertion of Sensitive Information into Externally-Accessible File or Directory' - description: Detects potential Google Maps API keys in code - impact: HIGH - likelihood: MEDIUM - owasp: - - A3:2017 Sensitive Data Exposure + category: best-practice references: - - https://ozguralp.medium.com/unauthorized-google-maps-api-key-usage-cases-and-why-you-need-to-care-1ccb28bf21e - severity: MEDIUM - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3029 + - https://docs.docker.com/buildx/working-with-buildx/ + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3029 technology: - - Google Maps - patterns: - - pattern-regex: ^(AIza[0-9A-Za-z_-]{35}(?!\S))$ - severity: WARNING - - id: generic.visualforce.security.ncino.html.usesriforcdns.use-sri-for-cdns + - dockerfile + pattern: FROM --platform=$PLATFORM $IMAGE + severity: INFO + - id: dockerfile.best-practice.avoid-yum-update.avoid-yum-update languages: - - generic - message: 'Consuming CDNs without including a SubResource Integrity (SRI) can expose your application and its users to compromised code. SRIs allow you to consume specific versions of content where if even a single byte is compromised, the resource will not be loaded. Add an integrity attribute to your - - pattern-not: - severity: ERROR - - id: generic.visualforce.security.ncino.xml.cspheaderattribute.csp-header-attribute + - dockerfile + pattern: zypper update ... + severity: INFO + - fix: '# MAINTAINER $NAME' + id: dockerfile.best-practice.maintainer-is-deprecated.maintainer-is-deprecated languages: - - generic - message: Visualforce Pages must have the cspHeader attribute set to true. This attribute is available in API version 55 or higher. + - dockerfile + message: MAINTAINER has been deprecated. metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + category: best-practice references: - - https://help.salesforce.com/s/articleView?id=sf.csp_trusted_sites.htm&type=5 - subcategory: - - vuln + - https://github.com/hadolint/hadolint/wiki/DL4000 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4000 technology: - - salesforce - - visualforce - paths: - include: - - '*.page' + - dockerfile + pattern: MAINTAINER $NAME + severity: INFO + - fix: RUN apk $COMMAND --no-cache $SOMETHING + id: dockerfile.best-practice.missing-apk-no-cache.missing-apk-no-cache + languages: + - dockerfile + message: This apk command is missing '--no-cache'. This forces apk to use a package index instead of a local package cache, removing the need for '--update' and the deletion of '/var/cache/apk/*'. Add '--no-cache' to your apk command. + metadata: + category: best-practice + references: + - https://github.com/hadolint/hadolint/wiki/DL3019 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3019 + technology: + - dockerfile patterns: - - pattern: ... - - pattern-not: ... - - pattern-not: ...... - - pattern-not: ...... + - pattern: | + RUN apk $COMMAND ... + - pattern-not-inside: | + RUN apk ... --no-cache ... severity: INFO - - id: generic.visualforce.security.ncino.xml.visualforceapiversion.visualforce-page-api-version + - id: dockerfile.best-practice.missing-dnf-assume-yes-switch.missing-dnf-assume-yes-switch languages: - - generic - message: Visualforce Pages must use API version 55 or higher for required use of the cspHeader attribute set to true. + - dockerfile + message: This 'dnf install' is missing the '-y' switch. This might stall builds because it requires human intervention. Add the '-y' switch. metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + category: best-practice references: - - https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_pages.htm - subcategory: - - vuln + - https://github.com/hadolint/hadolint/wiki/DL3038 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3038 technology: - - salesforce - - visualforce - paths: - include: - - '*.page-meta.xml' + - dockerfile patterns: - - pattern-inside: - - pattern-either: - - pattern-regex: '[>][0-9].[0-9][<]' - - pattern-regex: '[>][1-4][0-9].[0-9][<]' - - pattern-regex: '[>][5][0-4].[0-9][<]' + - pattern: | + RUN ... dnf install ... + - pattern-not-inside: | + RUN ... dnf install ... -y ... + - pattern-not-inside: | + RUN ... dnf ... --assumeyes ... severity: WARNING - - id: go.aws-lambda.security.database-sqli.database-sqli + - id: dockerfile.best-practice.missing-dnf-clean-all.missing-dnf-clean-all languages: - - go - message: Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use prepared statements with the 'Prepare' and 'PrepareContext' calls. + - dockerfile + message: This dnf command does not end with '&& dnf clean all'. Running 'dnf clean all' will remove cached data and reduce package size. (This must be performed in the same RUN step.) metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection + category: best-practice references: - - https://pkg.go.dev/database/sql#DB.Query - subcategory: - - vuln + - https://github.com/hadolint/hadolint/wiki/DL3038 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3038 technology: - - aws-lambda - - database - - sql - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $DB.Exec($QUERY,...) - - pattern: $DB.ExecContent($QUERY,...) - - pattern: $DB.Query($QUERY,...) - - pattern: $DB.QueryContext($QUERY,...) - - pattern: $DB.QueryRow($QUERY,...) - - pattern: $DB.QueryRowContext($QUERY,...) - - pattern-inside: | - import "database/sql" - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...} - ... - lambda.Start($HANDLER, ...) - - patterns: - - pattern-inside: | - func $HANDLER($EVENT $TYPE) {...} - ... - lambda.Start($HANDLER, ...) - - pattern-not-inside: | - func $HANDLER($EVENT context.Context) {...} - ... - lambda.Start($HANDLER, ...) - - focus-metavariable: $EVENT + - dockerfile + patterns: + - pattern: RUN ... dnf ... + - pattern-not-inside: RUN ... && dnf clean all + - pattern-not-inside: RUN ... && \ dnf clean all severity: WARNING - - id: go.aws-lambda.security.tainted-sql-string.tainted-sql-string + - id: dockerfile.best-practice.missing-image-version.missing-image-version languages: - - go - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + - dockerfile + message: Detected docker image with no explicit version attached. Images should be tagged with an explicit version to produce deterministic container images -- attach a version when using `FROM `. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection + category: best-practice references: - - https://owasp.org/www-community/attacks/SQL_Injection - subcategory: - - vuln + - https://github.com/hadolint/hadolint/wiki/DL3006 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3006 technology: - - aws-lambda - mode: taint - pattern-sanitizers: - - pattern: strconv.Atoi(...) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: | - "$SQLSTR" + ... - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(\s*select|\s*delete|\s*insert|\s*create|\s*update|\s*alter|\s*drop).* - - patterns: - - pattern-either: - - pattern: fmt.Fprintf($F, "$SQLSTR", ...) - - pattern: fmt.Sprintf("$SQLSTR", ...) - - pattern: fmt.Printf("$SQLSTR", ...) - - metavariable-regex: - metavariable: $SQLSTR - regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).* - - pattern-not-inside: | - log.$PRINT(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...} - ... - lambda.Start($HANDLER, ...) - - patterns: - - pattern-inside: | - func $HANDLER($EVENT $TYPE) {...} - ... - lambda.Start($HANDLER, ...) - - pattern-not-inside: | - func $HANDLER($EVENT context.Context) {...} - ... - lambda.Start($HANDLER, ...) - - focus-metavariable: $EVENT - severity: ERROR - - id: go.gorilla.security.audit.handler-assignment-from-multiple-sources.handler-assignment-from-multiple-sources + - dockerfile + patterns: + - pattern-either: + - pattern: FROM $IMAGE + - pattern-not: FROM $IMAGE:$VERSION + - pattern-not: FROM $IMAGE@$DIGEST + - pattern-not: FROM $IMAGE:$VERSION@$DIGEST + - pattern-not: FROM scratch + severity: WARNING + - id: dockerfile.best-practice.missing-no-install-recommends.missing-no-install-recommends languages: - - go - message: 'Variable $VAR is assigned from two different sources: ''$Y'' and ''$R''. Make sure this is intended, as this could cause logic bugs if they are treated as they are the same object.' + - dockerfile + message: This 'apt-get install' is missing '--no-install-recommends'. This prevents unnecessary packages from being installed, thereby reducing image size. Add '--no-install-recommends'. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-289: Authentication Bypass by Alternate Name' - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW + category: best-practice references: - - https://cwe.mitre.org/data/definitions/289.html - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3015 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3015 technology: - - gorilla - mode: taint - pattern-sinks: - - patterns: - - pattern: | - $Y, err := store.Get(...) - ... - $VAR := $Y.Values[...] - ... - $VAR = $R - - focus-metavariable: $R + - dockerfile + patterns: + - pattern: | + RUN apt-get install ... + - pattern-not: RUN apt-get install ... --no-install-recommends ... + severity: INFO + - id: dockerfile.best-practice.missing-pip-no-cache-dir.missing-pip-no-cache-dir + languages: + - dockerfile + message: This '$PIP install' is missing '--no-cache-dir'. This flag prevents package archives from being kept around, thereby reducing image size. Add '--no-cache-dir'. + metadata: + category: best-practice + references: + - https://github.com/hadolint/hadolint/wiki/DL3042 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3042 + technology: + - dockerfile + patterns: - patterns: - pattern: | - $Y, err := store.Get(...) + RUN ... $PIP install ... + - pattern-not-inside: | + RUN ... $PIP install ... --no-cache-dir ... + - pattern-not-inside: | + RUN ... $PIP install . ... + - pattern-not-inside: | + ENV ... PIP_NO_CACHE_DIR=$BOOL ... ... - var $VAR $INT = $Y.Values["..."].($INT) + RUN ... $PIP install ... + - pattern-not-inside: | + ENV ... PIP_NO_CACHE_DIR ... ... - $VAR = $R - - focus-metavariable: $R - pattern-sources: - - patterns: - - pattern-inside: | - func $HANDLER(..., $R *http.Request, ...) { - ... - } - - focus-metavariable: $R - - pattern-either: - - pattern: $R.query - severity: WARNING - - fix-regex: - regex: (HttpOnly\s*:\s+)false - replacement: \1true - id: go.gorilla.security.audit.session-cookie-missing-httponly.session-cookie-missing-httponly + RUN ... $PIP install ... + - metavariable-regex: + metavariable: $PIP + regex: (pip|pip2|pip3|python -m pip|python3 -m pip) + severity: INFO + - id: dockerfile.best-practice.missing-yum-assume-yes-switch.missing-yum-assume-yes-switch languages: - - go - message: A session cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie which mitigates XSS attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' in the Options struct. + - dockerfile + message: This 'yum install' is missing the '-y' switch. This might stall builds because it requires human intervention. Add the '-y' switch. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration + category: best-practice references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3030 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3030 technology: - - gorilla + - dockerfile patterns: - - pattern-not-inside: | - &sessions.Options{ - ..., - HttpOnly: true, - ..., - } - pattern: | - &sessions.Options{ - ..., - } + RUN ... yum install ... + - pattern-not: | + RUN ... yum install ... -y ... + - pattern-not: | + RUN ... yum ... --assumeyes ... severity: WARNING - - fix-regex: - regex: (Secure\s*:\s+)false - replacement: \1true - id: go.gorilla.security.audit.session-cookie-missing-secure.session-cookie-missing-secure + - id: dockerfile.best-practice.missing-zypper-clean.missing-zypper-clean languages: - - go - message: A session cookie was detected without setting the 'Secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'Secure' flag by setting 'Secure' to 'true' in the Options struct. + - dockerfile + message: This zypper command does not end with '&& zypper clean'. Running 'zypper clean' will remove cached data and reduce package size. (This must be performed in the same RUN step.) metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration + category: best-practice references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3036 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3036 technology: - - gorilla + - dockerfile patterns: - - pattern-not-inside: | - &sessions.Options{ - ..., - Secure: true, - ..., - } - - pattern: | - &sessions.Options{ - ..., - } + - pattern: RUN ... zypper $COMMAND ... + - pattern-not-inside: RUN ... zypper clean + - pattern-not-inside: RUN ... zypper clean severity: WARNING - - fix-regex: - regex: (SameSite\s*:\s+)http.SameSiteNoneMode - replacement: \1http.SameSiteDefaultMode - id: go.gorilla.security.audit.session-cookie-samesitenone.session-cookie-samesitenone + - id: dockerfile.best-practice.nonsensical-command.nonsensical-command languages: - - go - message: Found SameSiteNoneMode setting in Gorilla session options. Consider setting SameSite to Lax, Strict or Default for enhanced security. + - dockerfile + message: Some commands such as `$CMD` do not make sense in a container. Do not use these. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration + category: best-practice references: - - https://pkg.go.dev/github.com/gorilla/sessions#Options - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3001 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3001 technology: - - gorilla + - dockerfile patterns: - - pattern-inside: | - &sessions.Options{ - ..., - SameSite: http.SameSiteNoneMode, - ..., - } - - pattern: | - &sessions.Options{ - ..., - } + - pattern: RUN $CMD ... + - metavariable-regex: + metavariable: $CMD + regex: (shutdown|service|ps|free|top|kill|mount|ifconfig|nano|vim) severity: WARNING - - id: go.gorilla.security.audit.websocket-missing-origin-check.websocket-missing-origin-check + - id: dockerfile.best-practice.prefer-apt-get.prefer-apt-get languages: - - go - message: 'The Origin header in the HTTP WebSocket handshake is used to guarantee that the connection accepted by the WebSocket is from a trusted origin domain. Failure to enforce can lead to Cross Site Request Forgery (CSRF). As per "gorilla/websocket" documentation: "A CheckOrigin function should carefully validate the request origin to prevent cross-site request forgery."' + - dockerfile + message: '''apt-get'' is preferred as an unattended tool for stability. ''apt'' is discouraged.' metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control + category: best-practice references: - - https://pkg.go.dev/github.com/gorilla/websocket#Upgrader - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3027 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3027 technology: - - gorilla + - dockerfile patterns: - - pattern-inside: | - import ("github.com/gorilla/websocket") - ... - - patterns: - - pattern-not-inside: | - $UPGRADER = websocket.Upgrader{..., CheckOrigin: $FN ,...} - ... - - pattern-not-inside: | - $UPGRADER.CheckOrigin = $FN2 - ... - - pattern: | - $UPGRADER.Upgrade(...) - severity: WARNING - - id: go.gorm.security.audit.gorm-dangerous-methods-usage.gorm-dangerous-method-usage + - pattern: RUN apt ... + - pattern-not: RUN apt-get ... + severity: INFO + - id: dockerfile.best-practice.prefer-copy-over-add.prefer-copy-over-add languages: - - go - message: Detected usage of dangerous method $METHOD which does not escape inputs (see link in references). If the argument is user-controlled, this can lead to SQL injection. When using $METHOD function, do not trust user-submitted data and only allow approved list of input (possibly, use an allowlist approach). + - dockerfile + message: The ADD command will accept and include files from a URL and automatically extract archives. This potentially exposes the container to a man-in-the-middle attack or other attacks if a malicious actor can tamper with the source archive. Since ADD can have this and other unexpected side effects, the use of the more explicit COPY command is preferred. metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection + category: best-practice references: - - https://gorm.io/docs/security.html#SQL-injection-Methods - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html - subcategory: - - vuln + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html technology: - - gorm - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern-either: - - pattern: strconv.Atoi(...) - - pattern: | - ($X: bool) - pattern-sinks: + - dockerfile + patterns: + - pattern: | + ADD $FROM $TO + - metavariable-regex: + metavariable: $FROM + regex: (^[A-Za-z]+:\/\/|.*[.](gz|bz2|zip|tar)$) + - focus-metavariable: $FROM + severity: INFO + - id: dockerfile.best-practice.prefer-json-notation.prefer-json-notation + languages: + - dockerfile + message: Prefer JSON notation when using CMD or ENTRYPOINT. This allows signals to be passed from the OS. + metadata: + category: best-practice + references: + - https://github.com/hadolint/hadolint/wiki/DL3025 + - https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#cmd + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3025 + technology: + - dockerfile + pattern-either: - patterns: - - pattern-inside: | - import ("gorm.io/gorm") - ... - - patterns: - - pattern-inside: | - func $VAL(..., $GORM *gorm.DB,... ) { - ... - } - - pattern-either: - - pattern: | - $GORM. ... .$METHOD($VALUE) - - pattern: | - $DB := $GORM. ... .$ANYTHING(...) - ... - $DB. ... .$METHOD($VALUE) - - focus-metavariable: $VALUE - - metavariable-regex: - metavariable: $METHOD - regex: ^(Order|Exec|Raw|Group|Having|Distinct|Select|Pluck)$ - pattern-sources: + - pattern: CMD $WORD ... + - pattern-not-inside: CMD [...] - patterns: - - pattern-either: - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - severity: WARNING - - fix-regex: - regex: (.*)WithInsecure\(.*?\) - replacement: \1WithTransportCredentials(credentials.NewTLS()) - id: go.grpc.security.grpc-client-insecure-connection.grpc-client-insecure-connection + - pattern: ENTRYPOINT $WORD ... + - pattern-not-inside: ENTRYPOINT [...] + severity: INFO + - id: dockerfile.best-practice.remove-package-cache.remove-package-cache languages: - - go - message: 'Found an insecure gRPC connection using ''grpc.WithInsecure()''. This creates a connection without encryption to a gRPC server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. Instead, establish a secure connection with an SSL certificate using the ''grpc.WithTransportCredentials()'' function. You can create a create credentials using a ''tls.Config{}'' struct with ''credentials.NewTLS()''. The final fix looks like this: ''grpc.WithTransportCredentials(credentials.NewTLS())''.' + - dockerfile + message: The package cache was not deleted after running 'apt-get update', which increases the size of the image. Remove the package cache by appending '&& apt-get clean' at the end of apt-get command chain. metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-300: Channel Accessible by Non-Endpoint' - impact: LOW - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + category: best-practice + license: Commons Clause License Condition v1.0[LGPL-2.1-only] references: - - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3009 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3009 technology: - - grpc - pattern: $GRPC.Dial($ADDR, ..., $GRPC.WithInsecure(...), ...) - severity: ERROR - - id: go.grpc.security.grpc-server-insecure-connection.grpc-server-insecure-connection + - dockerfile + patterns: + - pattern-not-inside: RUN ... && apt-get clean ... + - pattern: RUN ... apt-get update ... + - pattern: apt-get update + severity: WARNING + - id: dockerfile.best-practice.remove-package-lists.remove-package-lists languages: - - go - message: Found an insecure gRPC server without 'grpc.Creds()' or options with credentials. This allows for a connection without encryption to this server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. Include credentials derived from an SSL certificate in order to create a secure gRPC connection. You can create credentials using 'credentials.NewServerTLSFromFile("cert.pem", "cert.key")'. + - dockerfile + message: The package lists were not deleted after running 'apt-get update', which increases the size of the image. Remove the package lists by appending '&& rm -rf /var/lib/apt/lists/*' at the end of apt-get command chain. metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-300: Channel Accessible by Non-Endpoint' - impact: LOW - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + category: best-practice references: - - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3009 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3009 technology: - - grpc - mode: taint - pattern-sinks: - - pattern: grpc.NewServer($OPT, ...) - requires: OPTIONS and not CREDS - - pattern: grpc.NewServer() - requires: EMPTY_CONSTRUCTOR - pattern-sources: - - label: OPTIONS - pattern: grpc.ServerOption{ ... } - - label: CREDS - pattern: grpc.Creds(...) - - label: EMPTY_CONSTRUCTOR - pattern: grpc.NewServer() - severity: ERROR - - id: go.jwt-go.security.audit.jwt-parse-unverified.jwt-go-parse-unverified + - dockerfile + patterns: + - pattern-not-inside: RUN ... rm -rf /var/lib/apt/lists/* + - pattern: RUN apt-get update ... + - pattern: apt-get update + severity: WARNING + - id: dockerfile.best-practice.set-pipefail.set-pipefail languages: - - go - message: Detected the decoding of a JWT token without a verify step. Don't use `ParseUnverified` unless you know what you're doing This method parses the token but doesn't validate the signature. It's only ever useful in cases where you know the signature is valid (because it has been checked previously in the stack) and you want to extract values from it. + - dockerfile + message: Only the exit code from the final command in this RUN instruction will be evaluated unless 'pipefail' is set. If you want to fail the command at any stage in the pipe, set 'pipefail' by including 'SHELL ["/bin/bash", "-o", "pipefail", "-c"] before the command. If you're using alpine and don't have bash installed, communicate this explicitly with `SHELL ["/bin/ash"]`. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-345: Insufficient Verification of Data Authenticity' - impact: LOW - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures + category: best-practice references: - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL4006 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4006 technology: - - jwt + - dockerfile patterns: - - pattern-inside: | - import "github.com/dgrijalva/jwt-go" + - pattern-either: + - pattern: RUN ... | ... + - pattern: RUN ... || ... + - pattern-not-inside: | + SHELL [..., "pipefail", ...] + ... + RUN ... | ... + - pattern-not-inside: | + SHELL ["/bin/ash", ...] + ... + RUN ... | ... + severity: WARNING + - id: dockerfile.best-practice.use-either-wget-or-curl.use-either-wget-or-curl + languages: + - dockerfile + message: '''wget'' and ''curl'' are similar tools. Choose one and do not install the other to decrease image size.' + metadata: + category: best-practice + references: + - https://github.com/hadolint/hadolint/wiki/DL4001 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4001 + technology: + - dockerfile + pattern-either: + - pattern: | + RUN wget ... ... + RUN curl ... - pattern: | - $JWT.ParseUnverified(...) + RUN curl ... + ... + RUN wget ... + severity: INFO + - fix: SHELL ["$SHELL", "-c"] + id: dockerfile.best-practice.use-shell-instruction.use-shell-instruction + languages: + - dockerfile + message: Use the SHELL instruction to set the default shell instead of overwriting '/bin/sh'. + metadata: + category: best-practice + references: + - https://github.com/hadolint/hadolint/wiki/DL4005 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4005 + technology: + - dockerfile + pattern: | + RUN ln ... $SHELL /bin/sh severity: WARNING - - id: go.jwt-go.security.jwt-none-alg.jwt-go-none-algorithm + - id: dockerfile.best-practice.use-workdir.use-workdir languages: - - go - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + - dockerfile + message: As recommended by Docker's documentation, it is best to use 'WORKDIR' instead of 'RUN cd ...' for improved clarity and reliability. Also, 'RUN cd ...' may not work as expected in a container. metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + category: best-practice references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit + - https://github.com/hadolint/hadolint/wiki/DL3003 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3003 technology: - - jwt + - dockerfile + options: + implicit_deep_exprstmt: false patterns: - pattern-either: - pattern-inside: | - import "github.com/golang-jwt/jwt" - ... + RUN $ CMD ... - pattern-inside: | - import "github.com/dgrijalva/jwt-go" - ... - - pattern-either: - - pattern: | - jwt.SigningMethodNone - - pattern: jwt.UnsafeAllowNoneSignatureType - severity: ERROR - - id: go.jwt-go.security.jwt.hardcoded-jwt-key + RUN $CMD ... && ... + - metavariable-pattern: + metavariable: $CMD + pattern: cd + - focus-metavariable: $CMD + severity: WARNING + - id: dockerfile.correctness.invalid-port.invalid-port languages: - - go - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - dockerfile + message: Detected an invalid port number. Valid ports are 0 through 65535. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - likelihood: HIGH - owasp: - - A07:2021 - Identification and Authentication Failures + category: correctness references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - subcategory: - - vuln + - https://github.com/hadolint/hadolint/wiki/DL3011 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3011 technology: - - jwt - - secrets - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $TOKEN.SignedString($F) - - focus-metavariable: $F - pattern-sources: + - dockerfile + pattern-either: - patterns: - - pattern-inside: | - []byte("$F") + - pattern: EXPOSE $PORT + - metavariable-comparison: + comparison: int($PORT) > 65535 + metavariable: $PORT + severity: ERROR + - id: dockerfile.correctness.missing-assume-yes-switch.missing-assume-yes-switch + languages: + - dockerfile + message: This 'apt-get install' is missing the '-y' switch. This might stall builds because it requires human intervention. Add the '-y' switch. + metadata: + category: correctness + references: + - https://github.com/hadolint/hadolint/wiki/DL3014 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3014 + technology: + - dockerfile + patterns: + - pattern: "RUN ... apt-get install ... $MULTIFLAG ... \n" + - pattern-not: | + RUN ... apt-get install ... --assume-yes ... + - pattern-not: | + RUN ... apt-get install ... --yes ... + - pattern-not: | + RUN ... apt-get install ... -y ... + - metavariable-regex: + metavariable: $MULTIFLAG + regex: (^([^-])|(-[^y]+)$) severity: WARNING - - id: go.lang.security.audit.crypto.bad_imports.insecure-module-used + - id: dockerfile.correctness.multiple-entrypoint-instructions.multiple-entrypoint-instructions languages: - - go - message: The package `net/http/cgi` is on the import blocklist. The package is vulnerable to httpoxy attacks (CVE-2015-5386). It is recommended to use `net/http` or a web framework to build a web application instead. + - dockerfile + message: Multiple ENTRYPOINT instructions were found. Only the last one will take effect. + metadata: + category: correctness + references: + - https://github.com/hadolint/hadolint/wiki/DL4004 + - https://kapeli.com/cheat_sheets/Dockerfile.docset/Contents/Resources/Documents/index#//dash_ref_Instructions/Entry/ENTRYPOINT/0 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4004 + technology: + - dockerfile + patterns: + - pattern: | + ENTRYPOINT ... + ... + $ENTRYPOINT_INSTR + - metavariable-pattern: + metavariable: $ENTRYPOINT_INSTR + pattern: | + ENTRYPOINT ... + - focus-metavariable: $ENTRYPOINT_INSTR + severity: ERROR + - id: dockerfile.security.last-user-is-root.last-user-is-root + languages: + - dockerfile + message: The last user in the container is 'root'. This is a security hazard because if an attacker gains control of the container they will have root access. Switch back to another user after running commands as 'root'. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-269: Improper Privilege Management' impact: MEDIUM likelihood: MEDIUM owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A04:2021 - Insecure Design references: - - https://godoc.org/golang.org/x/crypto/sha3 - source-rule-url: https://github.com/securego/gosec + - https://github.com/hadolint/hadolint/wiki/DL3002 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3002 subcategory: - audit technology: - - go - pattern-either: - - patterns: - - pattern-inside: | - import "net/http/cgi" - ... - - pattern: | - cgi.$FUNC(...) - severity: WARNING - - id: go.lang.security.audit.crypto.insecure_ssh.avoid-ssh-insecure-ignore-host-key + - dockerfile + patterns: + - pattern: USER root + - pattern-not-inside: + patterns: + - pattern: | + USER root + ... + USER $X + - metavariable-pattern: + metavariable: $X + patterns: + - pattern-not: root + severity: ERROR + - fix: | + USER non-root + ENTRYPOINT $...VARS + id: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint languages: - - go - message: Disabled host key verification detected. This allows man-in-the-middle attacks. Use the 'golang.org/x/crypto/ssh/knownhosts' package to do host key verification. See https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ to learn more about the problem and how to fix it. + - dockerfile + message: By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-322: Key Exchange without Entity Authentication' - impact: LOW + - 'CWE-269: Improper Privilege Management' + impact: MEDIUM likelihood: LOW owasp: - - A02:2021 - Cryptographic Failures + - A04:2021 - Insecure Design references: - - https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ - - https://gist.github.com/Skarlso/34321a230cf0245018288686c9e70b2d - source-rule-url: https://github.com/securego/gosec + - https://owasp.org/Top10/A04_2021-Insecure_Design subcategory: - audit technology: - - go - pattern: ssh.InsecureIgnoreHostKey() - severity: WARNING + - dockerfile + patterns: + - pattern: | + ENTRYPOINT $...VARS + - pattern-not-inside: | + USER $USER + ... + severity: ERROR - fix: | - crypto/rand - id: go.lang.security.audit.crypto.math_random.math-random-used + USER non-root + CMD $...VARS + id: dockerfile.security.missing-user.missing-user languages: - - go - message: Do not use `math/rand`. Use `crypto/rand` instead. + - dockerfile + message: By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)' + - 'CWE-269: Improper Privilege Management' impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A02:2021 - Cryptographic Failures + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#secure-random-number-generation + - https://owasp.org/Top10/A04_2021-Insecure_Design subcategory: - - vuln + - audit technology: - - go + - dockerfile patterns: - - pattern-either: - - pattern: | - import $RAND "$MATH" - - pattern: | - import "$MATH" - - metavariable-regex: - metavariable: $MATH - regex: ^(math/rand(\/v[0-9]+)*)$ - - pattern-either: - - pattern-inside: | - ... - rand.$FUNC(...) - - pattern-inside: | - ... - $RAND.$FUNC(...) - - focus-metavariable: - - $MATH - severity: WARNING - - fix: | - tls.Config{ $...CONF, MinVersion: tls.VersionTLS13 } - id: go.lang.security.audit.crypto.missing-ssl-minversion.missing-ssl-minversion + - pattern: | + CMD $...VARS + - pattern-not-inside: | + USER $USER + ... + severity: ERROR + - id: dockerfile.security.no-sudo-in-dockerfile.no-sudo-in-dockerfile languages: - - go - message: '`MinVersion` is missing from this TLS configuration. By default, TLS 1.2 is currently used as the minimum when acting as a client, and TLS 1.0 when acting as a server. General purpose web applications should default to TLS 1.3 with all other protocols disabled. Only where it is known that a web server must support legacy clients with unsupported an insecure browsers (such as Internet Explorer 10), it may be necessary to enable TLS 1.0 to provide support. Add `MinVersion: tls.VersionTLS13'' to the TLS configuration to bump the minimum version to TLS 1.3.' + - dockerfile + message: Avoid using sudo in Dockerfiles. Running processes as a non-root user can help reduce the potential impact of configuration errors and security vulnerabilities. metadata: category: security confidence: HIGH cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-250: Execution with Unnecessary Privileges' impact: LOW - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A05:2021 - Security Misconfiguration references: - - https://golang.org/doc/go1.14#crypto/tls - - https://golang.org/pkg/crypto/tls/#:~:text=MinVersion - - https://www.us-cert.gov/ncas/alerts/TA14-290A - source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go + - https://cwe.mitre.org/data/definitions/250.html + - https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user subcategory: - - guardrail + - audit technology: - - go + - dockerfile patterns: - pattern: | - tls.Config{ $...CONF } - - pattern-not: | - tls.Config{..., MinVersion: ..., ...} + RUN sudo ... severity: WARNING - - fix-regex: - regex: VersionSSL30 - replacement: VersionTLS13 - id: go.lang.security.audit.crypto.ssl.ssl-v3-is-insecure + - id: dockerfile.security.secret-in-build-arg.secret-in-build-arg languages: - - go - message: SSLv3 is insecure because it has known vulnerabilities. Starting with go1.14, SSLv3 will be removed. Instead, use 'tls.VersionTLS13'. + - dockerfile + message: Docker build time arguments are not suited for secrets, because the argument values are saved with the image. Running `docker image history` on the image will show information on how the image was built, including arguments. If these contain plain text secrets, anyone with access to the docker image can access those secrets and exploit them. metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW - likelihood: MEDIUM + - 'CWE-538: Insertion of Sensitive Information into Externally-Accessible File or Directory' + impact: HIGH + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A01:2021 - Broken Access Control references: - - https://golang.org/doc/go1.14#crypto/tls - - https://www.us-cert.gov/ncas/alerts/TA14-290A - source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go + - https://cwe.mitre.org/data/definitions/538.html + - https://docs.docker.com/engine/reference/builder/#arg subcategory: - - vuln + - audit technology: - - go - pattern: 'tls.Config{..., MinVersion: $TLS.VersionSSL30, ...}' + - dockerfile + patterns: + - pattern-either: + - pattern: ARG $ARG + - pattern: ARG $ARG=... + - metavariable-regex: + metavariable: $ARG + regex: (?i).*(password|secret|token|key|cert|api|auth) severity: WARNING - - id: go.lang.security.audit.crypto.tls.tls-with-insecure-cipher + - fix: Bitwise.bnot($VAL) + id: elixir.lang.best-practice.deprecated-bnot-operator.deprecated_bnot_operator languages: - - go - message: Detected an insecure CipherSuite via the 'tls' module. This suite is considered weak. Use the function 'tls.CipherSuites()' to get a list of good cipher suites. See https://golang.org/pkg/crypto/tls/#InsecureCipherSuites for why and what other cipher suites to use. + - elixir + message: The bitwise operator (`^^^`) is already deprecated. Please use `Bitwise.bnot($VAL)` instead. metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + category: best-practice references: - - https://golang.org/pkg/crypto/tls/#InsecureCipherSuites - source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls.go - subcategory: - - vuln + - https://github.com/elixir-lang/elixir/commit/f1b9d3e818e5bebd44540f87be85979f24b9abfc technology: - - go + - elixir + pattern: ~~~$VAL + severity: WARNING + - fix: Bitwise.bxor($LEFT, $RIGHT) + id: elixir.lang.best-practice.deprecated-bxor-operator.deprecated_bxor_operator + languages: + - elixir + message: The bitwise operator (`^^^`) is already deprecated. Please use `Bitwise.bxor($LEFT, $RIGHT)` instead. + metadata: + category: best-practice + references: + - https://github.com/elixir-lang/elixir/commit/c9a171da5b25e0eb5d1da3b04c622f8b79a8aff4 + technology: + - elixir + pattern: $LEFT ^^^ $RIGHT + severity: WARNING + - fix: | + {$VAR, _, _} = Calendar.ISO.day_of_week($YEAR, $MONTH, $DAY, :default) + id: elixir.lang.best-practice.deprecated-calendar-iso-day-of-week-3.deprecated_calendar_iso_day_of_week_3 + languages: + - elixir + message: '`Calendar.ISO.day_of_week/3` is already deprecated. Please use `Calendar.ISO.day_of_week/4` instead.' + metadata: + category: best-practice + references: + - https://github.com/elixir-lang/elixir/releases/tag/v1.15.0 + technology: + - elixir + pattern: $VAR = Calendar.ISO.day_of_week($YEAR, $MONTH, $DAY) + severity: WARNING + - fix: import Bitwise + id: elixir.lang.best-practice.deprecated-use-bitwise.deprecated_use_bitwise + languages: + - elixir + message: The syntax `use Bitwise` is already deprecated. Please use `import Bitwise` instead. + metadata: + category: best-practice + references: + - https://github.com/elixir-lang/elixir/commit/f1b9d3e818e5bebd44540f87be85979f24b9abfc + technology: + - elixir + pattern: use Bitwise + severity: WARNING + - fix: | + $E + |> Enum.into($INTO, $FUN end) + id: elixir.lang.best-practice.enum-map-into.enum_map_into + languages: + - elixir + message: Using `Enum.into/3` is more efficient than using `Enum.map/2 |> Enum.into/2`. + metadata: + category: best-practice + references: + - https://github.com/rrrene/credo/blob/master/lib/credo/check/refactor/map_into.ex + technology: + - elixir pattern-either: - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_RC4_128_SHA, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_AES_128_CBC_SHA256, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ...}} - - pattern: | - tls.CipherSuite{..., TLS_RSA_WITH_RC4_128_SHA, ...} - - pattern: | - tls.CipherSuite{..., TLS_RSA_WITH_3DES_EDE_CBC_SHA, ...} - - pattern: | - tls.CipherSuite{..., TLS_RSA_WITH_AES_128_CBC_SHA256, ...} + Enum.into(Enum.map($E, $FUN), $INTO) - pattern: | - tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, ...} + Enum.map($E, $FUN) + |> Enum.into($INTO) - pattern: | - tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_RC4_128_SHA, ...} + $E + |> Enum.map($FUN) + |> Enum.into($INTO) + severity: WARNING + - fix: | + $E + |> Enum.map_join($JOINER, $FUN end) + id: elixir.lang.best-practice.enum-map-join.enum_map_join + languages: + - elixir + message: Using `Enum.map_join/3` is more efficient than using `Enum.map/2 |> Enum.join/2`. + metadata: + category: best-practice + references: + - https://github.com/rrrene/credo/blob/master/lib/credo/check/refactor/map_join.ex + technology: + - elixir + pattern-either: - pattern: | - tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, ...} + Enum.join(Enum.map($E, $FUN), $JOINER) - pattern: | - tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ...} + Enum.map($E, $FUN) + |> Enum.join($JOINER) - pattern: | - tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ...} + $E + |> Enum.map($FUN) + |> Enum.join($JOINER) severity: WARNING - - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-md5 + - fix: $MODULE.to_existing_atom($STRING) + id: elixir.lang.correctness.atom-exhaustion.atom_exhaustion languages: - - go - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - elixir + message: Atom values are appended to a global table but never removed. If input is user-controlled, dynamic instantiations such as `String.to_atom` or `List.to_atom` can lead to possible memory leaks. Instead, use `String.to_existing_atom` or `List.to_existing_atom`. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-328: Use of Weak Hash' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + category: correctness references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://github.com/securego/gosec#available-rules - subcategory: - - vuln + - https://erlef.github.io/security-wg/secure_coding_and_deployment_hardening/atom_exhaustion.html technology: - - go + - elixir patterns: - - pattern-inside: | - import "crypto/md5" - ... - - pattern-either: - - pattern: | - md5.New() - - pattern: | - md5.Sum(...) + - pattern: $MODULE.to_atom($STRING) + - metavariable-regex: + metavariable: $MODULE + regex: ^(String|List)$ + severity: ERROR + - id: generic.dockerfile.best-practice.missing-yum-clean-all.missing-yum-clean-all + languages: + - generic + message: This yum command does not end with '&& yum clean all'. Running 'yum clean all' will remove cached data and reduce package size. (This must be performed in the same RUN step.) + metadata: + category: best-practice + references: + - https://github.com/hadolint/hadolint/wiki/DL3032 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3032 + technology: + - dockerfile + paths: + include: + - '*dockerfile*' + - '*Dockerfile*' + patterns: + - pattern: yum $COMMAND + - pattern-not-inside: RUN ... && yum clean all + - pattern-not-inside: RUN ... && \ yum clean all severity: WARNING - - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-sha1 + - id: generic.dockerfile.best-practice.use-absolute-workdir.use-absolute-workdir languages: - - go - message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - generic + message: Detected a relative WORKDIR. Use absolute paths. This prevents issues based on assumptions about the WORKDIR of previous containers. metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-328: Use of Weak Hash' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + category: best-practice references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://github.com/securego/gosec#available-rules - subcategory: - - vuln + - https://github.com/hadolint/hadolint/wiki/DL3000 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3000 technology: - - go + - dockerfile + paths: + include: + - '*dockerfile*' + - '*Dockerfile*' + pattern-either: + - patterns: + - pattern: WORKDIR $VALUE + - metavariable-pattern: + metavariable: $VALUE + patterns: + - pattern-not-regex: (\/.*) + - patterns: + - pattern: ENV $VAR=$VALUE ... $CMD ${$VAR} + - metavariable-pattern: + metavariable: $VALUE + patterns: + - pattern-not-regex: (\/.*) + - metavariable-pattern: + metavariable: $CMD + pattern: WORKDIR + - focus-metavariable: $CMD + severity: WARNING + - id: generic.dockerfile.correctness.alias-must-be-unique.alias-must-be-unique + languages: + - generic + message: Image aliases must have a unique name, and '$REF' is used twice. Use another name for '$REF'. + metadata: + category: correctness + references: + - https://github.com/hadolint/hadolint/wiki/DL3024 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3024 + technology: + - dockerfile + paths: + include: + - '*dockerfile*' + - '*Dockerfile*' patterns: - - pattern-inside: | - import "crypto/sha1" + - pattern-either: + - pattern: | + FROM ... as $REF + ... + ... + FROM ... as $REF + - pattern: | + FROM ... AS $REF + ... + ... + FROM ... AS $REF + - pattern-not-inside: | + FROM ... as $REF + ... ... + FROM ... as $REF- + - pattern-not-inside: | + FROM ... AS $REF + ... + ... + FROM ... AS $REF- + severity: ERROR + - id: generic.dockerfile.correctness.copy-from-own-alias.copy-from-own-alias + languages: + - generic + message: COPY instructions cannot copy from its own alias. The '$REF' alias is used before switching to a new image. If you meant to switch to a new image, include a new 'FROM' statement. Otherwise, remove the '--from=$REF' from the COPY statement. + metadata: + category: correctness + references: + - https://github.com/hadolint/hadolint/wiki/DL3023 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3023 + technology: + - dockerfile + paths: + include: + - '*dockerfile*' + - '*Dockerfile*' + pattern-either: + - pattern: | + FROM $IMAGE:$TAG as $REF + ... + COPY --from=$REF + ... + FROM + - pattern: | + FROM $IMAGE:$TAG AS $REF + ... + COPY --from=$REF + ... + FROM + severity: ERROR + - id: generic.dockerfile.correctness.multiple-cmd-instructions.multiple-cmd-instructions + languages: + - dockerfile + message: Multiple CMD instructions were found. Only the last one will take effect. + metadata: + category: correctness + references: + - https://github.com/hadolint/hadolint/wiki/DL4003 + - https://kapeli.com/cheat_sheets/Dockerfile.docset/Contents/Resources/Documents/index#//dash_ref_Instructions/Entry/CMD/0 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4003 + technology: + - dockerfile + patterns: - pattern-either: - pattern: | - sha1.New() + CMD ... + ... + CMD ... - pattern: | - sha1.Sum(...) + CMD [...] + ... + CMD [...] + - pattern: | + CMD [...] + ... + CMD ... + - pattern: | + CMD ... + ... + CMD [...] + - pattern-not-inside: | + CMD ... + ... + FROM $IMAGE + ... + CMD ... + - pattern-not: | + HEALTHCHECK $CMD + ... + CMD ... + - pattern-not: | + HEALTHCHECK $CMD + ... + CMD [...] + - pattern-not: | + CMD ... + ... + HEALTHCHECK $CMD + - pattern-not: | + CMD [...] + ... + HEALTHCHECK $CMD + severity: ERROR + - id: generic.dockerfile.missing-zypper-no-confirm-switch.missing-zypper-no-confirm-switch + languages: + - dockerfile + message: This 'zypper install' is missing the '-y' switch. This might stall builds because it requires human intervention. Add the '-y' switch. + metadata: + category: best-practice + references: + - https://github.com/hadolint/hadolint/wiki/DL3034 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3034 + technology: + - dockerfile + paths: + include: + - '*dockerfile*' + - '*Dockerfile*' + patterns: + - pattern: | + RUN ... zypper install ... + - pattern-not: | + RUN ... zypper install ... -y ... + - pattern-not: | + RUN ... zypper install ... --no-confirm ... severity: WARNING - - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-des + - id: generic.secrets.gitleaks.adafruit-api-key.adafruit-api-key languages: - - go - message: Detected DES cipher algorithm which is insecure. The algorithm is considered weak and has been deprecated. Use AES instead. + - regex + message: A gitleaks adafruit-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://github.com/securego/gosec#available-rules + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go + - gitleaks patterns: - - pattern-inside: | - import "crypto/des" - ... - - pattern-either: - - pattern: | - des.NewTripleDESCipher(...) - - pattern: | - des.NewCipher(...) - severity: WARNING - - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-rc4 + - pattern-regex: (?i)(?:adafruit)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.adobe-client-id.adobe-client-id languages: - - go - message: Detected RC4 cipher algorithm which is insecure. The algorithm has many known vulnerabilities. Use AES instead. + - regex + message: A gitleaks adobe-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://github.com/securego/gosec#available-rules + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go + - gitleaks patterns: - - pattern-inside: | - import "crypto/rc4" - ... - - pattern: rc4.NewCipher(...) - severity: WARNING - - fix: | - 2048 - id: go.lang.security.audit.crypto.use_of_weak_rsa_key.use-of-weak-rsa-key + - pattern-regex: (?i)(?:adobe)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.adobe-client-secret.adobe-client-secret languages: - - go - message: RSA keys should be at least 2048 bits + - regex + message: A gitleaks adobe-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-326: Inadequate Encryption Strength' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms - source-rule-url: https://github.com/securego/gosec/blob/master/rules/rsa.go + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - go + - gitleaks patterns: - - pattern-either: - - pattern: | - rsa.GenerateKey(..., $BITS) - - pattern: | - rsa.GenerateMultiPrimeKey(..., $BITS) - - metavariable-comparison: - comparison: $BITS < 2048 - metavariable: $BITS - - focus-metavariable: - - $BITS - severity: WARNING - - id: go.lang.security.audit.dangerous-exec-cmd.dangerous-exec-cmd + - pattern-regex: (?i)\b((p8e-)(?i)[a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.age-secret-key.age-secret-key languages: - - go - message: Detected non-static command inside exec.Cmd. Audit the input to 'exec.Cmd'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + - regex + message: A gitleaks age-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - go + - gitleaks patterns: - - pattern-either: - - patterns: - - pattern: | - exec.Cmd {...,Path: $CMD,...} - - pattern-not: | - exec.Cmd {...,Path: "...",...} - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - - pattern-not-inside: | - $CMD = "..."; - ... - - patterns: - - pattern: | - exec.Cmd {...,Args: $ARGS,...} - - pattern-not: | - exec.Cmd {...,Args: []string{...},...} - - pattern-not-inside: | - $ARGS = []string{"...",...}; - ... - - pattern-not-inside: | - $CMD = "..."; - ... - $ARGS = []string{$CMD,...}; - ... - - pattern-not-inside: | - $CMD = exec.LookPath("..."); - ... - $ARGS = []string{$CMD,...}; - ... - - patterns: - - pattern: | - exec.Cmd {...,Args: []string{$CMD,...},...} - - pattern-not: | - exec.Cmd {...,Args: []string{"...",...},...} - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - - pattern-not-inside: | - $CMD = "..."; - ... - - patterns: - - pattern-either: - - pattern: | - exec.Cmd {...,Args: []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...} - - patterns: - - pattern: | - exec.Cmd {...,Args: []string{$CMD,"-c",$EXE,...},...} - - pattern-inside: | - $CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/"); - ... - - pattern-not: | - exec.Cmd {...,Args: []string{"...","...","...",...},...} - - pattern-not-inside: | - $EXE = "..."; - ... - - pattern-inside: | - import "os/exec" - ... - severity: ERROR - - id: go.lang.security.audit.md5-used-as-password.md5-used-as-password + - pattern-regex: AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58} + severity: INFO + - id: generic.secrets.gitleaks.airtable-api-key.airtable-api-key languages: - - go - message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as bcrypt. You can use the `golang.org/x/crypto/bcrypt` package. + - regex + message: A gitleaks airtable-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html - - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords - - https://github.com/returntocorp/semgrep-rules/issues/1609 - - https://pkg.go.dev/golang.org/x/crypto/bcrypt + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - md5 - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern: $FUNCTION(...) - - metavariable-regex: - metavariable: $FUNCTION - regex: (?i)(.*password.*) - pattern-sources: - - patterns: - - pattern-either: - - pattern: md5.New - - pattern: md5.Sum - severity: WARNING - - id: go.lang.security.audit.net.bind_all.avoid-bind-to-all-interfaces + - gitleaks + patterns: + - pattern-regex: (?i)(?:airtable)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{17})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.algolia-api-key.algolia-api-key languages: - - go - message: Detected a network listener listening on 0.0.0.0 or an empty string. This could unexpectedly expose the server publicly as it binds to all available interfaces. Instead, specify another IP address that is not 0.0.0.0 nor the empty string. + - regex + message: A gitleaks algolia-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://github.com/securego/gosec + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - go - pattern-either: - - pattern: tls.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) - - pattern: net.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) - - pattern: tls.Listen($NETWORK, "=~/^:.*$/", ...) - - pattern: net.Listen($NETWORK, "=~/^:.*$/", ...) - severity: WARNING - - fix-regex: - regex: (HttpOnly\s*:\s+)false - replacement: \1true - id: go.lang.security.audit.net.cookie-missing-httponly.cookie-missing-httponly + - gitleaks + patterns: + - pattern-regex: (?i)(?:algolia)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.alibaba-access-key-id.alibaba-access-key-id languages: - - go - message: A session cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie which mitigates XSS attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' in the Cookie. + - regex + message: A gitleaks alibaba-access-key-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: LOW owasp: - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go - - https://golang.org/src/net/http/cookie.go + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go + - gitleaks patterns: - - pattern-not-inside: | - http.Cookie{ - ..., - HttpOnly: true, - ..., - } - - pattern: | - http.Cookie{ - ..., - } - severity: WARNING - - fix-regex: - regex: (Secure\s*:\s+)false - replacement: \1true - id: go.lang.security.audit.net.cookie-missing-secure.cookie-missing-secure + - pattern-regex: (?i)\b((LTAI)(?i)[a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.alibaba-secret-key.alibaba-secret-key languages: - - go - message: A session cookie was detected without setting the 'Secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'Secure' flag by setting 'Secure' to 'true' in the Options struct. + - regex + message: A gitleaks alibaba-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: LOW owasp: - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go - - https://golang.org/src/net/http/cookie.go + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go + - gitleaks patterns: - - pattern-not-inside: | - http.Cookie{ - ..., - Secure: true, - ..., - } - - pattern: | - http.Cookie{ - ..., - } - severity: WARNING - - id: go.lang.security.audit.net.dynamic-httptrace-clienttrace.dynamic-httptrace-clienttrace + - pattern-regex: (?i)(?:alibaba)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.asana-client-id.asana-client-id languages: - - go - message: Detected a potentially dynamic ClientTrace. This occurred because semgrep could not find a static definition for '$TRACE'. Dynamic ClientTraces are dangerous because they deserialize function code to run when certain Request events occur, which could lead to code being run without your knowledge. Ensure that your ClientTrace is statically defined. + - regex + message: A gitleaks asana-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-913: Improper Control of Dynamically-Managed Code Resources' - impact: LOW + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/returntocorp/semgrep-rules/issues/518 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go + - gitleaks patterns: - - pattern-not-inside: | - package $PACKAGE - ... - &httptrace.ClientTrace { ... } - ... - - pattern: httptrace.WithClientTrace($ANY, $TRACE) - severity: WARNING - - id: go.lang.security.audit.net.formatted-template-string.formatted-template-string + - pattern-regex: (?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.asana-client-secret.asana-client-secret languages: - - go - message: Found a formatted template string passed to 'template.HTML()'. 'template.HTML()' does not escape contents. Be absolutely sure there is no user-controlled data in this template. If user data can reach this template, you may have a XSS vulnerability. + - regex + message: A gitleaks asana-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://golang.org/pkg/html/template/#HTML + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - go + - gitleaks patterns: - - pattern-not: template.HTML("..." + "...") - - pattern-either: - - pattern: template.HTML($T + $X, ...) - - pattern: template.HTML(fmt.$P("...", ...), ...) - - pattern: | - $T = "..." - ... - $T = $FXN(..., $T, ...) - ... - template.HTML($T, ...) - - pattern: | - $T = fmt.$P("...", ...) - ... - template.HTML($T, ...) - - pattern: | - $T, $ERR = fmt.$P("...", ...) - ... - template.HTML($T, ...) - - pattern: | - $T = $X + $Y - ... - template.HTML($T, ...) - - pattern: |- - $T = "..." - ... - $OTHER, $ERR = fmt.$P(..., $T, ...) - ... - template.HTML($OTHER, ...) - severity: WARNING - - id: go.lang.security.audit.net.fs-directory-listing.fs-directory-listing + - pattern-regex: (?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.atlassian-api-token.atlassian-api-token languages: - - go - message: 'Detected usage of ''http.FileServer'' as handler: this allows directory listing and an attacker could navigate through directories looking for sensitive files. Be sure to disable directory listing or restrict access to specific directories/files.' + - regex + message: A gitleaks atlassian-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-548: Exposure of Information Through Directory Listing' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A06:2017 - Security Misconfiguration - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/OWASP/Go-SCP - - https://cwe.mitre.org/data/definitions/548.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go + - gitleaks patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $FS := http.FileServer(...) - ... - - pattern-either: - - pattern: | - http.ListenAndServe(..., $FS) - - pattern: | - http.ListenAndServeTLS(..., $FS) - - pattern: | - http.Handle(..., $FS) - - pattern: | - http.HandleFunc(..., $FS) - - patterns: - - pattern: | - http.$FN(..., http.FileServer(...)) - - metavariable-regex: - metavariable: $FN - regex: (ListenAndServe|ListenAndServeTLS|Handle|HandleFunc) - severity: WARNING - - fix: http.ListenAndServeTLS($ADDR, certFile, keyFile, $HANDLER) - id: go.lang.security.audit.net.use-tls.use-tls + - pattern-regex: (?i)(?:atlassian|confluence|jira)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.authress-service-client-access-key.authress-service-client-access-key languages: - - go - message: Found an HTTP server without TLS. Use 'http.ListenAndServeTLS' instead. See https://golang.org/pkg/net/http/#ListenAndServeTLS for more information. + - regex + message: A gitleaks authress-service-client-access-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://golang.org/pkg/net/http/#ListenAndServeTLS + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - go - pattern: http.ListenAndServe($ADDR, $HANDLER) - severity: WARNING - - id: go.lang.security.audit.net.wip-xss-using-responsewriter-and-printf.wip-xss-using-responsewriter-and-printf + - gitleaks + patterns: + - pattern-regex: (?i)\b((?:sc|ext|scauth|authress)_[a-z0-9]{5,30}\.[a-z0-9]{4,6}\.acc[_-][a-z0-9-]{10,32}\.[a-z0-9+/_=-]{30,120})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.aws-access-token.aws-access-token languages: - - go - message: Found data going from url query parameters into formatted data written to ResponseWriter. This could be XSS and should not be done. If you must do this, ensure your data is sanitized or escaped. + - regex + message: A gitleaks aws-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go + - gitleaks patterns: - - pattern-inside: | - func $FUNC(..., $W http.ResponseWriter, ...) { - ... - var $TEMPLATE = "..." - ... - $W.Write([]byte(fmt.$PRINTF($TEMPLATE, ...)), ...) - ... - } - - pattern-either: - - pattern: | - $PARAMS = r.URL.Query() - ... - $DATA, $ERR := $PARAMS[...] - ... - $INTERM = $ANYTHING(..., $DATA, ...) - ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - - pattern: | - $PARAMS = r.URL.Query() - ... - $DATA, $ERR := $PARAMS[...] - ... - $INTERM = $DATA[...] - ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - - pattern: | - $DATA, $ERR := r.URL.Query()[...] - ... - $INTERM = $DATA[...] - ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - - pattern: | - $DATA, $ERR := r.URL.Query()[...] - ... - $INTERM = $ANYTHING(..., $DATA, ...) - ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - - pattern: | - $PARAMS = r.URL.Query() - ... - $DATA, $ERR := $PARAMS[...] - ... - $W.Write([]byte(fmt.$PRINTF(..., $DATA, ...))) - severity: WARNING - - fix: filepath.FromSlash(filepath.Clean("/"+strings.Trim($...INNER, "/"))) - id: go.lang.security.filepath-clean-misuse.filepath-clean-misuse + - pattern-regex: (?:A3T[A-Z0-9]|AKIA|ASIA|ABIA|ACCA)[A-Z0-9]{16} + severity: INFO + - id: generic.secrets.gitleaks.beamer-api-token.beamer-api-token languages: - - go - message: '`Clean` is not intended to sanitize against path traversal attacks. This function is for finding the shortest path name equivalent to the given input. Using `Clean` to sanitize file reads may expose this application to path traversal attacks, where an attacker could access arbitrary files on the server. To fix this easily, write this: `filepath.FromSlash(path.Clean("/"+strings.Trim(req.URL.Path, "/")))` However, a better solution is using the `SecureJoin` function in the package `filepath-securejoin`. See https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme.' + - regex + message: A gitleaks beamer-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: MEDIUM + likelihood: LOW owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://pkg.go.dev/path#Clean - - http://technosophos.com/2016/03/31/go-quickly-cleaning-filepaths.html - - https://labs.detectify.com/2021/12/15/zero-day-path-traversal-grafana/ - - https://dzx.cz/2021/04/02/go_path_traversal/ - - https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern-either: - - pattern: | - "/" + ... - pattern-sinks: - - patterns: - - pattern-either: - - pattern: filepath.Clean($...INNER) - - pattern: path.Clean($...INNER) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - severity: ERROR - - id: go.lang.security.injection.open-redirect.open-redirect + - gitleaks + patterns: + - pattern-regex: (?i)(?:beamer)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(b_[a-z0-9=_\-]{44})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.bitbucket-client-id.bitbucket-client-id languages: - - go - message: An HTTP redirect was found to be crafted from user-input `$REQUEST`. This can lead to open redirect vulnerabilities, potentially allowing attackers to redirect users to malicious web sites. It is recommend where possible to not allow user-input to craft the redirect URL. When user-input is necessary to craft the request, it is recommended to follow OWASP best practices to restrict the URL to domains in an allowlist. + - regex + message: A gitleaks bitbucket-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - description: An HTTP redirect was found to be crafted from user-input leading to an open redirect vulnerability + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: MEDIUM + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://knowledge-base.secureflag.com/vulnerabilities/unvalidated_redirects___forwards/open_redirect_go_lang.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern: http.Redirect($W, $REQ, $URL, ...) - - focus-metavariable: $URL - requires: INPUT and not CLEAN - pattern-sources: - - label: INPUT - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - - label: CLEAN - patterns: - - pattern-either: - - pattern: | - "$URLSTR" + $INPUT - - patterns: - - pattern-either: - - pattern: fmt.Fprintf($F, "$URLSTR", $INPUT, ...) - - pattern: fmt.Sprintf("$URLSTR", $INPUT, ...) - - pattern: fmt.Printf("$URLSTR", $INPUT, ...) - - metavariable-regex: - metavariable: $URLSTR - regex: .*//[a-zA-Z0-10]+\..* - requires: INPUT - severity: WARNING - - id: go.lang.security.injection.raw-html-format.raw-html-format + - gitleaks + patterns: + - pattern-regex: (?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.bitbucket-client-secret.bitbucket-client-secret languages: - - go - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. Use the `html/template` package which will safely render HTML instead, or inspect that the HTML is rendered safely. + - regex + message: A gitleaks bitbucket-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go - mode: taint - pattern-sanitizers: - - pattern: html.EscapeString(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: fmt.Printf("$HTMLSTR", ...) - - pattern: fmt.Sprintf("$HTMLSTR", ...) - - pattern: fmt.Fprintf($W, "$HTMLSTR", ...) - - pattern: '"$HTMLSTR" + ...' - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - severity: WARNING - - id: go.lang.security.injection.tainted-sql-string.tainted-sql-string + - gitleaks + patterns: + - pattern-regex: (?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.bittrex-access-key.bittrex-access-key languages: - - go - message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`db.Query("SELECT * FROM t WHERE id = ?", id)`) or a safe library. + - regex + message: A gitleaks bittrex-access-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://golang.org/doc/database/sql-injection - - https://www.stackhawk.com/blog/golang-sql-injection-guide-examples-and-prevention/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern-either: - - pattern: strconv.Atoi(...) - - pattern: | - ($X: bool) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - patterns: - - pattern-inside: | - $VAR = "$SQLSTR"; - ... - - pattern: $VAR += ... - - patterns: - - pattern-inside: | - var $SB strings.Builder - ... - - pattern-inside: | - $SB.WriteString("$SQLSTR") - ... - $SB.String(...) - - pattern: | - $SB.WriteString(...) - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop).* - - patterns: - - pattern-either: - - pattern: fmt.Fprintf($F, "$SQLSTR", ...) - - pattern: fmt.Sprintf("$SQLSTR", ...) - - pattern: fmt.Printf("$SQLSTR", ...) - - metavariable-regex: - metavariable: $SQLSTR - regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).* - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - severity: ERROR - - id: go.lang.security.injection.tainted-url-host.tainted-url-host + - gitleaks + patterns: + - pattern-regex: (?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.bittrex-secret-key.bittrex-secret-key languages: - - go - message: A request was found to be crafted from user-input `$REQUEST`. This can lead to Server-Side Request Forgery (SSRF) vulnerabilities, potentially exposing sensitive data. It is recommend where possible to not allow user-input to craft the base request, but to be treated as part of the path or query parameter. When user-input is necessary to craft the request, it is recommended to follow OWASP best practices to prevent abuse, including using an allowlist. + - regex + message: A gitleaks bittrex-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + likelihood: LOW owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) + - A07:2021 - Identification and Authentication Failures references: - - https://goteleport.com/blog/ssrf-attacks/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $CLIENT := &http.Client{...} - ... - - pattern: $CLIENT.$METHOD($URL, ...) - - pattern: http.$METHOD($URL, ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Get|Head|Post|PostForm)$ - - patterns: - - pattern: | - http.NewRequest("$METHOD", $URL, ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(GET|HEAD|POST|POSTFORM)$ - - focus-metavariable: $URL - requires: INPUT and not CLEAN - pattern-sources: - - label: INPUT - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - - label: CLEAN - patterns: - - pattern-either: - - pattern: | - "$URLSTR" + $INPUT - - patterns: - - pattern-either: - - pattern: fmt.Fprintf($F, "$URLSTR", $INPUT, ...) - - pattern: fmt.Sprintf("$URLSTR", $INPUT, ...) - - pattern: fmt.Printf("$URLSTR", $INPUT, ...) - - metavariable-regex: - metavariable: $URLSTR - regex: .*//[a-zA-Z0-10]+\..* - requires: INPUT - severity: WARNING - - id: go.template.security.ssti.go-ssti + - gitleaks + patterns: + - pattern-regex: (?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.clojars-api-token.clojars-api-token languages: - - go - message: A server-side template injection occurs when an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side. When using "html/template" always check that user inputs are validated and sanitized before included within the template. + - regex + message: A gitleaks clojars-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine' - impact: HIGH + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://www.onsecurity.io/blog/go-ssti-method-research/ - - http://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - go + - gitleaks patterns: - - pattern-inside: | - import ("html/template") - ... - - pattern: $TEMPLATE = fmt.Sprintf("...", $ARG, ...) - - patterns: - - pattern-either: - - pattern-inside: | - func $FN(..., $REQ *http.Request, ...){ - ... - } - - pattern-inside: | - func $FN(..., $REQ http.Request, ...){ - ... - } - - pattern-inside: | - func(..., $REQ *http.Request, ...){ - ... - } - - patterns: - - pattern-either: - - pattern-inside: | - $ARG := $REQ.URL.Query().Get(...) - ... - $T, $ERR := $TMPL.Parse($TEMPLATE) - - pattern-inside: | - $ARG := $REQ.Form.Get(...) - ... - $T, $ERR := $TMPL.Parse($TEMPLATE) - - pattern-inside: | - $ARG := $REQ.PostForm.Get(...) - ... - $T, $ERR := $TMPL.Parse($TEMPLATE) - severity: ERROR - - id: java.android.security.exported_activity.exported_activity + - pattern-regex: (?i)(CLOJARS_)[a-z0-9]{60} + severity: INFO + - id: generic.secrets.gitleaks.cloudflare-api-key.cloudflare-api-key languages: - - generic - message: The application exports an activity. Any application on the device can launch the exported activity which may compromise the integrity of your application or its data. Ensure that any exported activities do not have privileged access to your application's control plane. + - regex + message: A gitleaks cloudflare-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-926: Improper Export of Android Application Components' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A5:2021 Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://cwe.mitre.org/data/definitions/926.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - Android - paths: - exclude: - - sources/ - - classes3.dex - - '*.so' - include: - - '*AndroidManifest.xml' + - gitleaks patterns: - - pattern-not-inside: - - pattern-inside: " \n" - - pattern-either: - - pattern: | - - - pattern: | - ... /> - severity: WARNING - - id: java.aws-lambda.security.tainted-sql-string.tainted-sql-string + - pattern-regex: (?i)(?:cloudflare)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.cloudflare-global-api-key.cloudflare-global-api-key languages: - - java - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + - regex + message: A gitleaks cloudflare-global-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - interfile: true - likelihood: MEDIUM + impact: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/www-community/attacks/SQL_Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws-lambda - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR".concat(...) - - patterns: - - pattern-inside: | - StringBuilder $SB = new StringBuilder("$SQLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$SQLSTR"; - ... - - pattern: $VAR += ... - - pattern: String.format("$SQLSTR", ...) - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b - - pattern-not-inside: | - System.out.$PRINTLN(...) - pattern-sources: - - patterns: - - focus-metavariable: $EVENT - - pattern-either: - - pattern: | - $HANDLERTYPE $HANDLER($TYPE $EVENT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { - ... - } - - pattern: | - $HANDLERTYPE $HANDLER(InputStream $EVENT, OutputStream $OUT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { - ... - } - severity: ERROR - - id: java.aws-lambda.security.tainted-sqli.tainted-sqli + - gitleaks + patterns: + - pattern-regex: (?i)(?:cloudflare)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{37})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.cloudflare-origin-ca-key.cloudflare-origin-ca-key languages: - - java - message: Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use parameterized SQL queries or properly sanitize user input instead. + - regex + message: A gitleaks cloudflare-origin-ca-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - interfile: true - likelihood: MEDIUM + impact: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - sql - - java - - aws-lambda - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: "(java.sql.CallableStatement $STMT) = ...; \n" - - pattern: | - (java.sql.Statement $STMT) = ...; - - pattern: | - (java.sql.PreparedStatement $STMT) = ...; - - pattern: | - $VAR = $CONN.prepareStatement(...) - - pattern: | - $PATH.queryForObject(...); - - pattern: | - (java.util.Map $STMT) = $PATH.queryForMap(...); - - pattern: | - (org.springframework.jdbc.support.rowset.SqlRowSet $STMT) = ...; - - patterns: - - pattern-inside: | - (String $SQL) = "$SQLSTR" + ...; - ... - - pattern: $PATH.$SQLCMD(..., $SQL, ...); - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(^SELECT.* | ^INSERT.* | ^UPDATE.*) - - metavariable-regex: - metavariable: $SQLCMD - regex: (execute|query|executeUpdate|batchUpdate) - pattern-sources: - - patterns: - - focus-metavariable: $EVENT - - pattern-either: - - pattern: | - $HANDLERTYPE $HANDLER($TYPE $EVENT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { - ... - } - - pattern: | - $HANDLERTYPE $HANDLER(InputStream $EVENT, OutputStream $OUT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { - ... - } - severity: WARNING - - id: java.java-jwt.security.audit.jwt-decode-without-verify.java-jwt-decode-without-verify + - gitleaks + patterns: + - pattern-regex: \b(v1\.0-[a-f0-9]{24}-[a-f0-9]{146})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.codecov-access-token.codecov-access-token languages: - - java - message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token. + - regex + message: A gitleaks codecov-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-345: Insufficient Verification of Data Authenticity' - impact: HIGH + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: LOW owasp: - - A08:2021 - Software and Data Integrity Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - jwt + - gitleaks patterns: - - pattern: | - com.auth0.jwt.JWT.decode(...); - - pattern-not-inside: |- - class $CLASS { - ... - $RETURNTYPE $FUNC (...) { - ... - $VERIFIER.verify(...); - ... - } - } - severity: WARNING - - id: java.java-jwt.security.jwt-hardcode.java-jwt-hardcoded-secret + - pattern-regex: (?i)(?:codecov)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.coinbase-access-token.coinbase-access-token languages: - - java - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - regex + message: A gitleaks coinbase-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true @@ -3544,10809 +4767,5233 @@ rules: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - secrets - - jwt + - gitleaks patterns: - - pattern-either: - - pattern: | - (Algorithm $ALG) = $ALGO.$HMAC("$Y"); - - pattern: | - $SECRET = "$Y"; - ... - (Algorithm $ALG) = $ALGO.$HMAC($SECRET); - - pattern: | - class $CLASS { - ... - $TYPE $SECRET = "$Y"; - ... - $RETURNTYPE $FUNC (...) { - ... - (Algorithm $ALG) = $ALGO.$HMAC($SECRET); - ... - } - ... - } - - focus-metavariable: $Y - - metavariable-regex: - metavariable: $HMAC - regex: (HMAC384|HMAC256|HMAC512) - severity: WARNING - - id: java.java-jwt.security.jwt-none-alg.java-jwt-none-alg + - pattern-regex: (?i)(?:coinbase)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.confluent-access-token.confluent-access-token languages: - - java - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + - regex + message: A gitleaks confluent-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - jwt - pattern-either: - - pattern: | - $JWT.sign(com.auth0.jwt.algorithms.Algorithm.none()); - - pattern: | - $NONE = com.auth0.jwt.algorithms.Algorithm.none(); - ... - $JWT.sign($NONE); - - pattern: |- - class $CLASS { - ... - $TYPE $NONE = com.auth0.jwt.algorithms.Algorithm.none(); - ... - $RETURNTYPE $FUNC (...) { - ... - $JWT.sign($NONE); - ... - } - ... - } - severity: ERROR - - id: java.jax-rs.security.jax-rs-path-traversal.jax-rs-path-traversal + - gitleaks + patterns: + - pattern-regex: (?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.confluent-secret-key.confluent-secret-key languages: - - java - message: Detected a potential path traversal. A malicious actor could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. + - regex + message: A gitleaks confluent-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: LOW + impact: MEDIUM likelihood: LOW owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://www.owasp.org/index.php/Path_Traversal - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - jax-rs - pattern-either: - - pattern: | - $RETURNTYPE $FUNC (..., @PathParam(...) $TYPE $VAR, ...) { - ... - new File(..., $VAR, ...); - ... - } - - pattern: |- - $RETURNTYPE $FUNC (..., @javax.ws.rs.PathParam(...) $TYPE $VAR, ...) { - ... - new File(..., $VAR, ...); - ... - } - severity: WARNING - - id: java.jboss.security.session_sqli.find-sql-string-concatenation + - gitleaks + patterns: + - pattern-regex: (?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.contentful-delivery-api-token.contentful-delivery-api-token languages: - - java - message: In $METHOD, $X is used to construct a SQL query via string concatenation. + - regex + message: A gitleaks contentful-delivery-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - jboss - pattern-either: - - pattern: | - $RETURN $METHOD(...,String $X,...){ - ... - Session $SESSION = ...; - ... - String $QUERY = ... + $X + ...; - ... - PreparedStatement $PS = $SESSION.connection().prepareStatement($QUERY); - ... - ResultSet $RESULT = $PS.executeQuery(); - ... - } - - pattern: | - $RETURN $METHOD(...,String $X,...){ - ... - String $QUERY = ... + $X + ...; - ... - Session $SESSION = ...; - ... - PreparedStatement $PS = $SESSION.connection().prepareStatement($QUERY); - ... - ResultSet $RESULT = $PS.executeQuery(); - ... - } - severity: ERROR - - id: java.lang.security.audit.blowfish-insufficient-key-size.blowfish-insufficient-key-size + - gitleaks + patterns: + - pattern-regex: (?i)(?:contentful)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{43})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.databricks-api-token.databricks-api-token languages: - - java - message: Using less than 128 bits for Blowfish is considered insecure. Use 128 bits or more, or switch to use AES instead. + - regex + message: A gitleaks databricks-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-326: Inadequate Encryption Strength' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#BLOWFISH_KEY_SIZE + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - java + - gitleaks patterns: - - pattern: | - $KEYGEN = KeyGenerator.getInstance("Blowfish"); - ... - $KEYGEN.init($SIZE); - - metavariable-comparison: - comparison: $SIZE < 128 - metavariable: $SIZE - severity: WARNING - - fix: | - "AES/GCM/NoPadding" - id: java.lang.security.audit.cbc-padding-oracle.cbc-padding-oracle + - pattern-regex: (?i)\b(dapi[a-h0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.datadog-access-token.datadog-access-token languages: - - java - message: Using CBC with PKCS5Padding is susceptible to padding oracle attacks. A malicious actor could discern the difference between plaintext with valid or invalid padding. Further, CBC mode does not include any integrity checks. Use 'AES/GCM/NoPadding' instead. + - regex + message: A gitleaks datadog-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://capec.mitre.org/data/definitions/463.html - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#cipher-modes - - https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PADDING_ORACLE + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - java + - gitleaks patterns: - - pattern-inside: Cipher.getInstance("=~/.*\/CBC\/PKCS5Padding/") - - pattern: | - "=~/.*\/CBC\/PKCS5Padding/" - severity: WARNING - - id: java.lang.security.audit.crlf-injection-logs.crlf-injection-logs + - pattern-regex: (?i)(?:datadog)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.defined-networking-api-token.defined-networking-api-token languages: - - java - message: When data from an untrusted source is put into a logger and not neutralized correctly, an attacker could forge log entries or include malicious content. + - regex + message: A gitleaks defined-networking-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-93: Improper Neutralization of CRLF Sequences (''CRLF Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#CRLF_INJECTION_LOGS + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern-either: - - patterns: - - pattern-inside: | - class $CLASS { - ... - Logger $LOG = ...; - ... - } - - pattern-either: - - pattern-inside: | - $X $METHOD(...,HttpServletRequest $REQ,...) { - ... - } - - pattern-inside: | - $X $METHOD(...,ServletRequest $REQ,...) { - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - HttpServletRequest $REQ = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - ServletRequest $REQ = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - Logger $LOG = ...; - ... - HttpServletRequest $REQ = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - Logger $LOG = ...; - ... - ServletRequest $REQ = ...; - ... - } - - pattern-either: - - pattern: | - String $VAL = $REQ.getParameter(...); - ... - $LOG.$LEVEL(<... $VAL ...>); - - pattern: | - String $VAL = $REQ.getParameter(...); - ... - $LOG.log($LEVEL,<... $VAL ...>); - - pattern: | - $LOG.$LEVEL(<... $REQ.getParameter(...) ...>); - - pattern: | - $LOG.log($LEVEL,<... $REQ.getParameter(...) ...>); - severity: WARNING - - fix: | - "AES/GCM/NoPadding" - id: java.lang.security.audit.crypto.des-is-deprecated.des-is-deprecated + - pattern-regex: (?i)(?:dnkey)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(dnkey-[a-z0-9=_\-]{26}-[a-z0-9=_\-]{52})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.digitalocean-access-token.digitalocean-access-token languages: - - java - - kt - message: DES is considered deprecated. AES is the recommended cipher. Upgrade to use AES. See https://www.nist.gov/news-events/news/2005/06/nist-withdraws-outdated-data-encryption-standard for more information. + - regex + message: A gitleaks digitalocean-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::symmetric-algorithm::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://www.nist.gov/news-events/news/2005/06/nist-withdraws-outdated-data-encryption-standard - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#DES_USAGE + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern-either: - - pattern-inside: $CIPHER.getInstance("=~/DES/.*/") - - pattern-inside: $CIPHER.getInstance("DES") - - pattern-either: - - pattern: | - "=~/DES/.*/" - - pattern: | - "DES" - severity: WARNING - - id: java.lang.security.audit.crypto.desede-is-deprecated.desede-is-deprecated + - pattern-regex: (?i)\b(doo_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.digitalocean-pat.digitalocean-pat languages: - - java - - kt - message: Triple DES (3DES or DESede) is considered deprecated. AES is the recommended cipher. Upgrade to use AES. + - regex + message: A gitleaks digitalocean-pat was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::symmetric-algorithm::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#TDES_USAGE + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern-either: - - pattern: | - $CIPHER.getInstance("=~/DESede.*/") - - pattern: | - $CRYPTO.KeyGenerator.getInstance("DES") - severity: WARNING - - id: java.lang.security.audit.crypto.ecb-cipher.ecb-cipher + - pattern-regex: (?i)\b(dop_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.digitalocean-refresh-token.digitalocean-refresh-token languages: - - java - message: Cipher in ECB mode is detected. ECB mode produces the same output for the same input each time which allows an attacker to intercept and replay the data. Further, ECB mode does not provide any integrity checking. See https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY. + - regex + message: A gitleaks digitalocean-refresh-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::mode::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#ECB_MODE + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern: | - Cipher $VAR = $CIPHER.getInstance($MODE); - - metavariable-regex: - metavariable: $MODE - regex: .*ECB.* - severity: WARNING - - id: java.lang.security.audit.crypto.gcm-nonce-reuse.gcm-nonce-reuse + - pattern-regex: (?i)\b(dor_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.discord-api-token.discord-api-token languages: - - java - message: 'GCM IV/nonce is reused: encryption can be totally useless' + - regex + message: A gitleaks discord-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-323: Reusing a Nonce, Key Pair in Encryption' - functional-categories: - - crypto::search::randomness::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://www.youtube.com/watch?v=r1awgAl90wM + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern-either: - - pattern: new GCMParameterSpec(..., "...".getBytes(...), ...); - - pattern: byte[] $NONCE = "...".getBytes(...); ... new GCMParameterSpec(..., $NONCE, ...); - severity: ERROR - - id: java.lang.security.audit.crypto.no-null-cipher.no-null-cipher + - pattern-regex: (?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.discord-client-id.discord-client-id languages: - - java - message: 'NullCipher was detected. This will not encrypt anything; the cipher text will be the same as the plain text. Use a valid, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + - regex + message: A gitleaks discord-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#NULL_CIPHER + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern-either: - - pattern: new NullCipher(...); - - pattern: new javax.crypto.NullCipher(...); - severity: WARNING - - id: java.lang.security.audit.crypto.no-static-initialization-vector.no-static-initialization-vector + - pattern-regex: (?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{18})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.discord-client-secret.discord-client-secret languages: - - java - message: Initialization Vectors (IVs) for block ciphers should be randomly generated each time they are used. Using a static IV means the same plaintext encrypts to the same ciphertext every time, weakening the strength of the encryption. + - regex + message: A gitleaks discord-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-329: Generation of Predictable IV with CBC Mode' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://cwe.mitre.org/data/definitions/329.html - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#STATIC_IV + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - pattern-either: - - pattern: | - byte[] $IV = { - ... - }; - ... - new IvParameterSpec($IV, ...); - - pattern: | - class $CLASS { - byte[] $IV = { - ... - }; - ... - $METHOD(...) { - ... - new IvParameterSpec($IV, ...); - ... - } - } - severity: WARNING - - id: java.lang.security.audit.crypto.rsa-no-padding.rsa-no-padding + - gitleaks + patterns: + - pattern-regex: (?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.doppler-api-token.doppler-api-token languages: - - java - - kt - message: Using RSA without OAEP mode weakens the encryption. + - regex + message: A gitleaks doppler-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::mode::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://rdist.root.org/2009/10/06/why-rsa-encryption-padding-is-critical/ - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#RSA_NO_PADDING + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - kotlin - pattern: $CIPHER.getInstance("=~/RSA/[Nn][Oo][Nn][Ee]/NoPadding/") - severity: WARNING - - id: java.lang.security.audit.crypto.unencrypted-socket.unencrypted-socket + - gitleaks + patterns: + - pattern-regex: (dp\.pt\.)(?i)[a-z0-9]{43} + severity: INFO + - id: generic.secrets.gitleaks.droneci-access-token.droneci-access-token languages: - - java - message: Detected use of a Java socket that is not encrypted. As a result, the traffic could be read by an attacker intercepting the network traffic. Use an SSLSocket created by 'SSLSocketFactory' or 'SSLServerSocketFactory' instead. + - regex + message: A gitleaks droneci-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - functional-categories: - - net::search::crypto-config::java.net + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNENCRYPTED_SOCKET + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - pattern-either: - - pattern: new ServerSocket(...) - - pattern: new Socket(...) - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-aes-ecb.use-of-aes-ecb + - gitleaks + patterns: + - pattern-regex: (?i)(?:droneci)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.dropbox-api-token.dropbox-api-token languages: - - java - message: 'Use of AES with ECB mode detected. ECB doesn''t provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + - regex + message: A gitleaks dropbox-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::mode::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - pattern: $CIPHER.getInstance("=~/AES/ECB.*/") - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-blowfish.use-of-blowfish + - gitleaks + patterns: + - pattern-regex: (?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{15})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.dropbox-long-lived-api-token.dropbox-long-lived-api-token languages: - - java - message: 'Use of Blowfish was detected. Blowfish uses a 64-bit block size that makes it vulnerable to birthday attacks, and is therefore considered non-compliant. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + - regex + message: A gitleaks dropbox-long-lived-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - pattern: $CIPHER.getInstance("Blowfish") - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-default-aes.use-of-default-aes + - gitleaks + patterns: + - pattern-regex: (?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.dropbox-short-lived-api-token.dropbox-short-lived-api-token languages: - - java - message: 'Use of AES with no settings detected. By default, java.crypto.Cipher uses ECB mode. ECB doesn''t provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: java.crypto.Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + - regex + message: A gitleaks dropbox-short-lived-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::mode::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - import javax; - ... - - pattern-either: - - pattern: javax.crypto.Cipher.getInstance("AES") - - pattern: (javax.crypto.Cipher $CIPHER).getInstance("AES") - - patterns: - - pattern-either: - - pattern-inside: | - import javax.*; - ... - - pattern-inside: | - import javax.crypto; - ... - - pattern-either: - - pattern: crypto.Cipher.getInstance("AES") - - pattern: (crypto.Cipher $CIPHER).getInstance("AES") - - patterns: - - pattern-either: - - pattern-inside: | - import javax.crypto.*; - ... - - pattern-inside: | - import javax.crypto.Cipher; - ... - - pattern-either: - - pattern: Cipher.getInstance("AES") - - pattern: (Cipher $CIPHER).getInstance("AES") - severity: WARNING - - fix: | - getSha512Digest - id: java.lang.security.audit.crypto.use-of-md5-digest-utils.use-of-md5-digest-utils + - gitleaks + patterns: + - pattern-regex: (?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(sl\.[a-z0-9\-=_]{135})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.duffel-api-token.duffel-api-token languages: - - java - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use HMAC instead. + - regex + message: A gitleaks duffel-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-328: Use of Weak Hash' - functional-categories: - - crypto::search::hash-algorithm::org.apache.commons + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_MD5 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern: | - $DU.$GET_ALGO().digest(...) - - metavariable-pattern: - metavariable: $GET_ALGO - pattern: getMd5Digest - - metavariable-pattern: - metavariable: $DU - pattern: DigestUtils - - focus-metavariable: $GET_ALGO - severity: WARNING - - fix: | - "SHA-512" - id: java.lang.security.audit.crypto.use-of-md5.use-of-md5 + - pattern-regex: duffel_(test|live)_(?i)[a-z0-9_\-=]{43} + severity: INFO + - id: generic.secrets.gitleaks.dynatrace-api-token.dynatrace-api-token languages: - - java - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use HMAC instead. + - regex + message: A gitleaks dynatrace-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-328: Use of Weak Hash' - functional-categories: - - crypto::search::hash-algorithm::java.security + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_MD5 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern: | - java.security.MessageDigest.getInstance($ALGO, ...); - - metavariable-regex: - metavariable: $ALGO - regex: (.MD5.) - - focus-metavariable: $ALGO - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-rc2.use-of-rc2 + - pattern-regex: dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64} + severity: INFO + - id: generic.secrets.gitleaks.easypost-api-token.easypost-api-token languages: - - java - message: 'Use of RC2 was detected. RC2 is vulnerable to related-key attacks, and is therefore considered non-compliant. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + - regex + message: A gitleaks easypost-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - pattern: $CIPHER.getInstance("RC2") - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-rc4.use-of-rc4 + - gitleaks + patterns: + - pattern-regex: \bEZAK(?i)[a-z0-9]{54} + severity: INFO + - id: generic.secrets.gitleaks.easypost-test-api-token.easypost-test-api-token languages: - - java - message: 'Use of RC4 was detected. RC4 is vulnerable to several attacks, including stream cipher attacks and bit flipping attacks. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + - regex + message: A gitleaks easypost-test-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - pattern: $CIPHER.getInstance("RC4") - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-sha1.use-of-sha1 + - gitleaks + patterns: + - pattern-regex: \bEZTK(?i)[a-z0-9]{54} + severity: INFO + - id: generic.secrets.gitleaks.etsy-access-token.etsy-access-token languages: - - java - message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Instead, use PBKDF2 for password hashing or SHA256 or SHA512 for other hash function applications. + - regex + message: A gitleaks etsy-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-328: Use of Weak Hash' - functional-categories: - - crypto::search::hash-algorithm::javax.crypto + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_SHA1 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - pattern-either: - - patterns: - - pattern: | - java.security.MessageDigest.getInstance("$ALGO", ...); - - metavariable-regex: - metavariable: $ALGO - regex: (SHA1|SHA-1) - - pattern: | - $DU.getSha1Digest().digest(...) - severity: WARNING - - id: java.lang.security.audit.crypto.weak-rsa.use-of-weak-rsa-key + - gitleaks + patterns: + - pattern-regex: (?i)(?:etsy)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.facebook-access-token.facebook-access-token languages: - - java - message: RSA keys should be at least 2048 bits based on NIST recommendation. + - regex + message: A gitleaks facebook-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::key-length::java.security + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#RSA_KEY_SIZE + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern: | - KeyPairGenerator $KEY = $G.getInstance("RSA"); - ... - $KEY.initialize($BITS); - - metavariable-comparison: - comparison: $BITS < 2048 - metavariable: $BITS - severity: WARNING - - id: java.lang.security.audit.formatted-sql-string.formatted-sql-string + - pattern-regex: (?i)\b(\d{15,16}(\||%)[0-9a-z\-_]{27,40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.facebook-page-access-token.facebook-page-access-token languages: - - java - message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. + - regex + message: A gitleaks facebook-page-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.3.5 Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html - - https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html#create_ps - - https://software-security.sans.org/developer-how-to/fix-sql-injection-in-java-using-prepared-callable-statement - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SQL_INJECTION + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - mode: taint - options: - taint_assume_safe_booleans: true - taint_assume_safe_numbers: true - pattern-propagators: - - from: $X - pattern: (StringBuffer $S).append($X) - to: $S - - from: $X - pattern: (StringBuilder $S).append($X) - to: $S - pattern-sanitizers: - - patterns: - - pattern: (CriteriaBuilder $CB).$ANY(...) - pattern-sinks: - - patterns: - - pattern-not: $S.$SQLFUNC(<... "=~/.*TABLE *$/" ...>) - - pattern-not: $S.$SQLFUNC(<... "=~/.*TABLE %s$/" ...>) - - pattern-either: - - pattern: (Statement $S).$SQLFUNC(...) - - pattern: (PreparedStatement $P).$SQLFUNC(...) - - pattern: (Connection $C).createStatement(...).$SQLFUNC(...) - - pattern: (Connection $C).prepareStatement(...).$SQLFUNC(...) - - pattern: (EntityManager $EM).$SQLFUNC(...) - - metavariable-regex: - metavariable: $SQLFUNC - regex: execute|executeQuery|createQuery|query|addBatch|nativeSQL|create|prepare - requires: CONCAT - pattern-sources: - - label: INPUT - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - $ANNOT $FUNC (..., $INPUT, ...) { - ... - } - - pattern: (String $INPUT) - - focus-metavariable: $INPUT - - label: CONCAT - patterns: - - pattern-either: - - pattern: $X + $INPUT - - pattern: $X += $INPUT - - pattern: $STRB.append($INPUT) - - pattern: String.format(..., $INPUT, ...) - - pattern: String.join(..., $INPUT, ...) - - pattern: (String $STR).concat($INPUT) - - pattern: $INPUT.concat(...) - - pattern: new $STRB(..., $INPUT, ...) - requires: INPUT - severity: ERROR - - id: java.lang.security.audit.http-response-splitting.http-response-splitting + - gitleaks + patterns: + - pattern-regex: (?i)\b(EAA[MC][a-z0-9]{20,})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.facebook-secret.facebook-secret languages: - - java - message: Older Java application servers are vulnerable to HTTP response splitting, which may occur if an HTTP request can be injected with CRLF characters. This finding is reported for completeness; it is recommended to ensure your environment is not affected by testing this yourself. + - regex + message: A gitleaks facebook-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers (''HTTP Request/Response Splitting'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://www.owasp.org/index.php/HTTP_Response_Splitting - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#HTTP_RESPONSE_SPLITTING + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - pattern-either: - - pattern: | - $VAR = $REQ.getParameter(...); - ... - $COOKIE = new Cookie(..., $VAR, ...); - ... - $RESP.addCookie($COOKIE, ...); - - patterns: - - pattern-inside: | - $RETTYPE $FUNC(...,@PathVariable $TYPE $VAR, ...) { - ... - } - - pattern: | - $COOKIE = new Cookie(..., $VAR, ...); - ... - $RESP.addCookie($COOKIE, ...); + - gitleaks + patterns: + - pattern-regex: (?i)(?:facebook)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) severity: INFO - - id: java.lang.security.audit.insecure-smtp-connection.insecure-smtp-connection + - id: generic.secrets.gitleaks.facebook.facebook languages: - - java - message: Insecure SMTP connection detected. This connection will trust any SSL certificate. Enable certificate verification by setting 'email.setSSLCheckServerIdentity(true)'. + - regex + message: A gitleaks facebook was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-297: Improper Validation of Certificate with Host Mismatch' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#INSECURE_SMTP_SSL + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern-not-inside: | - $EMAIL.setSSLCheckServerIdentity(true); - ... - - pattern-inside: | - $EMAIL = new SimpleEmail(...); - ... - - pattern: $EMAIL.send(...); - severity: WARNING - - id: java.lang.security.audit.md5-used-as-password.md5-used-as-password + - pattern-regex: (?i)(?:facebook)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.fastly-api-token.fastly-api-token languages: - - java - message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as PBKDF2 or bcrypt. You can use `javax.crypto.SecretKeyFactory` with `SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")` or, if using Spring, `org.springframework.security.crypto.bcrypt`. + - regex + message: A gitleaks fastly-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html - - https://github.com/returntocorp/semgrep-rules/issues/1609 - - https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory - - https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - md5 - mode: taint - pattern-sinks: - - patterns: - - pattern: $MODEL.$METHOD(...); - - metavariable-regex: - metavariable: $METHOD - regex: (?i)(.*password.*) - pattern-sources: - - patterns: - - pattern-inside: | - $TYPE $MD = MessageDigest.getInstance("MD5"); - ... - - pattern: $MD.digest(...); - severity: WARNING - - id: java.lang.security.audit.sqli.tainted-sql-from-http-request.tainted-sql-from-http-request + - gitleaks + patterns: + - pattern-regex: (?i)(?:fastly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.finicity-api-token.finicity-api-token languages: - - java - message: Detected input from a HTTPServletRequest going into a SQL sink or statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use parameterized SQL queries or properly sanitize user input instead. + - regex + message: A gitleaks finicity-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html - - https://owasp.org/www-community/attacks/SQL_Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - sql - - java - - servlets - - spring - mode: taint - options: - taint_assume_safe_booleans: true - taint_assume_safe_numbers: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: "(java.sql.CallableStatement $STMT) = ...; \n" - - pattern: | - (java.sql.Statement $STMT) = ...; - ... - $OUTPUT = $STMT.$FUNC(...); - - pattern: | - (java.sql.PreparedStatement $STMT) = ...; - - pattern: | - $VAR = $CONN.prepareStatement(...) - - pattern: | - $PATH.queryForObject(...); - - pattern: | - (java.util.Map $STMT) = $PATH.queryForMap(...); - - pattern: | - (org.springframework.jdbc.support.rowset.SqlRowSet $STMT) = ...; - - pattern: | - (org.springframework.jdbc.core.JdbcTemplate $TEMPL).batchUpdate(...) - - patterns: - - pattern-inside: | - (String $SQL) = "$SQLSTR" + ...; - ... - - pattern: $PATH.$SQLCMD(..., $SQL, ...); - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(^SELECT.* | ^INSERT.* | ^UPDATE.*) - - metavariable-regex: - metavariable: $SQLCMD - regex: (execute|query|executeUpdate|batchUpdate) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ).$REQFUNC(...) - - pattern: "(ServletRequest $REQ).$REQFUNC(...) \n" - - metavariable-regex: - metavariable: $REQFUNC - regex: (getInputStream|getParameter|getParameterMap|getParameterValues|getReader|getCookies|getHeader|getHeaderNames|getHeaders|getPart|getParts|getQueryString) - severity: WARNING - - id: java.lang.security.audit.tainted-cmd-from-http-request.tainted-cmd-from-http-request + - gitleaks + patterns: + - pattern-regex: (?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.finicity-client-secret.finicity-client-secret languages: - - java - message: Detected input from a HTTPServletRequest going into a 'ProcessBuilder' or 'exec' command. This could lead to command injection if variables passed into the exec commands are not properly sanitized. Instead, avoid using these OS commands with user-supplied input, or, if you must use these commands, use a whitelist of specific values. + - regex + message: A gitleaks finicity-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (ProcessBuilder $PB) = ...; - - patterns: - - pattern: | - (Process $P) = ...; - - pattern-not: | - (Process $P) = (java.lang.Runtime $R).exec(...); - - patterns: - - pattern: (java.lang.Runtime $R).exec($CMD, ...); - - focus-metavariable: $CMD - - patterns: - - pattern-either: - - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(ProcessBuilder $PB) = ...;\n...\n$PB.command($ARGLIST);\n" - - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(ProcessBuilder $PB) = ...;\n" - - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(Process $P) = ...;\n" - - pattern: | - $ARGLIST.add(...); - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); - ... - for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { - ... - } - - pattern: | - $COOKIE.getValue(...) - severity: ERROR - - id: java.lang.security.audit.tainted-env-from-http-request.tainted-env-from-http-request + - gitleaks + patterns: + - pattern-regex: (?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.finnhub-access-token.finnhub-access-token languages: - - java - message: Detected input from a HTTPServletRequest going into the environment variables of an 'exec' command. Instead, call the command with user-supplied arguments by using the overloaded method with one String array as the argument. `exec({"command", "arg1", "arg2"})`. + - regex + message: A gitleaks finnhub-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-454: External Initialization of Trusted Variables or Data Stores' - cwe2021-top25: false - cwe2022-top25: false + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern: (java.lang.Runtime $R).exec($CMD, $ENV_ARGS, ...); - - focus-metavariable: $ENV_ARGS - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); - ... - for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { - ... - } - - pattern: | - $COOKIE.getValue(...) - severity: ERROR - - id: java.lang.security.audit.tainted-ldapi-from-http-request.tainted-ldapi-from-http-request + - gitleaks + patterns: + - pattern-regex: (?i)(?:finnhub)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.flickr-access-token.flickr-access-token languages: - - java - message: Detected input from a HTTPServletRequest going into an LDAP query. This could lead to LDAP injection if the input is not properly sanitized, which could result in attackers modifying objects in the LDAP tree structure. Ensure data passed to an LDAP query is not controllable or properly sanitize the data. + - regex + message: A gitleaks flickr-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://sensei.securecodewarrior.com/recipes/scw%3Ajava%3ALDAP-injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (javax.naming.directory.InitialDirContext $IDC).search(...) - - pattern: | - (javax.naming.directory.DirContext $CTX).search(...) - - pattern-not: | - (javax.naming.directory.InitialDirContext $IDC).search($Y, "...", ...) - - pattern-not: | - (javax.naming.directory.DirContext $CTX).search($Y, "...", ...) - pattern-sources: - - patterns: - - pattern: (HttpServletRequest $REQ) - severity: WARNING - - id: java.lang.security.audit.tainted-session-from-http-request.tainted-session-from-http-request + - gitleaks + patterns: + - pattern-regex: (?i)(?:flickr)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.flutterwave-encryption-key.flutterwave-encryption-key languages: - - java - message: Detected input from a HTTPServletRequest going into a session command, like `setAttribute`. User input into such a command could lead to an attacker inputting malicious code into your session parameters, blurring the line between what's trusted and untrusted, and therefore leading to a trust boundary violation. This could lead to programmers trusting unvalidated data. Instead, thoroughly sanitize user input before passing it into such function calls. + - regex + message: A gitleaks flutterwave-encryption-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-501: Trust Boundary Violation' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: MEDIUM + likelihood: LOW owasp: - - A04:2021 - Insecure Design + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A04_2021-Insecure_Design + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern: (HttpServletRequest $REQ).getSession().$FUNC($NAME, $VALUE); - - metavariable-regex: - metavariable: $FUNC - regex: ^(putValue|setAttribute)$ - - focus-metavariable: $VALUE - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern: | - (HttpServletRequest $REQ).$FUNC(...) - - pattern-not: | - (HttpServletRequest $REQ).getSession() - - patterns: - - pattern-inside: | - (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); - ... - for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { - ... - } - - pattern: | - $COOKIE.getValue(...) - - patterns: - - pattern-inside: | - $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(... ); - ... - - pattern: | - $PARAM = $VALS[$INDEX]; - - patterns: - - pattern-inside: | - $HEADERS = (HttpServletRequest $REQ).getHeaders(...); - ... - $PARAM = $HEADERS.$FUNC(...); - ... - - pattern: | - java.net.URLDecoder.decode($PARAM, ...) - severity: WARNING - - id: java.lang.security.audit.tainted-xpath-from-http-request.tainted-xpath-from-http-request + - gitleaks + patterns: + - pattern-regex: FLWSECK_TEST-(?i)[a-h0-9]{12} + severity: INFO + - id: generic.secrets.gitleaks.flutterwave-public-key.flutterwave-public-key languages: - - java - message: Detected input from a HTTPServletRequest going into a XPath evaluate or compile command. This could lead to xpath injection if variables passed into the evaluate or compile commands are not properly sanitized. Xpath injection could lead to unauthorized access to sensitive information in XML documents. Instead, thoroughly sanitize user input or use parameterized xpath queries if you can. + - regex + message: A gitleaks flutterwave-public-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-643: Improper Neutralization of Data within XPath Expressions (''XPath Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (javax.xml.xpath.XPath $XP).evaluate(...) - - pattern: | - (javax.xml.xpath.XPath $XP).compile(...).evaluate(...) - pattern-sources: - - patterns: - - pattern: | - (HttpServletRequest $REQ).$FUNC(...) - severity: WARNING - - id: java.lang.security.audit.unvalidated-redirect.unvalidated-redirect + - gitleaks + patterns: + - pattern-regex: FLWPUBK_TEST-(?i)[a-h0-9]{32}-X + severity: INFO + - id: generic.secrets.gitleaks.flutterwave-secret-key.flutterwave-secret-key languages: - - java - message: Application redirects to a destination URL specified by a user-supplied parameter that is not validated. This could direct users to malicious locations. Consider using an allowlist to validate URLs. + - regex + message: A gitleaks flutterwave-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.1.5 Open Redirect - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: LOW - likelihood: MEDIUM + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNVALIDATED_REDIRECT + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - pattern-either: - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...,String $URL,...) { - ... - $RES.sendRedirect($URL); - ... - } - - pattern: | - $X $METHOD(...,String $URL,...,HttpServletResponse $RES,...) { - ... - $RES.sendRedirect($URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { - ... - String $URL = $REQ.getParameter(...); - ... - $RES.sendRedirect($URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { - ... - String $URL = $REQ.getParameter(...); - ... - $RES.sendRedirect($URL); - ... - } - - pattern: | - $X $METHOD(...,String $URL,...) { - ... - HttpServletResponse $RES = ...; - ... - $RES.sendRedirect($URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { - ... - $RES.sendRedirect($REQ.getParameter(...)); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { - ... - $RES.sendRedirect($REQ.getParameter(...)); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...,String $URL,...) { - ... - $RES.addHeader("Location",$URL); - ... - } - - pattern: | - $X $METHOD(...,String $URL,...,HttpServletResponse $RES,...) { - ... - $RES.addHeader("Location",$URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { - ... - String $URL = $REQ.getParameter(...); - ... - $RES.addHeader("Location",$URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { - ... - String $URL = $REQ.getParameter(...); - ... - $RES.addHeader("Location",$URL); - ... - } - - pattern: | - $X $METHOD(...,String $URL,...) { - ... - HttpServletResponse $RES = ...; - ... - $RES.addHeader("Location",$URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { - ... - $RES.addHeader("Location",$REQ.getParameter(...)); - ... - } - - pattern: |- - $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { - ... - $RES.addHeader("Location",$REQ.getParameter(...)); - ... - } - severity: WARNING - - fix-regex: - regex: (.*?)\.getInstance\(.*?\) - replacement: \1.getInstance("TLSv1.2") - id: java.lang.security.audit.weak-ssl-context.weak-ssl-context + - gitleaks + patterns: + - pattern-regex: FLWSECK_TEST-(?i)[a-h0-9]{32}-X + severity: INFO + - id: generic.secrets.gitleaks.frameio-api-token.frameio-api-token languages: - - java - message: An insecure SSL context was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use SSLContext.getInstance("TLSv1.2") for the best security. + - regex + message: A gitleaks frameio-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-326: Inadequate Encryption Strength' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://tools.ietf.org/html/rfc7568 - - https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html - source_rule_url: https://find-sec-bugs.github.io/bugs.htm#SSL_CONTEXT + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - java + - gitleaks patterns: - - pattern-not: SSLContext.getInstance("TLSv1.3") - - pattern-not: SSLContext.getInstance("TLSv1.2") - - pattern: SSLContext.getInstance("...") - severity: WARNING - - id: java.lang.security.audit.xss.no-direct-response-writer.no-direct-response-writer + - pattern-regex: fio-u-(?i)[a-z0-9\-_=]{64} + severity: INFO + - id: generic.secrets.gitleaks.gcp-api-key.gcp-api-key languages: - - java - message: Detected a request with potential user-input going into a OutputStream or Writer object. This bypasses any view or template environments, including HTML escaping, which may expose this application to cross-site scripting (XSS) vulnerabilities. Consider using a view technology such as JavaServer Faces (JSFs) which automatically escapes HTML views. + - regex + message: A gitleaks gcp-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - license: proprietary license - copyright © Semgrep, Inc. - likelihood: HIGH + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaServerFaces.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - servlets - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern-either: - - pattern: Encode.forHtml(...) - - pattern: (PolicyFactory $POLICY).sanitize(...) - - pattern: (AntiSamy $AS).scan(...) - - pattern: JSoup.clean(...) - - pattern: org.apache.commons.lang.StringEscapeUtils.escapeHtml(...) - - pattern: org.springframework.web.util.HtmlUtils.htmlEscape(...) - - pattern: org.owasp.esapi.ESAPI.encoder().encodeForHTML(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (HttpServletResponse $RESPONSE).getWriter(...).$WRITE(...) - - pattern: | - (HttpServletResponse $RESPONSE).getOutputStream(...).$WRITE(...) - - pattern: | - (java.io.PrintWriter $WRITER).$WRITE(...) - - pattern: | - (PrintWriter $WRITER).$WRITE(...) - - pattern: | - (javax.servlet.ServletOutputStream $WRITER).$WRITE(...) - - pattern: | - (ServletOutputStream $WRITER).$WRITE(...) - - pattern: | - (java.io.OutputStream $WRITER).$WRITE(...) - - pattern: | - (OutputStream $WRITER).$WRITE(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ).$REQFUNC(...) - - pattern: "(ServletRequest $REQ).$REQFUNC(...) \n" - - metavariable-regex: - metavariable: $REQFUNC - regex: (getInputStream|getParameter|getParameterMap|getParameterValues|getReader|getCookies|getHeader|getHeaderNames|getHeaders|getPart|getParts|getQueryString) - severity: WARNING - - id: java.lang.security.audit.xxe.documentbuilderfactory-disallow-doctype-decl-false.documentbuilderfactory-disallow-doctype-decl-false + - gitleaks + patterns: + - pattern-regex: (?i)\b(AIza[0-9A-Za-z\\-_]{35})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.generic-api-key.generic-api-key languages: - - java - message: DOCTYPE declarations are enabled for $DBFACTORY. Without prohibiting external entity declarations, this is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false. + - regex + message: A gitleaks generic-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). This rule can introduce a lot of false positives, it is not recommended to be used in PR comments. metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - xml + - gitleaks + paths: + exclude: + - '*.svg' + - '*go.sum' + - '*cargo.lock' + - '*package.json' + - '*package-lock.json' + - '*bundle.js' + - '*pnpm-lock*' + - '*Podfile.lock' + - '*/openssl/*.h' + - '*.xcscmblueprint' patterns: - - pattern: $DBFACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false); - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - } - severity: ERROR - - fix: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - $FACTORY.newDocumentBuilder(); - id: java.lang.security.audit.xxe.documentbuilderfactory-disallow-doctype-decl-missing.documentbuilderfactory-disallow-doctype-decl-missing + - pattern-regex: (?i)(?:key|api|token|secret|client|passwd|password|auth|access)(?:[0-9a-z\-_\t.]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|@\"|\"|\s|=|\x60){0,5}(?!([a-z]+\.[a-zA-Z]+)|.*(\d{4}-\d{2}-\d{2}|[a-z]+-[a-z]+.*)|:*(?!("|'))[0-9A-Za-z]+\.[0-9A-Za-z]+,|[A-Z]+_[A-Z]+_)(?P[0-9a-z\-_.=\~]{10,150})(?:['|\"|\n|\r|\s|\x60|;]|$) + - metavariable-analysis: + analyzer: entropy + metavariable: $CONTENT + - focus-metavariable: $CONTENT + - pattern-not-regex: .*((?i)omitted|arn:aws|(?i)(pub.*key|public.*key)|(?i)clientToken|symbol|cache|author\.).* + - pattern-not-regex: (\d\.\d\.\d-}|([\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})|(\w)\1{5}|(?i)keywords|xxxx|eeeeeeee|0000|\*\*\*|example|test|author=|author("|')|preview|[A-Z]+_KEY|[.]value|[.]key|-\d\.\d\.) + - metavariable-regex: + metavariable: $CONTENT + regex: (?!(^0x0*|^pub)|.*\.(bin|json|exe)$|.*(?i)(Client|Factory)$|(^__[A-Za-z]+__$)|^(12345|abcd)|^\d+(\.\d+)?$) + - pattern-not-regex: (\w|\.)\1{5} + - metavariable-regex: + metavariable: $CONTENT + regex: (?!(?i).*(client|endpoint|vpn|_ec2_|aws_|authorize|author|define|config|credential|setting|sample|xxxxxx|000000|buffer|delete|aaaaaa|fewfwef|getenv|env_|system|example|ecdsa|sha256|sha1|sha2|md5|alert|wizard|target|onboard|welcome|page|exploit|experiment|expire|rabbitmq|scraper|widget|music|dns_|dns-|yahoo|want|json|action|script|fix_|fix-|develop|compas|stripe|service|master|metric|tech|gitignore|rich|open|stack|irc_|irc-|sublime|kohana|has_|has-|fabric|wordpres|role|osx_|osx-|boost|addres|queue|working|sandbox|internet|print|vision|tracking|being|generator|traffic|world|pull|rust|watcher|small|auth|full|hash|more|install|auto|complete|learn|paper|installer|research|acces|last|binding|spine|into|chat|algorithm|resource|uploader|video|maker|next|proc|lock|robot|snake|patch|matrix|drill|terminal|term|stuff|genetic|generic|identity|audit|pattern|audio|web_|web-|crud|problem|statu|cms-|cms_|arch|coffee|workflow|changelog|another|uiview|content|kitchen|gnu_|gnu-|gnu\.|conf|couchdb|client|opencv|rendering|update|concept|varnish|gui_|gui-|gui\.|version|shared|extra|product|still|not_|not-|not\.|drop|ring|png_|png-|png\.|actively|import|output|backup|start|embedded|registry|pool|semantic|instagram|bash|system|ninja|drupal|jquery|polyfill|physic|league|guide|pack|synopsi|sketch|injection|svg_|svg-|svg\.|friendly|wave|convert|manage|camera|link|slide|timer|wrapper|gallery|url_|url-|url\.|todomvc|requirej|party|http|payment|async|library|home|coco|gaia|display|universal|func|metadata|hipchat|under|room|config|personal|realtime|resume|database|testing|tiny|basic|forum|meetup|yet_|yet-|yet\.|cento|dead|fluentd|editor|utilitie|run_|run-|run\.|box_|box-|box\.|bot_|bot-|bot\.|making|sample|group|monitor|ajax|parallel|cassandra|ultimate|site|get_|get-|get\.|gen_|gen-|gen\.|gem_|gem-|gem\.|extended|image|knife|asset|nested|zero|plugin|bracket|mule|mozilla|number|act_|act-|act\.|map_|map-|map\.|micro|debug|openshift|chart|expres|backend|task|source|translate|jbos|composer|sqlite|profile|mustache|mqtt|yeoman|have|builder|smart|like|oauth|school|guideline|captcha|filter|bitcoin|bridge|color|toolbox|discovery|new_|new-|new\.|dashboard|when|setting|level|post|standard|port|platform|yui_|yui-|yui\.|grunt|animation|haskell|icon|latex|cheat|lua_|lua-|lua\.|gulp|case|author|without|simulator|wifi|directory|lisp|list|flat|adventure|story|storm|gpu_|gpu-|gpu\.|store|caching|attention|solr|logger|demo|shortener|hadoop|finder|phone|pipeline|range|textmate|showcase|app_|app-|app\.|idiomatic|edit|our_|our-|our\.|out_|out-|out\.|sentiment|linked|why_|why-|why\.|local|cube|gmail|job_|job-|job\.|rpc_|rpc-|rpc\.|contest|tcp_|tcp-|tcp\.|usage|buildout|weather|transfer|automated|sphinx|issue|sas_|sas-|sas\.|parallax|jasmine|addon|machine|solution|dsl_|dsl-|dsl\.|episode|menu|theme|best|adapter|debugger|chrome|tutorial|life|step|people|joomla|paypal|developer|solver|team|current|love|visual|date|data|canva|container|future|xml_|xml-|xml\.|twig|nagio|spatial|original|sync|archived|refinery|science|mapping|gitlab|play|ext_|ext-|ext\.|session|impact|set_|set-|set\.|see_|see-|see\.|migration|commit|community|shopify|what'|cucumber|statamic|mysql|location|tower|line|code|amqp|hello|send|index|high|notebook|alloy|python|field|document|soap|edition|email|php_|php-|php\.|command|transport|official|upload|study|secure|angularj|akka|scalable|package|request|con_|con-|con\.|flexible|security|comment|module|flask|graph|flash|apache|change|window|space|lambda|sheet|bookmark|carousel|friend|objective|jekyll|bootstrap|first|article|gwt_|gwt-|gwt\.|classic|media|websocket|touch|desktop|real|read|recorder|moved|storage|validator|add-on|pusher|scs_|scs-|scs\.|inline|asp_|asp-|asp\.|timeline|base|encoding|ffmpeg|kindle|tinymce|pretty|jpa_|jpa-|jpa\.|used|user|required|webhook|download|resque|espresso|cloud|mongo|benchmark|pure|cakephp|modx|mode|reactive|fuel|written|flickr|mail|brunch|meteor|dynamic|neo_|neo-|neo\.|new_|new-|new\.|net_|net-|net\.|typo|type|keyboard|erlang|adobe|logging|ckeditor|message|iso_|iso-|iso\.|hook|ldap|folder|reference|railscast|www_|www-|www\.|tracker|azure|fork|form|digital|exporter|skin|string|template|designer|gollum|fluent|entity|language|alfred|summary|wiki|kernel|calendar|plupload|symfony|foundry|remote|talk|search|dev_|dev-|dev\.|del_|del-|del\.|token|idea|sencha|selector|interface|create|fun_|fun-|fun\.|groovy|query|grail|red_|red-|red\.|laravel|monkey|slack|supported|instant|value|center|latest|work|but_|but-|but\.|bug_|bug-|bug\.|virtual|tweet|statsd|studio|path|real-time|frontend|notifier|coding|tool|firmware|flow|random|mediawiki|bosh|been|beer|lightbox|theory|origin|redmine|hub_|hub-|hub\.|require|pro_|pro-|pro\.|ant_|ant-|ant\.|any_|any-|any\.|recipe|closure|mapper|event|todo|model|redi|provider|rvm_|rvm-|rvm\.|program|memcached|rail|silex|foreman|activity|license|strategy|batch|streaming|fast|use_|use-|use\.|usb_|usb-|usb\.|impres|academy|slider|please|layer|cros|now_|now-|now\.|miner|extension|own_|own-|own\.|app_|app-|app\.|debian|symphony|example|feature|serie|tree|project|runner|entry|leetcode|layout|webrtc|logic|login|worker|toolkit|mocha|support|back|inside|device|jenkin|contact|fake|awesome|ocaml|bit_|bit-|bit\.|drive|screen|prototype|gist|binary|nosql|rest|overview|dart|dark|emac|mongoid|solarized|homepage|emulator|commander|django|yandex|gradle|xcode|writer|crm_|crm-|crm\.|jade|startup|error|using|format|name|spring|parser|scratch|magic|try_|try-|try\.|rack|directive|challenge|slim|counter|element|chosen|doc_|doc-|doc\.|meta|should|button|packet|stream|hardware|android|infinite|password|software|ghost|xamarin|spec|chef|interview|hubot|mvc_|mvc-|mvc\.|exercise|leaflet|launcher|air_|air-|air\.|photo|board|boxen|way_|way-|way\.|computing|welcome|notepad|portfolio|cat_|cat-|cat\.|can_|can-|can\.|magento|yaml|domain|card|yii_|yii-|yii\.|checker|browser|upgrade|only|progres|aura|ruby_|ruby-|ruby\.|polymer|util|lite|hackathon|rule|log_|log-|log\.|opengl|stanford|skeleton|history|inspector|help|soon|selenium|lab_|lab-|lab\.|scheme|schema|look|ready|leveldb|docker|game|minimal|logstash|messaging|within|heroku|mongodb|kata|suite|picker|win_|win-|win\.|wip_|wip-|wip\.|panel|started|starter|front-end|detector|deploy|editing|based|admin|capture|spree|page|bundle|goal|rpg_|rpg-|rpg\.|setup|side|mean|reader|cookbook|mini|modern|seed|dom_|dom-|dom\.|doc_|doc-|doc\.|dot_|dot-|dot\.|syntax|sugar|loader|website|make|kit_|kit-|kit\.|protocol|human|daemon|golang|manager|countdown|connector|swagger|map_|map-|map\.|mac_|mac-|mac\.|man_|man-|man\.|orm_|orm-|orm\.|org_|org-|org\.|little|zsh_|zsh-|zsh\.|shop|show|workshop|money|grid|server|octopres|svn_|svn-|svn\.|ember|embed|general|file|important|dropbox|portable|public|docpad|fish|sbt_|sbt-|sbt\.|done|para|network|common|readme|popup|simple|purpose|mirror|single|cordova|exchange|object|design|gateway|account|lamp|intellij|math|mit_|mit-|mit\.|control|enhanced|emitter|multi|add_|add-|add\.|about|socket|preview|vagrant|cli_|cli-|cli\.|powerful|top_|top-|top\.|radio|watch|fluid|amazon|report|couchbase|automatic|detection|sprite|pyramid|portal|advanced|plu_|plu-|plu\.|runtime|git_|git-|git\.|uri_|uri-|uri\.|haml|node|sql_|sql-|sql\.|cool|core|obsolete|handler|iphone|extractor|array|copy|nlp_|nlp-|nlp\.|reveal|pop_|pop-|pop\.|engine|parse|check|html|nest|all_|all-|all\.|chinese|buildpack|what|tag_|tag-|tag\.|proxy|style|cookie|feed|restful|compiler|creating|prelude|context|java|rspec|mock|backbone|light|spotify|flex|related|shell|which|clas|webapp|swift|ansible|unity|console|tumblr|export|campfire|conway'|made|riak|hero|here|unix|unit|glas|smtp|how_|how-|how\.|hot_|hot-|hot\.|debug|release|diff|player|easy|right|old_|old-|old\.|animate|time|push|explorer|course|training|nette|router|draft|structure|note|salt|where|spark|trello|power|method|social|via_|via-|via\.|vim_|vim-|vim\.|select|webkit|github|ftp_|ftp-|ftp\.|creator|mongoose|led_|led-|led\.|movie|currently|pdf_|pdf-|pdf\.|load|markdown|phalcon|input|custom|atom|oracle|phonegap|ubuntu|great|rdf_|rdf-|rdf\.|popcorn|firefox|zip_|zip-|zip\.|cuda|dotfile|static|openwrt|viewer|powered|graphic|les_|les-|les\.|doe_|doe-|doe\.|maven|word|eclipse|lab_|lab-|lab\.|hacking|steam|analytic|option|abstract|archive|reality|switcher|club|write|kafka|arduino|angular|online|title|don't|contao|notice|analyzer|learning|zend|external|staging|busines|tdd_|tdd-|tdd\.|scanner|building|snippet|modular|bower|stm_|stm-|stm\.|lib_|lib-|lib\.|alpha|mobile|clean|linux|nginx|manifest|some|raspberry|gnome|ide_|ide-|ide\.|block|statistic|info|drag|youtube|koan|facebook|paperclip|art_|art-|art\.|quality|tab_|tab-|tab\.|need|dojo|shield|computer|stat|state|twitter|utility|converter|hosting|devise|liferay|updated|force|tip_|tip-|tip\.|behavior|active|call|answer|deck|better|principle|ches|bar_|bar-|bar\.|reddit|three|haxe|just|plug-in|agile|manual|tetri|super|beta|parsing|doctrine|minecraft|useful|perl|sharing|agent|switch|view|dash|channel|repo|pebble|profiler|warning|cluster|running|markup|evented|mod_|mod-|mod\.|share|csv_|csv-|csv\.|response|good|house|connect|built|build|find|ipython|webgl|big_|big-|big\.|google|scala|sdl_|sdl-|sdl\.|sdk_|sdk-|sdk\.|native|day_|day-|day\.|puppet|text|routing|helper|linkedin|crawler|host|guard|merchant|poker|over|writing|free|classe|component|craft|nodej|phoenix|longer|quick|lazy|memory|clone|hacker|middleman|factory|motion|multiple|tornado|hack|ssh_|ssh-|ssh\.|review|vimrc|driver|driven|blog|particle|table|intro|importer|thrift|xmpp|framework|refresh|react|font|librarie|variou|formatter|analysi|karma|scroll|tut_|tut-|tut\.|apple|tag_|tag-|tag\.|tab_|tab-|tab\.|category|ionic|cache|homebrew|reverse|english|getting|shipping|clojure|boot|book|branch|combination|combo)) + severity: INFO + - id: generic.secrets.gitleaks.github-app-token.github-app-token languages: - - java - message: DOCTYPE declarations are enabled for this DocumentBuilderFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false. + - regex + message: A gitleaks github-app-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - xml - mode: taint - pattern-sanitizers: - - by-side-effect: true - pattern-either: - - patterns: - - pattern-either: - - pattern: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - - focus-metavariable: $FACTORY - - patterns: - - pattern-either: - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", - true); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); - ... - } - ... - } - - pattern: $M($X) - - focus-metavariable: $X - pattern-sinks: - - patterns: - - pattern: $FACTORY.newDocumentBuilder(); - pattern-sources: - - by-side-effect: true - patterns: - - pattern-either: - - pattern: | - $FACTORY = DocumentBuilderFactory.newInstance(); - - patterns: - - pattern: $FACTORY - - pattern-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - severity: ERROR - - fix: $DBFACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - id: java.lang.security.audit.xxe.documentbuilderfactory-external-general-entities-true.documentbuilderfactory-external-general-entities-true + - gitleaks + patterns: + - pattern-regex: (ghu|ghs)_[0-9a-zA-Z]{36} + severity: INFO + - id: generic.secrets.gitleaks.github-fine-grained-pat.github-fine-grained-pat languages: - - java - message: External entities are allowed for $DBFACTORY. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://xml.org/sax/features/external-general-entities" to false. + - regex + message: A gitleaks github-fine-grained-pat was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - xml - pattern: $DBFACTORY.setFeature("http://xml.org/sax/features/external-general-entities", true); - severity: ERROR - - fix: $DBFACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - id: java.lang.security.audit.xxe.documentbuilderfactory-external-parameter-entities-true.documentbuilderfactory-external-parameter-entities-true + - gitleaks + patterns: + - pattern-regex: github_pat_[0-9a-zA-Z_]{82} + severity: INFO + - id: generic.secrets.gitleaks.github-oauth.github-oauth languages: - - java - message: External entities are allowed for $DBFACTORY. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://xml.org/sax/features/external-parameter-entities" to false. + - regex + message: A gitleaks github-oauth was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - xml - pattern: $DBFACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", true); - severity: ERROR - - fix: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - $FACTORY.newSAXParser(); - id: java.lang.security.audit.xxe.saxparserfactory-disallow-doctype-decl-missing.saxparserfactory-disallow-doctype-decl-missing + - gitleaks + patterns: + - pattern-regex: gho_[0-9a-zA-Z]{36} + severity: INFO + - id: generic.secrets.gitleaks.github-pat.github-pat languages: - - java - message: DOCTYPE declarations are enabled for this SAXParserFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature `http://apache.org/xml/features/disallow-doctype-decl` to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features `http://xml.org/sax/features/external-general-entities` and `http://xml.org/sax/features/external-parameter-entities` to false. NOTE - The previous links are not meant to be clicked. They are the literal config key values that are supposed to be used to disable these features. For more information, see https://semgrep.dev/docs/cheat-sheets/java-xxe/#3a-documentbuilderfactory. + - regex + message: A gitleaks github-pat was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - xml - mode: taint - pattern-sanitizers: - - by-side-effect: true - pattern-either: - - patterns: - - pattern-either: - - pattern: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - - focus-metavariable: $FACTORY - - patterns: - - pattern-either: - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", - true); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); - ... - } - ... - } - - pattern: $M($X) - - focus-metavariable: $X - pattern-sinks: - - patterns: - - pattern: $FACTORY.newSAXParser(); - pattern-sources: - - by-side-effect: true - patterns: - - pattern-either: - - pattern: | - $FACTORY = SAXParserFactory.newInstance(); - - patterns: - - pattern: $FACTORY - - pattern-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - severity: ERROR - - fix: | - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - $FACTORY.newTransformer(...); - id: java.lang.security.audit.xxe.transformerfactory-dtds-not-disabled.transformerfactory-dtds-not-disabled + - gitleaks + patterns: + - pattern-regex: ghp_[0-9a-zA-Z]{36} + severity: INFO + - id: generic.secrets.gitleaks.github-refresh-token.github-refresh-token languages: - - java - message: DOCTYPE declarations are enabled for this TransformerFactory. This is vulnerable to XML external entity attacks. Disable this by setting the attributes "accessExternalDTD" and "accessExternalStylesheet" to "". + - regex + message: A gitleaks github-refresh-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - xml - mode: taint - pattern-sanitizers: - - by-side-effect: true - pattern-either: - - patterns: - - pattern-either: - - pattern: | - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - - pattern: | - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - - pattern: | - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - - pattern: | - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - - focus-metavariable: $FACTORY - - patterns: - - pattern-either: - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - } - ... - } - - pattern: $M($X) - - focus-metavariable: $X - pattern-sinks: - - patterns: - - pattern: $FACTORY.newTransformer(...); - pattern-sources: - - by-side-effect: true - patterns: - - pattern-either: - - pattern: | - $FACTORY = TransformerFactory.newInstance(); - - patterns: - - pattern: $FACTORY - - pattern-inside: | - class $C { - ... - $V $FACTORY = TransformerFactory.newInstance(); - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - } - ... - } - severity: ERROR - - id: java.lang.security.httpservlet-path-traversal.httpservlet-path-traversal + - gitleaks + patterns: + - pattern-regex: ghr_[0-9a-zA-Z]{36} + severity: INFO + - id: generic.secrets.gitleaks.gitlab-pat.gitlab-pat languages: - - java - message: Detected a potential path traversal. A malicious actor could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. + - regex + message: A gitleaks gitlab-pat was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://www.owasp.org/index.php/Path_Traversal - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - mode: taint - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (java.io.File $FILE) = ... - - pattern: | - (java.io.FileOutputStream $FOS) = ... - - pattern: | - new java.io.FileInputStream(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); - ... - for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { - ... - } - - pattern: | - $COOKIE.getValue(...) - - patterns: - - pattern-inside: | - $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(...); - ... - - pattern: | - $PARAM = $VALS[$INDEX]; - severity: ERROR - - id: java.lang.security.insecure-jms-deserialization.insecure-jms-deserialization + - gitleaks + patterns: + - pattern-regex: glpat-[0-9a-zA-Z\-\_]{20} + severity: INFO + - id: generic.secrets.gitleaks.gitlab-ptt.gitlab-ptt languages: - - java - message: JMS Object messages depend on Java Serialization for marshalling/unmarshalling of the message payload when ObjectMessage.getObject() is called. Deserialization of untrusted data can lead to security flaws; a remote attacker could via a crafted JMS ObjectMessage to execute arbitrary code with the permissions of the application listening/consuming JMS Messages. In this case, the JMS MessageListener consume an ObjectMessage type received inside the onMessage method, which may lead to arbitrary code execution when calling the $Y.getObject method. + - regex + message: A gitleaks gitlab-ptt was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.5.3 Insecue Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-502: Deserialization of Untrusted Data' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures + - A07:2021 - Identification and Authentication Failures references: - - https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities-wp.pdf + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern-inside: | - public class $JMS_LISTENER implements MessageListener { - ... - public void onMessage(Message $JMS_MSG) { - ... - } - } - - pattern-either: - - pattern-inside: $X = $Y.getObject(...); - - pattern-inside: $X = ($Z) $Y.getObject(...); - severity: WARNING - - id: java.lang.security.jackson-unsafe-deserialization.jackson-unsafe-deserialization + - pattern-regex: glptt-[0-9a-f]{40} + severity: INFO + - id: generic.secrets.gitleaks.gitlab-rrt.gitlab-rrt languages: - - java - message: When using Jackson to marshall/unmarshall JSON to Java objects, enabling default typing is dangerous and can lead to RCE. If an attacker can control `$JSON` it might be possible to provide a malicious JSON which can be used to exploit unsecure deserialization. In order to prevent this issue, avoid to enable default typing (globally or by using "Per-class" annotations) and avoid using `Object` and other dangerous types for member variable declaration which creating classes for Jackson based deserialization. + - regex + message: A gitleaks gitlab-rrt was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-502: Deserialization of Untrusted Data' - impact: HIGH + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: LOW owasp: - - A8:2017 Insecure Deserialization - - A8:2021 Software and Data Integrity Failures + - A07:2021 - Identification and Authentication Failures references: - - https://swapneildash.medium.com/understanding-insecure-implementation-of-jackson-deserialization-7b3d409d2038 - - https://cowtowncoder.medium.com/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062 - - https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - jackson + - gitleaks patterns: - - pattern-either: - - patterns: - - pattern-inside: | - ObjectMapper $OM = new ObjectMapper(...); - ... - - pattern-inside: | - $OM.enableDefaultTyping(); - ... - - pattern: $OM.readValue($JSON, ...); - - patterns: - - pattern-inside: | - class $CLASS { - ... - @JsonTypeInfo(use = Id.CLASS,...) - $TYPE $VAR; - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: (Object|Serializable|Comparable) - - pattern: $OM.readValue($JSON, $CLASS.class); - - patterns: - - pattern-inside: | - class $CLASS { - ... - ObjectMapper $OM; - ... - $INITMETHODTYPE $INITMETHOD(...) { - ... - $OM = new ObjectMapper(); - ... - $OM.enableDefaultTyping(); - ... - } - ... - } - - pattern-inside: "$METHODTYPE $METHOD(...) {\n ... \n}\n" - - pattern: $OM.readValue($JSON, ...); - severity: WARNING - - id: java.lang.security.servletresponse-writer-xss.servletresponse-writer-xss + - pattern-regex: GR1348941[0-9a-zA-Z\-\_]{20} + severity: INFO + - id: generic.secrets.gitleaks.gitter-access-token.gitter-access-token languages: - - java - message: 'Cross-site scripting detected in HttpServletResponse writer with variable ''$VAR''. User input was detected going directly from the HttpServletRequest into output. Ensure your data is properly encoded using org.owasp.encoder.Encode.forHtml: ''Encode.forHtml($VAR)''.' + - regex + message: A gitleaks gitter-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#XSS_SERVLET + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern-inside: $TYPE $FUNC(..., HttpServletResponse $RESP, ...) { ... } - - pattern-inside: $VAR = $REQ.getParameter(...); ... - - pattern-either: - - pattern: $RESP.getWriter(...).write(..., $VAR, ...); - - pattern: | - $WRITER = $RESP.getWriter(...); - ... - $WRITER.write(..., $VAR, ...); - severity: ERROR - - id: java.lang.security.xmlinputfactory-possible-xxe.xmlinputfactory-possible-xxe + - pattern-regex: (?i)(?:gitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.gocardless-api-token.gocardless-api-token languages: - - java - message: XML external entities are not explicitly disabled for this XMLInputFactory. This could be vulnerable to XML external entity vulnerabilities. Explicitly disable external entities by setting "javax.xml.stream.isSupportingExternalEntities" to false. + - regex + message: A gitleaks gocardless-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#xmlinputfactory-a-stax-parser + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java + - gitleaks patterns: - - pattern-not-inside: | - $METHOD(...) { - ... - $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", false); - ... - } - - pattern-not-inside: | - $METHOD(...) { - ... - $XMLFACTORY.setProperty(javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); - ... - } - - pattern-not-inside: | - $METHOD(...) { - ... - $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", Boolean.FALSE); - ... - } - - pattern-not-inside: | - $METHOD(...) { - ... - $XMLFACTORY.setProperty(javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); - ... - } - - pattern-either: - - pattern: javax.xml.stream.XMLInputFactory.newFactory(...) - - pattern: new XMLInputFactory(...) - severity: WARNING - - id: java.spring.security.audit.spring-actuator-fully-enabled-yaml.spring-actuator-fully-enabled-yaml + - pattern-regex: (?i)(?:gocardless)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(live_(?i)[a-z0-9\-_=]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.grafana-api-key.grafana-api-key languages: - - yaml - message: Spring Boot Actuator is fully enabled. This exposes sensitive endpoints such as /actuator/env, /actuator/logfile, /actuator/heapdump and others. Unless you have Spring Security enabled or another means to protect these endpoints, this functionality is available without authentication, causing a severe security risk. + - regex + message: A gitleaks grafana-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true - impact: HIGH - likelihood: MEDIUM + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints - - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 - - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - spring + - gitleaks patterns: - - pattern-inside: | - management: - ... - endpoints: - ... - web: - ... - exposure: - ... - - pattern: | - include: "*" - severity: WARNING - - id: java.spring.security.audit.spring-actuator-fully-enabled.spring-actuator-fully-enabled + - pattern-regex: (?i)\b(eyJrIjoi[A-Za-z0-9]{70,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.grafana-cloud-api-token.grafana-cloud-api-token languages: - - generic - message: Spring Boot Actuator is fully enabled. This exposes sensitive endpoints such as /actuator/env, /actuator/logfile, /actuator/heapdump and others. Unless you have Spring Security enabled or another means to protect these endpoints, this functionality is available without authentication, causing a significant security risk. + - regex + message: A gitleaks grafana-cloud-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true - impact: HIGH - likelihood: MEDIUM + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints - - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 - - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - spring - paths: - include: - - '*properties' - pattern: management.endpoints.web.exposure.include=* - severity: ERROR - - id: java.spring.security.audit.spring-actuator-non-health-enabled-yaml.spring-actuator-dangerous-endpoints-enabled-yaml + - gitleaks + patterns: + - pattern-regex: (?i)\b(glc_[A-Za-z0-9+/]{32,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.grafana-service-account-token.grafana-service-account-token languages: - - yaml - message: Spring Boot Actuator "$ACTUATOR" is enabled. Depending on the actuator, this can pose a significant security risk. Please double-check if the actuator is needed and properly secured. + - regex + message: A gitleaks grafana-service-account-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true - impact: HIGH - likelihood: MEDIUM + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints - - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 - - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - spring + - gitleaks patterns: - - pattern-inside: | - management: - ... - endpoints: - ... - web: - ... - exposure: - ... - include: - ... - - pattern: | - include: [..., $ACTUATOR, ...] - - metavariable-comparison: - comparison: not str($ACTUATOR) in ["health","*"] - metavariable: $ACTUATOR - severity: WARNING - - id: java.spring.security.audit.spring-actuator-non-health-enabled.spring-actuator-dangerous-endpoints-enabled + - pattern-regex: (?i)\b(glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.harness-api-key.harness-api-key languages: - - generic - message: Spring Boot Actuators "$...ACTUATORS" are enabled. Depending on the actuators, this can pose a significant security risk. Please double-check if the actuators are needed and properly secured. + - regex + message: A gitleaks harness-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true - impact: HIGH - likelihood: MEDIUM + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints - - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 - - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - spring - options: - generic_ellipsis_max_span: 0 + - gitleaks patterns: - - pattern: management.endpoints.web.exposure.include=$...ACTUATORS - - metavariable-comparison: - comparison: not str($...ACTUATORS) in ["health","*"] - metavariable: $...ACTUATORS - severity: WARNING - - id: java.spring.security.audit.spring-sqli.spring-sqli + - pattern-regex: ((?:pat|sat)\.[a-zA-Z0-9]{22}\.[a-zA-Z0-9]{24}\.[a-zA-Z0-9]{20}) + severity: INFO + - id: generic.secrets.gitleaks.hashicorp-tf-api-token.hashicorp-tf-api-token languages: - - java - message: Detected a string argument from a public method contract in a raw SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. + - regex + message: A gitleaks hashicorp-tf-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - spring - mode: taint - options: - taint_assume_safe_booleans: true - taint_assume_safe_numbers: true - pattern-sanitizers: - - not_conflicting: true - pattern-either: - - patterns: - - focus-metavariable: $A - - pattern-inside: | - new $TYPE(...,$A,...); - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - focus-metavariable: $A - - pattern: | - new PreparedStatementCreatorFactory($A,...); - - patterns: - - focus-metavariable: $A - - pattern: | - (JdbcTemplate $T).$M($A,...) - - patterns: - - pattern: (String $A) - - pattern-inside: | - (JdbcTemplate $T).batchUpdate(...) - - patterns: - - focus-metavariable: $A - - pattern: | - NamedParameterBatchUpdateUtils.$M($A,...) - - patterns: - - focus-metavariable: $A - - pattern: | - BatchUpdateUtils.$M($A,...) - pattern-sources: - - patterns: - - pattern: $ARG - - pattern-inside: | - public $T $M (..., String $ARG,...){...} - severity: WARNING - - id: java.spring.security.audit.spring-unvalidated-redirect.spring-unvalidated-redirect + - gitleaks + patterns: + - pattern-regex: (?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70} + severity: INFO + - id: generic.secrets.gitleaks.hashicorp-tf-password.hashicorp-tf-password languages: - - java - message: Application redirects a user to a destination URL specified by a user supplied parameter that is not validated. + - regex + message: A gitleaks hashicorp-tf-password was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNVALIDATED_REDIRECT + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - spring - pattern-either: - - pattern: | - $X $METHOD(...,String $URL,...) { - return "redirect:" + $URL; - } - - pattern: | - $X $METHOD(...,String $URL,...) { - ... - String $REDIR = "redirect:" + $URL; - ... - return $REDIR; - ... - } - - pattern: | - $X $METHOD(...,String $URL,...) { - ... - new ModelAndView("redirect:" + $URL); - ... - } - - pattern: |- - $X $METHOD(...,String $URL,...) { - ... - String $REDIR = "redirect:" + $URL; - ... - new ModelAndView($REDIR); - ... - } - severity: WARNING - - id: java.spring.security.injection.tainted-file-path.tainted-file-path + - gitleaks + patterns: + - pattern-regex: (?i)(?:administrator_login_password|password)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}("[a-z0-9=_\-]{8,20}")(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.heroku-api-key.heroku-api-key languages: - - java - message: Detected user input controlling a file path. An attacker could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. + - regex + message: A gitleaks heroku-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-23: Relative Path Traversal' - impact: HIGH - interfile: true - likelihood: MEDIUM + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/www-community/attacks/Path_Traversal + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - spring - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: new File(...) - - pattern: new java.io.File(...) - - pattern: new FileReader(...) - - pattern: new java.io.FileReader(...) - - pattern: new FileInputStream(...) - - pattern: new java.io.FileInputStream(...) - - pattern: (Paths $PATHS).get(...) - - patterns: - - pattern: | - $CLASS.$FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: ^(getResourceAsStream|getResource)$ - - patterns: - - pattern-either: - - pattern: new ClassPathResource($FILE, ...) - - pattern: ResourceUtils.getFile($FILE, ...) - - pattern: new FileOutputStream($FILE, ...) - - pattern: new java.io.FileOutputStream($FILE, ...) - - pattern: new StreamSource($FILE, ...) - - pattern: new javax.xml.transform.StreamSource($FILE, ...) - - pattern: FileUtils.openOutputStream($FILE, ...) - - focus-metavariable: $FILE - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE - severity: ERROR - - id: java.spring.security.injection.tainted-html-string.tainted-html-string + - gitleaks + patterns: + - pattern-regex: (?i)(?:heroku)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.hubspot-api-key.hubspot-api-key languages: - - java - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. You can use the OWASP ESAPI encoder if you must render user data. + - regex + message: A gitleaks hubspot-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - spring - mode: taint - pattern-propagators: - - from: $...TAINTED - pattern: (StringBuilder $SB).append($...TAINTED) - to: $SB - - from: $...TAINTED - pattern: $VAR += $...TAINTED - to: $VAR - pattern-sanitizers: - - pattern-either: - - pattern: Encode.forHtml(...) - - pattern: (PolicyFactory $POLICY).sanitize(...) - - pattern: (AntiSamy $AS).scan(...) - - pattern: JSoup.clean(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: new ResponseEntity<>($PAYLOAD, ...) - - pattern: new ResponseEntity<$ERROR>($PAYLOAD, ...) - - pattern: ResponseEntity. ... .body($PAYLOAD) - - patterns: - - pattern: | - ResponseEntity.$RESPFUNC($PAYLOAD). ... - - metavariable-regex: - metavariable: $RESPFUNC - regex: ^(ok|of)$ - - focus-metavariable: $PAYLOAD - requires: CONCAT - pattern-sources: - - label: INPUT - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE - - by-side-effect: true - label: CONCAT - patterns: - - pattern-either: - - pattern: | - "$HTMLSTR" + ... - - pattern: | - "$HTMLSTR".concat(...) - - patterns: - - pattern-inside: | - StringBuilder $SB = new StringBuilder("$HTMLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$HTMLSTR"; - ... - - pattern: $VAR += ... - - pattern: String.format("$HTMLSTR", ...) - - patterns: - - pattern-inside: | - String $VAR = "$HTMLSTR"; - ... - - pattern: String.format($VAR, ...) - - metavariable-regex: - metavariable: $HTMLSTR - regex: ^<\w+ - requires: INPUT - severity: ERROR - - id: java.spring.security.injection.tainted-sql-string.tainted-sql-string + - gitleaks + patterns: + - pattern-regex: (?i)(?:hubspot)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.huggingface-access-token.huggingface-access-token languages: - - java - message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. + - regex + message: A gitleaks huggingface-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - spring - mode: taint - options: - interfile: true - taint_assume_safe_booleans: true - taint_assume_safe_numbers: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR".concat(...) - - patterns: - - pattern-inside: | - StringBuilder $SB = new StringBuilder("$SQLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$SQLSTR"; - ... - - pattern: $VAR += ... - - pattern: String.format("$SQLSTR", ...) - - patterns: - - pattern-inside: | - String $VAR = "$SQLSTR"; - ... - - pattern: String.format($VAR, ...) - - pattern-not-inside: System.out.println(...) - - pattern-not-inside: $LOG.info(...) - - pattern-not-inside: $LOG.warn(...) - - pattern-not-inside: $LOG.warning(...) - - pattern-not-inside: $LOG.debug(...) - - pattern-not-inside: $LOG.debugging(...) - - pattern-not-inside: $LOG.error(...) - - pattern-not-inside: new Exception(...) - - pattern-not-inside: throw ...; - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue) - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - focus-metavariable: $SOURCE - severity: ERROR - - id: java.spring.security.injection.tainted-system-command.tainted-system-command + - gitleaks + patterns: + - pattern-regex: (?:^|[\\'"` >=:])(hf_[a-zA-Z]{34})(?:$|[\\'"` <]) + severity: INFO + - id: generic.secrets.gitleaks.huggingface-organization-api-token.huggingface-organization-api-token languages: - - java - message: 'Detected user input entering a method which executes a system command. This could result in a command injection vulnerability, which allows an attacker to inject an arbitrary system command onto the server. The attacker could download malware onto or steal data from the server. Instead, use ProcessBuilder, separating the command into individual arguments, like this: `new ProcessBuilder("ls", "-al", targetDirectory)`. Further, make sure you hardcode or allowlist the actual command so that attackers can''t run arbitrary commands.' + - regex + message: A gitleaks huggingface-organization-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - likelihood: HIGH + impact: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://www.stackhawk.com/blog/command-injection-java/ - - https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html - - https://github.com/github/codeql/blob/main/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.java + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - spring - mode: taint - pattern-propagators: - - from: $INPUT - label: CONCAT - pattern: (StringBuilder $STRB).append($INPUT) - requires: INPUT - to: $STRB - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (Process $P) = new Process(...); - - pattern: | - (ProcessBuilder $PB).command(...); - - patterns: - - pattern-either: - - pattern: | - (Runtime $R).$EXEC(...); - - pattern: | - Runtime.getRuntime(...).$EXEC(...); - - metavariable-regex: - metavariable: $EXEC - regex: (exec|loadLibrary|load) - - patterns: - - pattern: | - (ProcessBuilder $PB).command(...).$ADD(...); - - metavariable-regex: - metavariable: $ADD - regex: (add|addAll) - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $BUILDER = new ProcessBuilder(...); - ... - - pattern: $BUILDER.start(...) - - pattern: | - new ProcessBuilder(...). ... .start(...); - requires: CONCAT - pattern-sources: - - label: INPUT - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE - - label: CONCAT - patterns: - - pattern-either: - - pattern: $X + $SOURCE - - pattern: $SOURCE + $Y - - pattern: String.format("...", ..., $SOURCE, ...) - - pattern: String.join("...", ..., $SOURCE, ...) - - pattern: (String $STR).concat($SOURCE) - - pattern: $SOURCE.concat(...) - - pattern: $X += $SOURCE - - pattern: $SOURCE += $X - requires: INPUT - severity: ERROR - - id: java.spring.security.injection.tainted-url-host.tainted-url-host + - gitleaks + patterns: + - pattern-regex: (?:^|[\\'"` >=:\(,)])(api_org_[a-zA-Z]{34})(?:$|[\\'"` <\),]) + severity: INFO + - id: generic.secrets.gitleaks.infracost-api-token.infracost-api-token languages: - - java - message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, hardcode the correct host, or ensure that the user data can only affect the path or parameters. + - regex + message: A gitleaks infracost-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: MEDIUM + likelihood: LOW owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - java - - spring - mode: taint - options: - interfile: true - pattern-sinks: - - pattern-either: - - pattern: new URL($ONEARG) - - patterns: - - pattern-either: - - pattern: | - "$URLSTR" + ... - - pattern: | - "$URLSTR".concat(...) - - patterns: - - pattern-inside: | - StringBuilder $SB = new StringBuilder("$URLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$URLSTR"; - ... - - pattern: $VAR += ... - - patterns: - - pattern: String.format("$URLSTR", ...) - - pattern-not: String.format("$URLSTR", "...", ...) - - patterns: - - pattern-inside: | - String $VAR = "$URLSTR"; - ... - - pattern: String.format($VAR, ...) - - metavariable-regex: - metavariable: $URLSTR - regex: http(s?)://%(v|s|q).* - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE - severity: ERROR - - id: javascript.angular.security.detect-angular-element-taint.detect-angular-element-taint + - gitleaks + patterns: + - pattern-regex: (?i)\b(ico-[a-zA-Z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.intercom-api-key.intercom-api-key languages: - - javascript - - typescript - message: Use of angular.element can lead to XSS if user-input is treated as part of the HTML element within `$SINK`. It is recommended to contextually output encode user-input, before inserting into `$SINK`. If the HTML needs to be preserved it is recommended to sanitize the input using $sce.getTrustedHTML or $sanitize. + - regex + message: A gitleaks intercom-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://docs.angularjs.org/api/ng/function/angular.element - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - angularjs - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: $sce.getTrustedHtml(...) - - pattern: $sanitize(...) - - pattern: DOMPurify.sanitize(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - angular.element(...). ... .$SINK($QUERY) - - pattern-inside: | - $ANGULAR = angular.element(...) - ... - $ANGULAR. ... .$SINK($QUERY) - - metavariable-regex: - metavariable: $SINK - regex: ^(after|append|html|prepend|replaceWith|wrap)$ - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-either: - - pattern: window.location.search - - pattern: window.document.location.search - - pattern: document.location.search - - pattern: location.search - - pattern: $location.search(...) - - patterns: - - pattern-either: - - pattern: $DECODE(<... location.hash ...>) - - pattern: $DECODE(<... window.location.hash ...>) - - pattern: $DECODE(<... document.location.hash ...>) - - pattern: $DECODE(<... location.href ...>) - - pattern: $DECODE(<... window.location.href ...>) - - pattern: $DECODE(<... document.location.href ...>) - - pattern: $DECODE(<... document.URL ...>) - - pattern: $DECODE(<... window.document.URL ...>) - - pattern: $DECODE(<... document.location.href ...>) - - pattern: $DECODE(<... document.location.href ...>) - - pattern: $DECODE(<... $location.absUrl() ...>) - - pattern: $DECODE(<... $location.url() ...>) - - pattern: $DECODE(<... $location.hash() ...>) - - metavariable-regex: - metavariable: $DECODE - regex: ^(unescape|decodeURI|decodeURIComponent)$ - - patterns: - - pattern-inside: $http.$METHOD(...).$CONTINUE(function $FUNC($RES) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|delete|head|jsonp|post|put|patch) - - pattern: $RES.data - severity: WARNING - - id: javascript.angular.security.detect-angular-sce-disabled.detect-angular-sce-disabled + - gitleaks + patterns: + - pattern-regex: (?i)(?:intercom)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{60})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.intra42-client-secret.intra42-client-secret languages: - - javascript - - typescript - message: $sceProvider is set to false. Disabling Strict Contextual escaping (SCE) in an AngularJS application could provide additional attack surface for XSS vulnerabilities. + - regex + message: A gitleaks intra42-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://docs.angularjs.org/api/ng/service/$sce - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - angular - pattern: | - $sceProvider.enabled(false); - severity: ERROR - - id: javascript.angular.security.detect-angular-trust-as-method.detect-angular-trust-as-method + - gitleaks + patterns: + - pattern-regex: (?i)\b(s-s4t2(?:ud|af)-[abcdef0123456789]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.jfrog-api-key.jfrog-api-key languages: - - javascript - - typescript - message: The use of $sce.trustAs can be dangerous if unsanitized user input flows through this API. + - regex + message: A gitleaks jfrog-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://docs.angularjs.org/api/ng/service/$sce - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - angular - mode: taint - pattern-sinks: - - pattern: $sce.trustAs(...) - - pattern: $sce.trustAsHtml(...) - pattern-sources: - - patterns: - - pattern-inside: | - app.controller(..., function($scope,$sce) { - ... - }); - - pattern: $scope.$X - severity: WARNING - - id: javascript.argon2.security.unsafe-argon2-config.unsafe-argon2-config + - gitleaks + patterns: + - pattern-regex: (?i)(?:jfrog|artifactory|bintray|xray)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{73})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.jfrog-identity-token.jfrog-identity-token languages: - - javascript - - typescript - message: Prefer Argon2id where possible. Per RFC9016, section 4 IETF recommends selecting Argon2id unless you can guarantee an adversary has no direct access to the computing environment. + - regex + message: A gitleaks jfrog-identity-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-916: Use of Password Hash With Insufficient Computational Effort' - impact: LOW - likelihood: HIGH + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - - https://eprint.iacr.org/2016/759.pdf - - https://www.cs.tau.ac.il/~tromer/papers/cache-joc-20090619.pdf - - https://datatracker.ietf.org/doc/html/rfc9106#section-4 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - argon2 - - cryptography - mode: taint - pattern-sanitizers: - - patterns: - - pattern: | - {type: $ARGON.argon2id} - ... - pattern-sinks: - - patterns: - - pattern: | - $Y - - pattern-inside: | - $ARGON.hash(...,$Y) - pattern-sources: - - patterns: - - pattern-inside: | - $ARGON = require('argon2'); - ... - - pattern: | - {type: ...} - severity: WARNING - - id: javascript.aws-lambda.security.detect-child-process.detect-child-process + - gitleaks + patterns: + - pattern-regex: (?i)(?:jfrog|artifactory|bintray|xray)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.jwt-base64.jwt-base64 languages: - - javascript - - typescript - message: Allowing spawning arbitrary programs or running shell processes with arbitrary arguments may end up in a command injection vulnerability. Try to avoid non-literal values for the command string. If it is not possible, then do not let running arbitrary commands, use a white list for inputs. + - regex + message: A gitleaks jwt-base64 was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + impact: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - javascript - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $CMD - - pattern-either: - - pattern: exec($CMD,...) - - pattern: execSync($CMD,...) - - pattern: spawn($CMD,...) - - pattern: spawnSync($CMD,...) - - pattern: $CP.exec($CMD,...) - - pattern: $CP.execSync($CMD,...) - - pattern: $CP.spawn($CMD,...) - - pattern: $CP.spawnSync($CMD,...) - - pattern-either: - - pattern-inside: | - require('child_process') - ... - - pattern-inside: | - import 'child_process' - ... - pattern-sources: - - patterns: - - pattern: $EVENT - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - severity: ERROR - - id: javascript.aws-lambda.security.dynamodb-request-object.dynamodb-request-object + - gitleaks + patterns: + - pattern-regex: \bZXlK(?:(?PaGJHY2lPaU)|(?PaGNIVWlPaU)|(?PaGNIWWlPaU)|(?PaGRXUWlPaU)|(?PaU5qUWlP)|(?PamNtbDBJanBi)|(?PamRIa2lPaU)|(?PbGNHc2lPbn)|(?PbGJtTWlPaU)|(?PcWEzVWlPaU)|(?PcWQyc2lPb)|(?PcGMzTWlPaU)|(?PcGRpSTZJ)|(?PcmFXUWlP)|(?PclpYbGZiM0J6SWpwY)|(?PcmRIa2lPaUp)|(?PdWIyNWpaU0k2)|(?Pd01tTWlP)|(?Pd01uTWlPaU)|(?Pd2NIUWlPaU)|(?PemRXSWlPaU)|(?PemRuUWlP)|(?PMFlXY2lPaU)|(?PMGVYQWlPaUp)|(?PMWNtd2l)|(?PMWMyVWlPaUp)|(?PMlpYSWlPaU)|(?PMlpYSnphVzl1SWpv)|(?PNElqb2)|(?PNE5XTWlP)|(?PNE5YUWlPaU)|(?PNE5YUWpVekkxTmlJNkl)|(?PNE5YVWlPaU)|(?PNmFYQWlPaU))[a-zA-Z0-9\/\\_+\-\r\n]{40,}={0,2} + severity: INFO + - id: generic.secrets.gitleaks.jwt.jwt languages: - - javascript - - typescript - message: Detected DynamoDB query params that are tainted by `$EVENT` object. This could lead to NoSQL injection if the variable is user-controlled and not properly sanitized. Explicitly assign query params instead of passing data from `$EVENT` directly to DynamoDB client. + - regex + message: A gitleaks jwt was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-943: Improper Neutralization of Special Elements in Data Query Logic' - impact: HIGH - likelihood: MEDIUM + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - javascript - - aws-lambda - - dynamodb - mode: taint - pattern-sanitizers: - - patterns: - - pattern: | - {...} - pattern-sinks: - - patterns: - - focus-metavariable: $SINK - - pattern: | - $DC.$METHOD($SINK, ...) - - metavariable-regex: - metavariable: $METHOD - regex: (query|send|scan|delete|put|transactWrite|update|batchExecuteStatement|executeStatement|executeTransaction|transactWriteItems) - - pattern-either: - - pattern-inside: | - $DC = new $AWS.DocumentClient(...); - ... - - pattern-inside: | - $DC = new $AWS.DynamoDB(...); - ... - - pattern-inside: | - $DC = new DynamoDBClient(...); - ... - - pattern-inside: | - $DC = DynamoDBDocumentClient.from(...); - ... - pattern-sources: - - patterns: - - pattern: $EVENT - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - severity: ERROR - - id: javascript.aws-lambda.security.knex-sqli.knex-sqli + - gitleaks + patterns: + - pattern-regex: \b(ey[a-zA-Z0-9]{17,}\.ey[a-zA-Z0-9\/\\_-]{17,}\.(?:[a-zA-Z0-9\/\\_-]{10,}={0,2})?)(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.kraken-access-token.kraken-access-token languages: - - javascript - - typescript - message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `knex.raw(''SELECT $1 from table'', [userinput])`' + - regex + message: A gitleaks kraken-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + impact: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://knexjs.org/#Builder-fromRaw - - https://knexjs.org/#Builder-whereRaw + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws-lambda - - knex - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $KNEX.fromRaw($QUERY, ...) - - pattern: $KNEX.whereRaw($QUERY, ...) - - pattern: $KNEX.raw($QUERY, ...) - - pattern-either: - - pattern-inside: | - require('knex') - ... - - pattern-inside: | - import 'knex' - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.mysql-sqli.mysql-sqli + - gitleaks + patterns: + - pattern-regex: (?i)(?:kraken)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9\/=_\+\-]{80,90})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.kucoin-access-token.kucoin-access-token languages: - - javascript - - typescript - message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `connection.query(''SELECT $1 from table'', [userinput])`' + - regex + message: A gitleaks kucoin-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + impact: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://www.npmjs.com/package/mysql2 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws-lambda - - mysql - - mysql2 - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $POOL.query($QUERY, ...) - - pattern: $POOL.execute($QUERY, ...) - - pattern-either: - - pattern-inside: | - require('mysql') - ... - - pattern-inside: | - require('mysql2') - ... - - pattern-inside: | - require('mysql2/promise') - ... - - pattern-inside: | - import 'mysql' - ... - - pattern-inside: | - import 'mysql2' - ... - - pattern-inside: | - import 'mysql2/promise' - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.pg-sqli.pg-sqli + - gitleaks + patterns: + - pattern-regex: (?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.kucoin-secret-key.kucoin-secret-key languages: - - javascript - - typescript - message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `connection.query(''SELECT $1 from table'', [userinput])`' + - regex + message: A gitleaks kucoin-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + impact: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://node-postgres.com/features/queries + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws-lambda - - postgres - - pg - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $DB.query($QUERY, ...) - - pattern-either: - - pattern-inside: | - require('pg') - ... - - pattern-inside: | - import 'pg' - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.sequelize-sqli.sequelize-sqli + - gitleaks + patterns: + - pattern-regex: (?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.launchdarkly-access-token.launchdarkly-access-token languages: - - javascript - - typescript - message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `sequelize.query(''SELECT * FROM projects WHERE status = ?'', { replacements: [''active''], type: QueryTypes.SELECT });`' + - regex + message: A gitleaks launchdarkly-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + impact: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://sequelize.org/master/manual/raw-queries.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws-lambda - - sequelize - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $DB.query($QUERY, ...) - - pattern-either: - - pattern-inside: | - require('sequelize') - ... - - pattern-inside: | - import 'sequelize' - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.tainted-html-response.tainted-html-response + - gitleaks + patterns: + - pattern-regex: (?i)(?:launchdarkly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.linear-api-key.linear-api-key languages: - - javascript - - typescript - message: Detected user input flowing into an HTML response. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. + - regex + message: A gitleaks linear-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $BODY - - pattern-inside: | - {..., headers: {..., 'Content-Type': 'text/html', ...}, body: $BODY, ... } - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.tainted-html-string.tainted-html-string + - gitleaks + patterns: + - pattern-regex: lin_api_(?i)[a-z0-9]{40} + severity: INFO + - id: generic.secrets.gitleaks.linear-client-secret.linear-client-secret languages: - - javascript - - typescript - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates which will safely render HTML instead. + - regex + message: A gitleaks linear-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - "$HTMLSTR" + $EXPR - - pattern: | - "$HTMLSTR".concat(...) - - pattern: $UTIL.format($HTMLSTR, ...) - - pattern: format($HTMLSTR, ...) - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - - patterns: - - pattern: | - `...${...}...` - - pattern-regex: | - .*<\w+.* - - pattern-not-inside: | - console.$LOG(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.tainted-sql-string.tainted-sql-string + - gitleaks + patterns: + - pattern-regex: (?i)(?:linear)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.linkedin-client-id.linkedin-client-id languages: - - javascript - - typescript - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + - regex + message: A gitleaks linkedin-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/www-community/attacks/SQL_Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + $EXPR - - pattern: | - "$SQLSTR".concat(...) - - pattern: util.format($SQLSTR, ...) - - metavariable-regex: - metavariable: $SQLSTR - regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - - patterns: - - pattern: | - `...${...}...` - - pattern-regex: | - .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - - pattern-not-inside: | - console.$LOG(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: ERROR - - id: javascript.aws-lambda.security.vm-runincontext-injection.vm-runincontext-injection + - gitleaks + patterns: + - pattern-regex: (?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{14})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.linkedin-client-secret.linkedin-client-secret languages: - - javascript - - typescript - message: The `vm` module enables compiling and running code within V8 Virtual Machine contexts. The `vm` module is not a security mechanism. Do not use it to run untrusted code. If code passed to `vm` functions is controlled by user input it could result in command injection. Do not let user input in `vm` functions. + - regex + message: A gitleaks linkedin-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - javascript - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('vm'); - ... - - pattern-inside: | - import 'vm' - ... - - pattern-either: - - pattern: $VM.runInContext($X,...) - - pattern: $VM.runInNewContext($X,...) - - pattern: $VM.runInThisContext($X,...) - - pattern: $VM.compileFunction($X,...) - - pattern: new $VM.Script($X,...) - - pattern: new $VM.SourceTextModule($X,...) - - pattern: runInContext($X,...) - - pattern: runInNewContext($X,...) - - pattern: runInThisContext($X,...) - - pattern: compileFunction($X,...) - - pattern: new Script($X,...) - - pattern: new SourceTextModule($X,...) - pattern-sources: - - patterns: - - pattern: $EVENT - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - severity: ERROR - - id: javascript.browser.security.open-redirect.js-open-redirect + - gitleaks + patterns: + - pattern-regex: (?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.lob-api-key.lob-api-key languages: - - javascript - - typescript - message: The application accepts potentially user-controlled input `$PROP` which can control the location of the current window context. This can lead two types of vulnerabilities open-redirection and Cross-Site-Scripting (XSS) with JavaScript URIs. It is recommended to validate user-controllable input before allowing it to control the redirection. + - regex + message: A gitleaks lob-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.5.1 Insecue Redirect - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - browser - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: location.href = $SINK - - pattern: $THIS. ... .location.href = $SINK - - pattern: location.replace($SINK) - - pattern: $THIS. ... .location.replace($SINK) - - pattern: location = $SINK - - pattern: $WINDOW. ... .location = $SINK - - focus-metavariable: $SINK - - metavariable-pattern: - metavariable: $SINK - patterns: - - pattern-not: | - "..." + $VALUE - - pattern-not: | - `...${$VALUE}` - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $PROP = new URLSearchParams($WINDOW. ... .location.search).get('...') - ... - - pattern-inside: | - $PROP = new URLSearchParams(location.search).get('...') - ... - - pattern-inside: | - $PROP = new URLSearchParams($WINDOW. ... .location.hash.substring(1)).get('...') - ... - - pattern-inside: | - $PROP = new URLSearchParams(location.hash.substring(1)).get('...') - ... - - pattern: $PROP - - patterns: - - pattern-either: - - pattern-inside: | - $PROPS = new URLSearchParams($WINDOW. ... .location.search) - ... - - pattern-inside: | - $PROPS = new URLSearchParams(location.search) - ... - - pattern-inside: | - $PROPS = new URLSearchParams($WINDOW. ... .location.hash.substring(1)) - ... - - pattern-inside: | - $PROPS = new URLSearchParams(location.hash.substring(1)) - ... - - pattern: $PROPS.get('...') - - patterns: - - pattern-either: - - pattern-inside: | - $PROPS = new URL($WINDOW. ... .location.href) - ... - - pattern-inside: | - $PROPS = new URL(location.href) - ... - - pattern: $PROPS.searchParams.get('...') - - patterns: - - pattern-either: - - pattern-inside: | - $PROPS = new URL($WINDOW. ... .location.href).searchParams.get('...') - ... - - pattern-inside: | - $PROPS = new URL(location.href).searchParams.get('...') - ... - - pattern: $PROPS - severity: WARNING - - id: javascript.browser.security.raw-html-concat.raw-html-concat + - gitleaks + patterns: + - pattern-regex: (?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}((live|test)_[a-f0-9]{35})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.lob-pub-api-key.lob-pub-api-key languages: - - javascript - - typescript - message: User controlled data in a HTML string may result in XSS + - regex + message: A gitleaks lob-pub-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/www-community/attacks/xss/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - browser - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; - ... - - pattern-inside: | - $S = require("sanitize-html") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - $S = new Remarkable() - ... - - pattern: $S.render(...) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: $STRING + $EXPR - - pattern-not: $STRING + "..." - - metavariable-pattern: - language: generic - metavariable: $STRING - patterns: - - pattern: <$TAG ... - - pattern-not: <$TAG ...>...... - - patterns: - - pattern: $EXPR + $STRING - - pattern-not: '"..." + $STRING' - - metavariable-pattern: - language: generic - metavariable: $STRING - patterns: - - pattern: '... |:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}((test|live)_pub_[a-f0-9]{31})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.mailchimp-api-key.mailchimp-api-key languages: - - javascript - - typescript - message: The target origin of the window.postMessage() API is set to "*". This could allow for information disclosure due to the possibility of any origin allowed to receive the message. + - regex + message: A gitleaks mailchimp-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-345: Insufficient Verification of Data Authenticity' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A08:2021 - Software and Data Integrity Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - browser - pattern: $OBJECT.postMessage(...,'*') - severity: WARNING - - id: javascript.chrome-remote-interface.security.audit.chrome-remote-interface-compilescript-injection.chrome-remote-interface-compilescript-injection + - gitleaks + patterns: + - pattern-regex: (?i)(?:MailchimpSDK.initialize|mailchimp)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32}-us\d\d)(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.mailgun-private-api-token.mailgun-private-api-token languages: - - javascript - - typescript - message: If unverified user data can reach the `compileScript` method it can result in Server-Side Request Forgery vulnerabilities + - regex + message: A gitleaks mailgun-private-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/cyrus-and/chrome-remote-interface + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - chrome-remote-interface - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('chrome-remote-interface'); - ... - - pattern-inside: | - import 'chrome-remote-interface'; - ... - - pattern-either: - - pattern: | - $RUNTIME.compileScript({expression: $SINK},...) - - pattern: | - $RUNTIME.evaluate({expression: $SINK},...) - - pattern: | - $PAGE.navigate({url: $SINK},...) - - pattern: | - $RUNTIME.printToPDF({headerTemplate: $SINK},...) - - pattern: | - $RUNTIME.printToPDF({footerTemplate: $SINK},...) - - pattern: | - $PAGE.setDocumentContent({html: $SINK},...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-inside: function ... (..., $ARG,...) {...} - - focus-metavariable: $ARG - severity: WARNING - - id: javascript.deno.security.audit.deno-dangerous-run.deno-dangerous-run + - gitleaks + patterns: + - pattern-regex: (?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(key-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.mailgun-pub-key.mailgun-pub-key languages: - - javascript - - typescript - message: Detected non-literal calls to Deno.run(). This could lead to a command injection vulnerability. + - regex + message: A gitleaks mailgun-pub-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://deno.land/manual/examples/subprocess#simple-example + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - deno - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - Deno.run({cmd: [$INPUT,...]},...) - - pattern: | - Deno.run({cmd: ["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$INPUT,...]},...) - - patterns: - - pattern: | - Deno.run({cmd: [$CMD,"-c",$INPUT,...]},...) - - pattern-inside: | - $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/" - ... - - focus-metavariable: $INPUT - pattern-sources: - - patterns: - - pattern-inside: function ... (..., $ARG,...) {...} - - focus-metavariable: $ARG - severity: ERROR - - id: javascript.express.security.audit.express-check-directory-listing.express-check-directory-listing + - gitleaks + patterns: + - pattern-regex: (?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(pubkey-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.mailgun-signing-key.mailgun-signing-key languages: - - javascript - - typescript - message: Directory listing/indexing is enabled, which may lead to disclosure of sensitive directories and files. It is recommended to disable directory listing unless it is a public resource. If you need directory listing, ensure that sensitive files are inaccessible when querying the resource. + - regex + message: A gitleaks mailgun-signing-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-548: Exposure of Information Through Directory Listing' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: HIGH + likelihood: LOW owasp: - - A06:2017 - Security Misconfiguration - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://www.npmjs.com/package/serve-index - - https://www.acunetix.com/blog/articles/directory-listing-information-disclosure/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - options: - interfile: true + - gitleaks patterns: - - pattern-either: - - pattern: | - $APP.use(require('serve-index')(...)) - - patterns: - - pattern-either: - - pattern-inside: | - $SERVEINDEX = require('serve-index') - ... - - pattern-inside: | - import $SERVEINDEX from 'serve-index' - ... - - pattern-inside: | - import * as $SERVEINDEX from 'serve-index' - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $SERVEINDEX(...) - ... - - pattern: | - $VALUE(...) - - pattern: | - $APP.use(..., $SERVEINDEX(...), ...) - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-default-name + - pattern-regex: (?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.mapbox-api-token.mapbox-api-token languages: - - javascript - - typescript - message: 'Don’t use the default session cookie name Using the default session cookie name can open your app to attacks. The security issue posed is similar to X-Powered-By: a potential attacker can use it to fingerprint the server and target attacks accordingly.' + - regex + message: A gitleaks mapbox-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-522: Insufficiently Protected Credentials' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true - impact: LOW - likelihood: HIGH + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express + - gitleaks patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {name:...} ...>,...) - - pattern-not-inside: | - $OPTS = <... {name:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.name = ...; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-secure + - pattern-regex: (?i)(?:mapbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(pk\.[a-z0-9]{60}\.[a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.mattermost-access-token.mattermost-access-token languages: - - javascript - - typescript - message: 'Default session middleware settings: `secure` not set. It ensures the browser only sends the cookie over HTTPS.' + - regex + message: A gitleaks mattermost-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-522: Insufficiently Protected Credentials' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true - impact: LOW - likelihood: HIGH + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express + - gitleaks patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{secure:true}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{secure:true}} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {secure:true} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {secure:true} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.secure = true; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.secure = true; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-httponly + - pattern-regex: (?i)(?:mattermost)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{26})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.messagebird-api-token.messagebird-api-token languages: - - javascript - - typescript - message: 'Default session middleware settings: `httpOnly` not set. It ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks.' + - regex + message: A gitleaks messagebird-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-522: Insufficiently Protected Credentials' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true - impact: LOW - likelihood: HIGH + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express + - gitleaks patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{httpOnly:true}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{httpOnly:true}} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {httpOnly:true} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {httpOnly:true} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.httpOnly = true; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.httpOnly = true; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-domain + - pattern-regex: (?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.messagebird-client-id.messagebird-client-id languages: - - javascript - - typescript - message: 'Default session middleware settings: `domain` not set. It indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.' + - regex + message: A gitleaks messagebird-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-522: Insufficiently Protected Credentials' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true - impact: LOW - likelihood: HIGH + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express + - gitleaks patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{domain:...}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{domain:...}} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {domain:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {domain:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.domain = ...; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.domain = ...; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-path + - pattern-regex: (?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.microsoft-teams-webhook.microsoft-teams-webhook languages: - - javascript - - typescript - message: 'Default session middleware settings: `path` not set. It indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request.' + - regex + message: A gitleaks microsoft-teams-webhook was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-522: Insufficiently Protected Credentials' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true - impact: LOW - likelihood: HIGH + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express + - gitleaks patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{path:...}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{path:...}} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {path:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {path:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.path = ...; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.path = ...; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-expires + - pattern-regex: https:\/\/[a-z0-9]+\.webhook\.office\.com\/webhookb2\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12} + severity: INFO + - id: generic.secrets.gitleaks.netlify-access-token.netlify-access-token languages: - - javascript - - typescript - message: 'Default session middleware settings: `expires` not set. Use it to set expiration date for persistent cookies.' + - regex + message: A gitleaks netlify-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-522: Insufficiently Protected Credentials' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true - impact: LOW - likelihood: HIGH + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express + - gitleaks patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{expires:...}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{expires:...}} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {expires:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {expires:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.expires = ...; - ... - $SESSION($OPTS,...); - - pattern-not-inside: |- - $OPTS = ...; - ... - $OPTS.cookie.expires = ...; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-jwt-not-revoked.express-jwt-not-revoked + - pattern-regex: (?i)(?:netlify)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40,46})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.new-relic-browser-api-token.new-relic-browser-api-token languages: - - javascript - - typescript - message: No token revoking configured for `express-jwt`. A leaked token could still be used and unable to be revoked. Consider using function as the `isRevoked` option. + - regex + message: A gitleaks new-relic-browser-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 3.5.3 Insecue Stateless Session Tokens - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-522: Insufficiently Protected Credentials' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://github.com/goldbergyoni/nodebestpractices/blob/master/sections/security/expirejwt.md + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express + - gitleaks patterns: - - pattern-inside: | - $JWT = require('express-jwt'); - ... - - pattern: $JWT(...) - - pattern-not-inside: $JWT(<... {isRevoked:...} ...>,...) - - pattern-not-inside: |- - $OPTS = <... {isRevoked:...} ...>; - ... - $JWT($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-libxml-noent.express-libxml-noent + - pattern-regex: (?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRJS-[a-f0-9]{19})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.new-relic-insert-key.new-relic-insert-key languages: - - javascript - - typescript - message: The libxml library processes user-input with the `noent` attribute is set to `true` which can lead to being vulnerable to XML External Entities (XXE) type attacks. It is recommended to set `noent` to `false` when using this feature to ensure you are protected. + - regex + message: A gitleaks new-relic-insert-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - interfile: true - likelihood: HIGH + impact: MEDIUM + likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - options: - interfile: true - pattern-sinks: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - $XML = require('$IMPORT') - ... - - pattern-inside: | - import $XML from '$IMPORT' - ... - - pattern-inside: | - import * as $XML from '$IMPORT' - ... - - metavariable-regex: - metavariable: $IMPORT - regex: ^(libxmljs|libxmljs2)$ - - pattern-inside: $XML.$FUNC($QUERY, {...,noent:true,...}) - - metavariable-regex: - metavariable: $FUNC - regex: ^(parseXmlString|parseXml)$ - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - pattern: $REQ.files.$ANYTHING.data.toString('utf8') - - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - pattern: files.$ANYTHING.data.toString('utf8') - - pattern: files.$ANYTHING['data'].toString('utf8') - severity: ERROR - - id: javascript.express.security.audit.express-open-redirect.express-open-redirect + - gitleaks + patterns: + - pattern-regex: (?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRII-[a-z0-9-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.new-relic-user-api-id.new-relic-user-api-id languages: - - javascript - - typescript - message: The application redirects to a URL specified by user-supplied input `$REQ` that is not validated. This could redirect users to malicious locations. Consider using an allow-list approach to validate URLs, or warn users they are being redirected to a third-party website. + - regex + message: A gitleaks new-relic-user-api-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - options: - symbolic_propagation: true - taint_unify_mvars: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $RES.redirect("$HTTP"+$REQ. ... .$VALUE) - - pattern: $RES.redirect("$HTTP"+$REQ. ... .$VALUE + $...A) - - pattern: $RES.redirect(`$HTTP${$REQ. ... .$VALUE}...`) - - pattern: $RES.redirect("$HTTP"+$REQ.$VALUE[...]) - - pattern: $RES.redirect("$HTTP"+$REQ.$VALUE[...] + $...A) - - pattern: $RES.redirect(`$HTTP${$REQ.$VALUE[...]}...`) - - metavariable-regex: - metavariable: $HTTP - regex: ^https?:\/\/$ - - pattern-either: - - pattern: $REQ. ... .$VALUE - - patterns: - - pattern-either: - - pattern: $RES.redirect($REQ. ... .$VALUE) - - pattern: $RES.redirect($REQ. ... .$VALUE + $...A) - - pattern: $RES.redirect(`${$REQ. ... .$VALUE}...`) - - pattern: $REQ. ... .$VALUE - - patterns: - - pattern-either: - - pattern: $RES.redirect($REQ.$VALUE['...']) - - pattern: $RES.redirect($REQ.$VALUE['...'] + $...A) - - pattern: $RES.redirect(`${$REQ.$VALUE['...']}...`) - - pattern: $REQ.$VALUE - - patterns: - - pattern-either: - - pattern-inside: | - $ASSIGN = $REQ. ... .$VALUE - ... - - pattern-inside: | - $ASSIGN = $REQ.$VALUE['...'] - ... - - pattern-inside: | - $ASSIGN = $REQ. ... .$VALUE + $...A - ... - - pattern-inside: "$ASSIGN = $REQ.$VALUE['...'] + $...A\n... \n" - - pattern-inside: | - $ASSIGN = `${$REQ. ... .$VALUE}...` - ... - - pattern-inside: "$ASSIGN = `${$REQ.$VALUE['...']}...`\n... \n" - - pattern-either: - - pattern: $RES.redirect($ASSIGN) - - pattern: $RES.redirect($ASSIGN + $...FOO) - - pattern: $RES.redirect(`${$ASSIGN}...`) - - focus-metavariable: $ASSIGN - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.audit.express-path-join-resolve-traversal.express-path-join-resolve-traversal + - gitleaks + patterns: + - pattern-regex: (?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.new-relic-user-api-key.new-relic-user-api-key languages: - - javascript - - typescript - message: Possible writing outside of the destination, make sure that the target path is nested in the intended destination + - regex + message: A gitleaks new-relic-user-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/www-community/attacks/Path_Traversal + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - - node.js - mode: taint - pattern-sanitizers: - - pattern: $Y.replace(...) - - pattern: $Y.indexOf(...) - - pattern: | - function ... (...) { - ... - <... $Y.indexOf(...) ...> - ... - } - - patterns: - - pattern: $FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: sanitize - pattern-sinks: - - patterns: - - focus-metavariable: $SINK - - pattern-either: - - pattern-inside: | - $PATH = require('path'); - ... - - pattern-inside: | - import $PATH from 'path'; - ... - - pattern-either: - - pattern: $PATH.join(...,$SINK,...) - - pattern: $PATH.resolve(...,$SINK,...) - - patterns: - - focus-metavariable: $SINK - - pattern-inside: | - import 'path'; - ... - - pattern-either: - - pattern: path.join(...,$SINK,...) - - pattern: path.resolve(...,$SINK,...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.audit.express-res-sendfile.express-res-sendfile + - gitleaks + patterns: + - pattern-regex: (?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRAK-[a-z0-9]{27})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.npm-access-token.npm-access-token languages: - - javascript - - typescript - message: The application processes user-input, this is passed to res.sendFile which can allow an attacker to arbitrarily read files on the system through path traversal. It is recommended to perform input validation in addition to canonicalizing the path. This allows you to validate the path against the intended directory it should be accessing. + - regex + message: A gitleaks npm-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-73: External Control of File Name or Path' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A04:2021 - Insecure Design + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $RES.$METH($QUERY,...) - - pattern-not-inside: $RES.$METH($QUERY,$OPTIONS) - - metavariable-regex: - metavariable: $METH - regex: ^(sendfile|sendFile)$ - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - function ... (...,$REQ: $TYPE, ...) {...} - - metavariable-regex: - metavariable: $TYPE - regex: ^(string|String) - severity: WARNING - - id: javascript.express.security.audit.express-session-hardcoded-secret.express-session-hardcoded-secret + - gitleaks + patterns: + - pattern-regex: (?i)\b(npm_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.nytimes-access-token.nytimes-access-token languages: - - javascript - - typescript - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - regex + message: A gitleaks nytimes-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - interfile: true - likelihood: HIGH + impact: MEDIUM + likelihood: LOW owasp: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - - secrets - options: - interfile: true + - gitleaks patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern-inside: | - import $SESSION from 'express-session' - ... - - pattern-inside: | - import {..., $SESSION, ...} from 'express-session' - ... - - pattern-inside: | - import * as $SESSION from 'express-session' - ... - - patterns: - - pattern-either: - - pattern-inside: $APP.use($SESSION({...})) - - pattern: | - $SECRET = $VALUE - ... - $APP.use($SESSION($SECRET)) - - pattern: | - secret: '$Y' - severity: WARNING - - id: javascript.express.security.audit.express-ssrf.express-ssrf + - pattern-regex: (?i)(?:nytimes|new-york-times,|newyorktimes)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.okta-access-token.okta-access-token languages: - - javascript - - typescript - message: 'The following request $REQUEST.$METHOD() was found to be crafted from user-input `$REQ` which can lead to Server-Side Request Forgery (SSRF) vulnerabilities. It is recommended where possible to not allow user-input to craft the base request, but to be treated as part of the path or query parameter. When user-input is necessary to craft the request, it is recommeneded to follow OWASP best practices to prevent abuse. ' + - regex + message: A gitleaks okta-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + impact: MEDIUM + likelihood: LOW owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - options: - taint_unify_mvars: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $REQUEST = require('request') - ... - - pattern-inside: | - import * as $REQUEST from 'request' - ... - - pattern-inside: | - import $REQUEST from 'request' - ... - - pattern-either: - - pattern: $REQUEST.$METHOD("$HTTP"+$REQ. ... .$VALUE) - - pattern: $REQUEST.$METHOD("$HTTP"+$REQ. ... .$VALUE + $...A) - - pattern: $REQUEST.$METHOD(`$HTTP${$REQ. ... .$VALUE}...`) - - pattern: $REQUEST.$METHOD("$HTTP"+$REQ.$VALUE[...]) - - pattern: $REQUEST.$METHOD("$HTTP"+$REQ.$VALUE[...] + $...A) - - pattern: $REQUEST.$METHOD(`$HTTP${$REQ.$VALUE[...]}...`) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|patch|del|head|delete)$ - - metavariable-regex: - metavariable: $HTTP - regex: ^(https?:\/\/|//)$ - - pattern-either: - - pattern: $REQ. ... .$VALUE - - patterns: - - pattern-either: - - pattern-inside: | - $REQUEST = require('request') - ... - - pattern-inside: | - import * as $REQUEST from 'request' - ... - - pattern-inside: | - import $REQUEST from 'request' - ... - - pattern-either: - - pattern: $REQUEST.$METHOD($REQ. ... .$VALUE,...) - - pattern: $REQUEST.$METHOD($REQ. ... .$VALUE + $...A,...) - - pattern: $REQUEST.$METHOD(`${$REQ. ... .$VALUE}...`,...) - - pattern: $REQ. ... .$VALUE - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|patch|del|head|delete)$ - - patterns: - - pattern-either: - - pattern-inside: | - $REQUEST = require('request') - ... - - pattern-inside: | - import * as $REQUEST from 'request' - ... - - pattern-inside: | - import $REQUEST from 'request' - ... - - pattern-either: - - pattern: $REQUEST.$METHOD($REQ.$VALUE['...'],...) - - pattern: $REQUEST.$METHOD($REQ.$VALUE['...'] + $...A,...) - - pattern: $REQUEST.$METHOD(`${$REQ.$VALUE['...']}...`,...) - - pattern: $REQ.$VALUE - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|patch|del|head|delete)$ - - patterns: - - pattern-either: - - pattern-inside: | - $REQUEST = require('request') - ... - - pattern-inside: | - import * as $REQUEST from 'request' - ... - - pattern-inside: | - import $REQUEST from 'request' - ... - - pattern-either: - - pattern-inside: | - $ASSIGN = $REQ. ... .$VALUE - ... - - pattern-inside: | - $ASSIGN = $REQ. ... .$VALUE['...'] - ... - - pattern-inside: | - $ASSIGN = $REQ. ... .$VALUE + $...A - ... - - pattern-inside: "$ASSIGN = $REQ. ... .$VALUE['...'] + $...A\n... \n" - - pattern-inside: | - $ASSIGN = `${$REQ. ... .$VALUE}...` - ... - - pattern-inside: "$ASSIGN = `${$REQ. ... .$VALUE['...']}...`\n... \n" - - patterns: - - pattern-either: - - pattern-inside: | - $ASSIGN = "$HTTP"+ $REQ. ... .$VALUE - ... - - pattern-inside: | - $ASSIGN = "$HTTP"+$REQ. ... .$VALUE + $...A - ... - - pattern-inside: | - $ASSIGN = "$HTTP"+$REQ.$VALUE[...] - ... - - pattern-inside: | - $ASSIGN = "$HTTP"+$REQ.$VALUE[...] + $...A - ... - - pattern-inside: | - $ASSIGN = `$HTTP${$REQ.$VALUE[...]}...` - ... - - metavariable-regex: - metavariable: $HTTP - regex: ^(https?:\/\/|//)$ - - pattern-either: - - pattern: $REQUEST.$METHOD($ASSIGN,...) - - pattern: $REQUEST.$METHOD($ASSIGN + $...FOO,...) - - pattern: $REQUEST.$METHOD(`${$ASSIGN}...`,...) - - patterns: - - pattern-either: - - pattern: $REQUEST.$METHOD("$HTTP"+$ASSIGN,...) - - pattern: $REQUEST.$METHOD("$HTTP"+$ASSIGN + $...A,...) - - pattern: $REQUEST.$METHOD(`$HTTP${$ASSIGN}...`,...) - - metavariable-regex: - metavariable: $HTTP - regex: ^(https?:\/\/|//)$ - - pattern: $ASSIGN - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|patch|del|head|delete)$ - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, ...) {...} - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,...) => - {...} - - pattern-inside: | - ({ $REQ }: $EXPRESS.Request,...) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.audit.express-third-party-object-deserialization.express-third-party-object-deserialization + - gitleaks + patterns: + - pattern-regex: (?i)(?:okta)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{42})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.openai-api-key.openai-api-key languages: - - javascript - - typescript - message: The following function call $SER.$FUNC accepts user controlled data which can result in Remote Code Execution (RCE) through Object Deserialization. It is recommended to use secure data processing alternatives such as JSON.parse() and Buffer.from(). + - regex + message: A gitleaks openai-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-502: Deserialization of Untrusted Data' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - interfile: true - likelihood: HIGH + impact: MEDIUM + likelihood: LOW owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html - source_rule_url: - - https://github.com/ajinabraham/njsscan/blob/75bfbeb9c8d72999e4d527dfa2548f7f0f3cc48a/njsscan/rules/semantic_grep/eval/eval_deserialize.yaml + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - options: - interfile: true - pattern-sinks: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - $SER = require('$IMPORT') - ... - - pattern-inside: | - import $SER from '$IMPORT' - ... - - pattern-inside: | - import * as $SER from '$IMPORT' - ... - - metavariable-regex: - metavariable: $IMPORT - regex: ^(node-serialize|serialize-to-js)$ - - pattern: $SER.$FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: ^(unserialize|deserialize)$ - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - pattern: $REQ.files.$ANYTHING.data.toString('utf8') - - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - pattern: files.$ANYTHING.data.toString('utf8') - - pattern: files.$ANYTHING['data'].toString('utf8') - severity: WARNING - - id: javascript.express.security.audit.express-xml2json-xxe-event.express-xml2json-xxe-event + - gitleaks + patterns: + - pattern-regex: (?i)\b(sk-[a-zA-Z0-9]{20}T3BlbkFJ[a-zA-Z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.plaid-api-token.plaid-api-token languages: - - javascript - - typescript - message: Xml Parser is used inside Request Event. Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities + - regex + message: A gitleaks plaid-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + impact: MEDIUM + likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://www.npmjs.com/package/xml2json + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('xml2json'); - ... - - pattern-inside: | - import 'xml2json'; - ... - - pattern: $REQ.on('...', function(...) { ... $EXPAT.toJson($INPUT,...); ... }) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.audit.res-render-injection.res-render-injection + - gitleaks + patterns: + - pattern-regex: (?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(access-(?:sandbox|development|production)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.plaid-client-id.plaid-client-id languages: - - javascript - - typescript - message: User controllable data `$REQ` enters `$RES.render(...)` this can lead to the loading of other HTML/templating pages that they may not be authorized to render. An attacker may attempt to use directory traversal techniques e.g. `../folder/index` to access other HTML pages on the file system. Where possible, do not allow users to define what should be loaded in $RES.render or use an allow list for the existing application. + - regex + message: A gitleaks plaid-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-706: Use of Incorrectly-Resolved Name or Reference' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - http://expressjs.com/en/4x/api.html#res.render + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $RES.render($SINK, ...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.audit.xss.direct-response-write.direct-response-write + - gitleaks + patterns: + - pattern-regex: (?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.plaid-secret-key.plaid-secret-key languages: - - javascript - - typescript - message: Detected directly writing to a Response object from user-defined input. This bypasses any HTML escaping and may expose your application to a Cross-Site-scripting (XSS) vulnerability. Instead, use 'resp.render()' to render safely escaped HTML. + - regex + message: A gitleaks plaid-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - vulnerability_class: - - Cross-Site-Scripting (XSS) - mode: taint - options: - interfile: true - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; - ... - - pattern-inside: | - $S = require("sanitize-html") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - $S = new Remarkable() - ... - - pattern: $S.render(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'express-xss-sanitizer'; - ... - - pattern-inside: | - import * as $S from "express-xss-sanitizer"; - ... - - pattern-inside: | - const { ..., $S, ... } = require('express-xss-sanitizer'); - ... - - pattern-inside: | - var { ..., $S, ... } = require('express-xss-sanitizer'); - ... - - pattern-inside: | - let { ...,$S,... } = require('express-xss-sanitizer'); - ... - - pattern-inside: | - $S = require("express-xss-sanitizer") - ... - - pattern: $S(...) - - patterns: - - pattern: $RES. ... .type('$F'). ... .send(...) - - metavariable-regex: - metavariable: $F - regex: (?!.*text/html) - - patterns: - - pattern-inside: | - $X = [...]; - ... - - pattern: | - if(<... !$X.includes($SOURCE)...>) { - ... - return ... - } - ... - - pattern: $SOURCE - pattern-sinks: - - patterns: - - pattern-inside: function ... (..., $RES,...) {...} - - pattern-either: - - pattern: $RES.write($ARG) - - pattern: $RES.send($ARG) - - pattern-not: $RES. ... .set('...'). ... .send($ARG) - - pattern-not: $RES. ... .type('...'). ... .send($ARG) - - pattern-not-inside: $RES.$METHOD({ ... }) - - focus-metavariable: $ARG - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options) - - pattern-not-inside: | - function ... ($REQ, $RES) { - ... - $RES.$SET('Content-Type', '$TYPE') - } - - pattern-not-inside: | - $APP.$METHOD(..., function $FUNC($REQ, $RES) { - ... - $RES.$SET('Content-Type', '$TYPE') - }) - - pattern-not-inside: | - function ... ($REQ, $RES, $NEXT) { - ... - $RES.$SET('Content-Type', '$TYPE') - } - - pattern-not-inside: | - function ... ($REQ, $RES) { - ... - $RES.set('$TYPE') - } - - pattern-not-inside: | - $APP.$METHOD(..., function $FUNC($REQ, $RES) { - ... - $RES.set('$TYPE') - }) - - pattern-not-inside: | - function ... ($REQ, $RES, $NEXT) { - ... - $RES.set('$TYPE') - } - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - pattern-not-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - { - ... - $RES.$SET('Content-Type', '$TYPE') - } - - pattern-not-inside: | - ({ $REQ }: Request,$RES: Response) => { - ... - $RES.$SET('Content-Type', '$TYPE') - } - - pattern-not-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - { - ... - $RES.set('$TYPE') - } - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: body - severity: WARNING - - id: javascript.express.security.cors-misconfiguration.cors-misconfiguration + - gitleaks + patterns: + - pattern-regex: (?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.planetscale-api-token.planetscale-api-token languages: - - javascript - - typescript - message: By letting user input control CORS parameters, there is a risk that software does not properly verify that the source of data or communication is valid. Use literal values for CORS settings. + - regex + message: A gitleaks planetscale-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-346: Origin Validation Error' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - A07:2021 - Identification and Authentication Failures references: - - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $RES.set($HEADER, $X) - - pattern: $RES.header($HEADER, $X) - - pattern: $RES.setHeader($HEADER, $X) - - pattern: | - $RES.set({$HEADER: $X}, ...) - - pattern: | - $RES.writeHead($STATUS, {$HEADER: $X}, ...) - - focus-metavariable: $X - - metavariable-regex: - metavariable: $HEADER - regex: .*(Access-Control-Allow-Origin|access-control-allow-origin).* - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.express-expat-xxe.express-expat-xxe + - gitleaks + patterns: + - pattern-regex: (?i)\b(pscale_tkn_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.planetscale-oauth-token.planetscale-oauth-token languages: - - javascript - - typescript - message: Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities. + - regex + message: A gitleaks planetscale-oauth-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: MEDIUM + likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/astro/node-expat + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $XML = require('node-expat') - ... - - pattern-inside: | - import $XML from 'node-expat' - ... - - pattern-inside: | - import * as $XML from 'node-expat' - ... - - pattern-either: - - pattern-inside: | - $PARSER = new $XML.Parser(...); - ... - - pattern-either: - - pattern: $PARSER.parse($QUERY) - - pattern: $PARSER.write($QUERY) - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-insecure-template-usage.express-insecure-template-usage + - gitleaks + patterns: + - pattern-regex: (?i)\b(pscale_oauth_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.planetscale-password.planetscale-password languages: - - javascript - - typescript - message: User data from `$REQ` is being compiled into the template, which can lead to a Server Side Template Injection (SSTI) vulnerability. + - regex + message: A gitleaks planetscale-password was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection - - A01:2017 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html - source_rule_url: - - https://github.com/github/codeql/blob/2ba2642c7ab29b9eedef33bcc2b8cd1d203d0c10/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - javascript - - typescript - - express - - pug - - jade - - dot - - ejs - - nunjucks - - lodash - - handlbars - - mustache - - hogan.js - - eta - - squirrelly - mode: taint - options: - interfile: true - pattern-propagators: - - from: $E - pattern: $MODEL.$FIND($E).then((...,$S,...)=>{...}) - to: $S - pattern-sinks: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('pug') - ... - - pattern-inside: | - import * as $PUG from 'pug' - ... - - pattern-inside: | - $PUG = require('jade') - ... - - pattern-inside: | - import * as $PUG from 'jade' - ... - - pattern-either: - - pattern: $PUG.compile(...) - - pattern: $PUG.compileClient(...) - - pattern: $PUG.compileClientWithDependenciesTracked(...) - - pattern: $PUG.render(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('dot') - ... - - pattern-inside: | - import * as $PUG from 'dot' - ... - - pattern-either: - - pattern: $PUG.template(...) - - pattern: $PUG.compile(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('ejs') - ... - - pattern-inside: | - import * as $PUG from 'ejs' - ... - - pattern-either: - - pattern: $PUG.render(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('nunjucks') - ... - - pattern-inside: | - import * as $PUG from 'nunjucks' - ... - - pattern-either: - - pattern: $PUG.renderString(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('lodash') - ... - - pattern-inside: | - import * as $PUG from 'lodash' - ... - - pattern-either: - - pattern: $PUG.template(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('mustache') - ... - - pattern-inside: | - import * as $PUG from 'mustache' - ... - - pattern-inside: | - $PUG = require('eta') - ... - - pattern-inside: | - import * as $PUG from 'eta' - ... - - pattern-inside: | - $PUG = require('squirrelly') - ... - - pattern-inside: | - import * as $PUG from 'squirrelly' - ... - - pattern-either: - - pattern: $PUG.render(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('hogan.js') - ... - - pattern-inside: | - import * as $PUG from 'hogan.js' - ... - - pattern-inside: | - $PUG = require('handlebars') - ... - - pattern-inside: | - import * as $PUG from 'handlebars' - ... - - pattern-either: - - pattern: $PUG.compile(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.express-jwt-hardcoded-secret.express-jwt-hardcoded-secret + - gitleaks + patterns: + - pattern-regex: (?i)\b(pscale_pw_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.postman-api-token.postman-api-token languages: - - javascript - - typescript - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - regex + message: A gitleaks postman-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: HIGH + likelihood: LOW owasp: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - express - - secrets - options: - interfile: true + - gitleaks patterns: - - pattern-either: - - pattern-inside: | - $JWT = require('express-jwt'); - ... - - pattern-inside: | - import $JWT from 'express-jwt'; - ... - - pattern-inside: | - import * as $JWT from 'express-jwt'; - ... - - pattern-inside: | - import { ..., $JWT, ... } from 'express-jwt'; - ... - - pattern-either: - - pattern: | - $JWT({...,secret: "$Y",...},...) - - pattern: | - $OPTS = "$Y"; - ... - $JWT({...,secret: $OPTS},...); - - focus-metavariable: $Y - severity: WARNING - - id: javascript.express.security.express-phantom-injection.express-phantom-injection + - pattern-regex: (?i)\b(PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.prefect-api-token.prefect-api-token languages: - - javascript - - typescript - message: If unverified user data can reach the `phantom` methods it can result in Server-Side Request Forgery vulnerabilities + - regex + message: A gitleaks prefect-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) + - A07:2021 - Identification and Authentication Failures references: - - https://phantomjs.org/page-automation.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('phantom'); - ... - - pattern-inside: | - import 'phantom'; - ... - - pattern-either: - - pattern: $PAGE.open($SINK,...) - - pattern: $PAGE.setContent($SINK,...) - - pattern: $PAGE.openUrl($SINK,...) - - pattern: $PAGE.evaluateJavaScript($SINK,...) - - pattern: $PAGE.property("content",$SINK,...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-puppeteer-injection.express-puppeteer-injection + - gitleaks + patterns: + - pattern-regex: (?i)\b(pnu_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.private-key.private-key languages: - - javascript - - typescript - message: If unverified user data can reach the `puppeteer` methods it can result in Server-Side Request Forgery vulnerabilities + - regex + message: A gitleaks private-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) + - A07:2021 - Identification and Authentication Failures references: - - https://pptr.dev/api/puppeteer.page + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('puppeteer'); - ... - - pattern-inside: | - import 'puppeteer'; - ... - - pattern-either: - - pattern: $PAGE.goto($SINK,...) - - pattern: $PAGE.setContent($SINK,...) - - pattern: $PAGE.evaluate($SINK,...) - - pattern: $PAGE.evaluate($CODE,$SINK,...) - - pattern: $PAGE.evaluateHandle($SINK,...) - - pattern: $PAGE.evaluateHandle($CODE,$SINK,...) - - pattern: $PAGE.evaluateOnNewDocument($SINK,...) - - pattern: $PAGE.evaluateOnNewDocument($CODE,$SINK,...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-sandbox-injection.express-sandbox-code-injection + - gitleaks + patterns: + - pattern-regex: (?i)-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY( BLOCK)?-----[\s\S-]*KEY( BLOCK)?---- + severity: INFO + - id: generic.secrets.gitleaks.pulumi-api-token.pulumi-api-token languages: - - javascript - - typescript - message: Make sure that unverified user data can not reach `sandbox`. + - regex + message: A gitleaks pulumi-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - $SANDBOX = require('sandbox'); - ... - - pattern-either: - - patterns: - - pattern-inside: | - $S = new $SANDBOX(...); - ... - - pattern: | - $S.run(...) - - pattern: | - new $SANDBOX($OPTS).run(...) - - pattern: new $SANDBOX().run(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-vm-injection.express-vm-injection + - gitleaks + patterns: + - pattern-regex: (?i)\b(pul-[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.pypi-upload-token.pypi-upload-token languages: - - javascript - - typescript - message: Make sure that unverified user data can not reach `$VM`. + - regex + message: A gitleaks pypi-upload-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - $VM = require('vm'); - ... - - pattern-either: - - pattern: | - $VM.runInContext(...) - - pattern: | - $VM.runInNewContext(...) - - pattern: | - $VM.compileFunction(...) - - pattern: | - $VM.runInThisContext(...) - - pattern: new $VM.Script(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-vm2-injection.express-vm2-injection + - gitleaks + patterns: + - pattern-regex: pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000} + severity: INFO + - id: generic.secrets.gitleaks.rapidapi-access-token.rapidapi-access-token languages: - - javascript - - typescript - message: Make sure that unverified user data can not reach `vm2`. + - regex + message: A gitleaks rapidapi-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - require('vm2') - ... - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - $VM = new VM(...) - ... - - pattern-inside: | - $VM = new NodeVM(...) - ... - - pattern: | - $VM.run(...) - - pattern: | - new VM(...).run(...) - - pattern: | - new NodeVM(...).run(...) - - pattern: | - new VMScript(...) - - pattern: | - new VM(...) - - pattern: new NodeVM(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.express-xml2json-xxe.express-xml2json-xxe + - gitleaks + patterns: + - pattern-regex: (?i)(?:rapidapi)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{50})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.readme-api-token.readme-api-token languages: - - javascript - - typescript - message: Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities + - regex + message: A gitleaks readme-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://www.npmjs.com/package/xml2json + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('xml2json'); - ... - - pattern-inside: | - import 'xml2json'; - ... - - pattern: $EXPAT.toJson($SINK,...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - pattern: $REQ.files.$ANYTHING.data.toString('utf8') - - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - pattern: files.$ANYTHING.data.toString('utf8') - - pattern: files.$ANYTHING['data'].toString('utf8') - severity: ERROR - - id: javascript.express.security.injection.raw-html-format.raw-html-format + - gitleaks + patterns: + - pattern-regex: (?i)\b(rdme_[a-z0-9]{70})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.rubygems-api-token.rubygems-api-token languages: - - javascript - - typescript - message: User data flows into the host portion of this manually-constructed HTML. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. Consider using a sanitization library such as DOMPurify to sanitize the HTML within. + - regex + message: A gitleaks rubygems-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: '"$HTMLSTR" + $EXPR' - - pattern: '"$HTMLSTR".concat(...)' - - pattern: util.format($HTMLSTR, ...) - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - - patterns: - - pattern: | - `...` - - pattern-regex: | - .*<\w+.* - requires: (EXPRESS and not CLEAN) or (EXPRESSTS and not CLEAN) - pattern-sources: - - label: EXPRESS - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - label: EXPRESSTS - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - by-side-effect: true - label: CLEAN - patterns: - - pattern-either: - - pattern: $A($SOURCE) - - pattern: $SANITIZE. ... .$A($SOURCE) - - pattern: $A. ... .$SANITIZE($SOURCE) - - focus-metavariable: $SOURCE - - metavariable-regex: - metavariable: $A - regex: (?i)(.*valid|.*sanitiz) - severity: WARNING - - id: javascript.express.security.injection.tainted-sql-string.tainted-sql-string + - gitleaks + patterns: + - pattern-regex: (?i)\b(rubygems_[a-f0-9]{48})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.scalingo-api-token.scalingo-api-token languages: - - javascript - - typescript - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + - regex + message: A gitleaks scalingo-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/www-community/attacks/SQL_Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - "$SQLSTR" + $EXPR - - pattern-inside: | - "$SQLSTR".concat($EXPR) - - pattern: util.format($SQLSTR, $EXPR) - - pattern: | - `$SQLSTR${$EXPR}...` - - metavariable-regex: - metavariable: $SQLSTR - regex: .*\b(?i)(select|delete|insert|create|update\s+.+\sset|alter|drop)\b.* - - focus-metavariable: $EXPR - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... (...,$REQ, ...) {...} - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - (...,{ $REQ }: Request,...) => {...} - - pattern-inside: | - (...,{ $REQ }: $EXPRESS.Request,...) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.require-request.require-request + - gitleaks + patterns: + - pattern-regex: \b(tk-us-[a-zA-Z0-9-_]{48})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.sendbird-access-id.sendbird-access-id languages: - - javascript - - typescript - message: If an attacker controls the x in require(x) then they can cause code to load that was not intended to run on the server. + - regex + message: A gitleaks sendbird-access-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-706: Use of Incorrectly-Resolved Name or Reference' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/google/node-sec-roadmap/blob/master/chapter-2/dynamism.md#dynamism-when-you-need-it - source-rule-url: https://nodesecroadmap.fyi/chapter-1/threat-UIR.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern: require($SINK) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.x-frame-options-misconfiguration.x-frame-options-misconfiguration + - gitleaks + patterns: + - pattern-regex: (?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.sendbird-access-token.sendbird-access-token languages: - - javascript - - typescript - message: By letting user input control `X-Frame-Options` header, there is a risk that software does not properly verify whether or not a browser should be allowed to render a page in an `iframe`. + - regex + message: A gitleaks sendbird-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-451: User Interface (UI) Misrepresentation of Critical Information' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A04:2021 - Insecure Design + - A07:2021 - Identification and Authentication Failures references: - - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $RES.set($HEADER, ...) - - pattern: $RES.header($HEADER, ...) - - pattern: $RES.setHeader($HEADER, ...) - - pattern: | - $RES.set({$HEADER: ...}, ...) - - pattern: | - $RES.writeHead($STATUS, {$HEADER: ...}, ...) - - metavariable-regex: - metavariable: $HEADER - regex: .*(X-Frame-Options|x-frame-options).* - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.intercom.security.audit.intercom-settings-user-identifier-without-user-hash.intercom-settings-user-identifier-without-user-hash + - gitleaks + patterns: + - pattern-regex: (?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.sendgrid-api-token.sendgrid-api-token languages: - - js - message: Found an initialization of the Intercom Messenger that identifies a User, but does not specify a `user_hash`.This configuration allows users to impersonate one another. See the Intercom Identity Verification docs for more context https://www.intercom.com/help/en/articles/183-set-up-identity-verification-for-web-and-mobile + - regex + message: A gitleaks sendgrid-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-287: Improper Authentication' - impact: HIGH - likelihood: MEDIUM + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://www.intercom.com/help/en/articles/183-set-up-identity-verification-for-web-and-mobile + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - guardrail + - vuln technology: - - intercom + - gitleaks patterns: - - pattern-either: - - pattern: | - window.intercomSettings = {..., email: $EMAIL, ...}; - - pattern: | - window.intercomSettings = {..., user_id: $USER_ID, ...}; - - pattern: | - Intercom('boot', {..., email: $EMAIL, ...}); - - pattern: | - Intercom('boot', {..., user_id: $USER_ID, ...}); - - pattern: | - $VAR = {..., email: $EMAIL, ...}; - ... - Intercom('boot', $VAR); - - pattern: | - $VAR = {..., user_id: $EMAIL, ...}; - ... - Intercom('boot', $VAR); - - pattern-not: | - window.intercomSettings = {..., user_hash: $USER_HASH, ...}; - - pattern-not: | - Intercom('boot', {..., user_hash: $USER_HASH, ...}); - - pattern-not: | - $VAR = {..., user_hash: $USER_HASH, ...}; - ... - Intercom('boot', $VAR); - severity: WARNING - - id: javascript.jose.security.jwt-hardcode.hardcoded-jwt-secret + - pattern-regex: (?i)\b(SG\.(?i)[a-z0-9=_\-\.]{66})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.sendinblue-api-token.sendinblue-api-token languages: - - javascript - - typescript - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - regex + message: A gitleaks sendinblue-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 3.5.2 Static API keys or secret - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: HIGH + likelihood: LOW owasp: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - jose - - jwt - - secrets - options: - interfile: true - symbolic_propagation: true + - gitleaks patterns: - - pattern-inside: | - $JOSE = require("jose"); - ... - - pattern-either: - - pattern-inside: | - var {JWT} = $JOSE; - ... - - pattern-inside: | - var {JWK, JWT} = $JOSE; - ... - - pattern-inside: | - const {JWT} = $JOSE; - ... - - pattern-inside: | - const {JWK, JWT} = $JOSE; - ... - - pattern-inside: | - let {JWT} = $JOSE; - ... - - pattern-inside: | - let {JWK, JWT} = $JOSE; - ... - - pattern-either: - - pattern: | - JWT.verify($P, "...", ...); - - pattern: | - JWT.sign($P, "...", ...); - - pattern: "JWT.verify($P, JWK.asKey(\"...\"), ...); \n" - - pattern: | - $JWT.sign($P, JWK.asKey("..."), ...); - severity: WARNING - - id: javascript.jose.security.jwt-none-alg.jwt-none-alg + - pattern-regex: (?i)\b(xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.sentry-access-token.sentry-access-token languages: - - javascript - - typescript - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + - regex + message: A gitleaks sentry-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 3.5.3 Insecue Stateless Session Tokens - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - jose - - jwt - pattern-either: - - pattern: | - var $JOSE = require("jose"); - ... - var { JWK, JWT } = $JOSE; - ... - var $T = JWT.verify($P, JWK.None,...); - - pattern: | - var $JOSE = require("jose"); - ... - var { JWK, JWT } = $JOSE; - ... - $T = JWT.verify($P, JWK.None,...); - - pattern: | - var $JOSE = require("jose"); - ... - var { JWK, JWT } = $JOSE; - ... - JWT.verify($P, JWK.None,...); - severity: ERROR - - id: javascript.jsonwebtoken.security.jwt-hardcode.hardcoded-jwt-secret + - gitleaks + patterns: + - pattern-regex: (?i)(?:sentry)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.shippo-api-token.shippo-api-token languages: - - javascript - - typescript - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - regex + message: A gitleaks shippo-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 3.5.2 Static API keys or secret - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - jwt - - javascript - - secrets - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $JWT = require("jsonwebtoken") - ... - - pattern-inside: | - import $JWT from "jsonwebtoken" - ... - - pattern-inside: | - import * as $JWT from "jsonwebtoken" - ... - - pattern-inside: | - import {...,$JWT,...} from "jsonwebtoken" - ... - - pattern-either: - - pattern-inside: | - $JWT.sign($DATA,$VALUE,...); - - pattern-inside: | - $JWT.verify($DATA,$VALUE,...); - - focus-metavariable: $VALUE - pattern-sources: - - patterns: - - pattern: "$X = '...' \n" - - pattern: "$X = '$Y' \n" - - patterns: - - pattern-either: - - pattern-inside: | - $JWT.sign($DATA,"...",...); - - pattern-inside: | - $JWT.verify($DATA,"...",...); - severity: WARNING - - id: javascript.jsonwebtoken.security.jwt-none-alg.jwt-none-alg + - gitleaks + patterns: + - pattern-regex: (?i)\b(shippo_(live|test)_[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.shopify-access-token.shopify-access-token languages: - - javascript - - typescript - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + - regex + message: A gitleaks shopify-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 3.5.3 Insecue Stateless Session Tokens - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: HIGH - likelihood: MEDIUM + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - jwt + - gitleaks patterns: - - pattern-inside: | - $JWT = require("jsonwebtoken"); - ... - - pattern: $JWT.verify($P, $X, {algorithms:[...,'none',...]},...) - severity: ERROR - - id: javascript.jwt-simple.security.jwt-simple-noverify.jwt-simple-noverify + - pattern-regex: shpat_[a-fA-F0-9]{32} + severity: INFO + - id: generic.secrets.gitleaks.shopify-custom-access-token.shopify-custom-access-token languages: - - javascript - - typescript - message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Set 'verify' to `true` before using the token. + - regex + message: A gitleaks shopify-custom-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-287: Improper Authentication' - - 'CWE-345: Insufficient Verification of Data Authenticity' - - 'CWE-347: Improper Verification of Cryptographic Signature' - impact: HIGH - likelihood: MEDIUM + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A05:2021 - Security Misconfiguration - A07:2021 - Identification and Authentication Failures references: - - https://www.npmjs.com/package/jwt-simple - - https://cwe.mitre.org/data/definitions/287 - - https://cwe.mitre.org/data/definitions/345 - - https://cwe.mitre.org/data/definitions/347 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - jwt-simple - - jwt + - gitleaks patterns: - - pattern-inside: | - $JWT = require('jwt-simple'); - ... - - pattern: $JWT.decode($TOKEN, $SECRET, $NOVERIFY, ...) - - metavariable-pattern: - metavariable: $NOVERIFY - patterns: - - pattern-either: - - pattern: | - true - - pattern: | - "..." - severity: ERROR - - id: javascript.lang.security.audit.code-string-concat.code-string-concat + - pattern-regex: shpca_[a-fA-F0-9]{32} + severity: INFO + - id: generic.secrets.gitleaks.shopify-private-app-access-token.shopify-private-app-access-token languages: - - javascript - - typescript - message: Found data from an Express or Next web request flowing to `eval`. If this data is user-controllable this can lead to execution of arbitrary system commands in the context of your application process. Avoid `eval` whenever possible. + - regex + message: A gitleaks shopify-private-app-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - interfile: true - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval - - https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback - - https://www.stackhawk.com/blog/nodejs-command-injection-examples-and-prevention/ - - https://ckarande.gitbooks.io/owasp-nodegoat-tutorial/content/tutorial/a1_-_server_side_js_injection.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - node.js - - Express - - Next.js - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern: | - eval(...) - pattern-sources: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - import { ...,$IMPORT,... } from 'next/router' - ... - - pattern-inside: | - import $IMPORT from 'next/router'; - ... - - pattern-either: - - patterns: - - pattern-inside: | - $ROUTER = $IMPORT() - ... - - pattern-either: - - pattern-inside: | - const { ...,$PROPS,... } = $ROUTER.query - ... - - pattern-inside: | - var { ...,$PROPS,... } = $ROUTER.query - ... - - pattern-inside: | - let { ...,$PROPS,... } = $ROUTER.query - ... - - focus-metavariable: $PROPS - - patterns: - - pattern-inside: | - $ROUTER = $IMPORT() - ... - - pattern: "$ROUTER.query.$VALUE \n" - - patterns: - - pattern: $IMPORT().query.$VALUE - severity: ERROR - - id: javascript.lang.security.audit.sqli.node-knex-sqli.node-knex-sqli + - gitleaks + patterns: + - pattern-regex: shppa_[a-fA-F0-9]{32} + severity: INFO + - id: generic.secrets.gitleaks.shopify-shared-secret.shopify-shared-secret languages: - - javascript - - typescript - message: 'Detected SQL statement that is tainted by `$REQ` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements. An example of parameterized queries like so: `knex.raw(''SELECT $1 from table'', [userinput])` can help prevent SQLi.' + - regex + message: A gitleaks shopify-shared-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://knexjs.org/#Builder-fromRaw - - https://knexjs.org/#Builder-whereRaw - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - - nodejs - - knex - mode: taint - pattern-sanitizers: - - patterns: - - pattern: parseInt(...) - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern-inside: $KNEX.fromRaw($QUERY, ...) - - pattern-inside: $KNEX.whereRaw($QUERY, ...) - - pattern-inside: $KNEX.raw($QUERY, ...) - - pattern-either: - - pattern-inside: | - require('knex') - ... - - pattern-inside: | - import 'knex' - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options) - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - pattern: $REQ.files.$ANYTHING.data.toString('utf8') - - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - pattern: files.$ANYTHING.data.toString('utf8') - - pattern: files.$ANYTHING['data'].toString('utf8') - severity: WARNING - - id: javascript.lang.security.detect-eval-with-expression.detect-eval-with-expression + - gitleaks + patterns: + - pattern-regex: shpss_[a-fA-F0-9]{32} + severity: INFO + - id: generic.secrets.gitleaks.sidekiq-secret.sidekiq-secret languages: - - javascript - - typescript - message: Detected use of dynamic execution of JavaScript which may come from user-input, which can lead to Cross-Site-Scripting (XSS). Where possible avoid including user-input in functions which dynamically execute user-input. + - regex + message: A gitleaks sidekiq-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#never_use_eval! - source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-eval-with-expression.js + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - javascript - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: location.href = $FUNC(...) - - pattern: location.hash = $FUNC(...) - - pattern: location.search = $FUNC(...) - - pattern: $WINDOW. ... .location.href = $FUNC(...) - - pattern: $WINDOW. ... .location.hash = $FUNC(...) - - pattern: $WINDOW. ... .location.search = $FUNC(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: eval(<... $SINK ...>) - - pattern: window.eval(<... $SINK ...>) - - pattern: new Function(<... $SINK ...>) - - pattern: new Function(<... $SINK ...>)(...) - - pattern: setTimeout(<... $SINK ...>,...) - - pattern: setInterval(<... $SINK ...>,...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $PROP = new URLSearchParams($WINDOW. ... .location.search).get('...') - ... - - pattern-inside: | - $PROP = new URLSearchParams(location.search).get('...') - ... - - pattern-inside: | - $PROP = new URLSearchParams($WINDOW. ... .location.hash.substring(1)).get('...') - ... - - pattern-inside: | - $PROP = new URLSearchParams(location.hash.substring(1)).get('...') - ... - - focus-metavariable: $PROP - - patterns: - - pattern-either: - - pattern-inside: | - $PROPS = new URLSearchParams($WINDOW. ... .location.search) - ... - - pattern-inside: | - $PROPS = new URLSearchParams(location.search) - ... - - pattern-inside: | - $PROPS = new - URLSearchParams($WINDOW. ... .location.hash.substring(1)) - ... - - pattern-inside: | - $PROPS = new URLSearchParams(location.hash.substring(1)) - ... - - pattern: $PROPS.get('...') - - focus-metavariable: $PROPS - - patterns: - - pattern-either: - - pattern: location.href - - pattern: location.hash - - pattern: location.search - - pattern: $WINDOW. ... .location.href - - pattern: $WINDOW. ... .location.hash - - pattern: $WINDOW. ... .location.search - severity: WARNING - - id: javascript.passport-jwt.security.passport-hardcode.hardcoded-passport-secret + - gitleaks + patterns: + - pattern-regex: (?i)(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.sidekiq-sensitive-url.sidekiq-sensitive-url languages: - - javascript - - typescript - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - regex + message: A gitleaks sidekiq-sensitive-url was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 3.5.2 Static API keys or secret - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - jwt - - nodejs - - secrets - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $F = require("$I").Strategy - ... - - pattern-inside: | - $F = require("$I") - ... - - pattern-inside: | - import { $STRAT as $F } from '$I' - ... - - pattern-inside: | - import $F from '$I' - ... - - metavariable-regex: - metavariable: $I - regex: (passport-.*) - - pattern-inside: | - new $F($VALUE,...) - - focus-metavariable: $VALUE - pattern-sources: - - by-side-effect: true - patterns: - - pattern-either: - - pattern: | - {..., clientSecret: "...", ...} - - pattern: | - {..., secretOrKey: "...", ...} - - pattern: | - {..., consumerSecret: "...", ...} - - patterns: - - pattern-inside: | - $OBJ = {} - ... - - pattern-either: - - pattern: | - $OBJ.clientSecret = "..." - - pattern: | - $OBJ.secretOrKey = "..." - - pattern: | - $OBJ.consumerSecret = "..." - - pattern: $OBJ - - patterns: - - pattern-inside: | - $SECRET = '...' - ... - - pattern-either: - - pattern: | - {..., clientSecret: $SECRET, ...} - - pattern: | - {..., secretOrKey: $SECRET, ...} - - pattern: | - {..., consumerSecret: $SECRET, ...} - - patterns: - - pattern-inside: | - $SECRET = '...' - ... - - pattern-either: - - pattern-inside: | - $VALUE = {..., clientSecret: $SECRET, ...} - ... - - pattern-inside: | - $VALUE = {..., secretOrKey: $SECRET, ...} - ... - - pattern-inside: | - $VALUE = {..., consumerSecret: $SECRET, ...} - ... - - pattern: $VALUE - severity: WARNING - - id: javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection + - gitleaks + patterns: + - pattern-regex: (?i)\b(http(?:s??):\/\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$) + severity: INFO + - id: generic.secrets.gitleaks.slack-app-token.slack-app-token languages: - - javascript - - typescript - message: Detected a sequelize statement that is tainted by user-input. This could lead to SQL injection if the variable is user-controlled and is not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements. + - regex + message: A gitleaks slack-app-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + impact: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://sequelize.org/docs/v6/core-concepts/raw-queries/#replacements + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - express - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern-either: - - pattern: parseInt(...) - - pattern: $FUNC. ... .hash(...) - pattern-sinks: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sequelize.query($QUERY,...) - - pattern: $DB.sequelize.query($QUERY,...) - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - pattern: $REQ.files.$ANYTHING.data.toString('utf8') - - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - pattern: files.$ANYTHING.data.toString('utf8') - - pattern: files.$ANYTHING['data'].toString('utf8') - severity: ERROR - - id: json.aws.security.public-s3-bucket.public-s3-bucket + - gitleaks + patterns: + - pattern-regex: (?i)(xapp-\d-[A-Z0-9]+-\d+-[a-z0-9]+) + severity: INFO + - id: generic.secrets.gitleaks.slack-bot-token.slack-bot-token languages: - - json - message: Detected public S3 bucket. This policy allows anyone to have some kind of access to the bucket. The exact level of access and types of actions allowed will depend on the configuration of bucket policy and ACLs. Please review the bucket configuration to make sure they are set with intended values. + - regex + message: A gitleaks slack-bot-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-264: CWE CATEGORY: Permissions, Privileges, and Access Controls' - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws + - gitleaks patterns: - - pattern-inside: | - $BUCKETNAME: { - "Type": "AWS::S3::Bucket", - "Properties": { - ..., - }, - ..., - } - - pattern-either: - - pattern: | - "PublicAccessBlockConfiguration": { - ..., - "RestrictPublicBuckets": false, - ..., - }, - - pattern: | - "PublicAccessBlockConfiguration": { - ..., - "IgnorePublicAcls": false, - ..., - }, - - pattern: | - "PublicAccessBlockConfiguration": { - ..., - "BlockPublicAcls": false, - ..., - }, - - pattern: | - "PublicAccessBlockConfiguration": { - ..., - "BlockPublicPolicy": false, - ..., - }, - severity: WARNING - - id: json.aws.security.public-s3-policy-statement.public-s3-policy-statement + - pattern-regex: (xoxb-[0-9]{10,13}\-[0-9]{10,13}[a-zA-Z0-9-]*) + severity: INFO + - id: generic.secrets.gitleaks.slack-config-access-token.slack-config-access-token languages: - - json - message: Detected public S3 bucket policy. This policy allows anyone to access certain properties of or items in the bucket. Do not do this unless you will never have sensitive data inside the bucket. + - regex + message: A gitleaks slack-config-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-264: CWE CATEGORY: Permissions, Privileges, and Access Controls' - impact: HIGH + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteAccessPermissionsReqd.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws - pattern: | - { - "Effect": "Allow", - "Principal": "*", - "Resource": [ - ..., "=~/arn:aws:s3.*/", ... - ], - ... - } - severity: WARNING - - id: json.aws.security.wildcard-assume-role.wildcard-assume-role + - gitleaks + patterns: + - pattern-regex: (?i)(xoxe.xox[bp]-\d-[A-Z0-9]{163,166}) + severity: INFO + - id: generic.secrets.gitleaks.slack-config-refresh-token.slack-config-refresh-token languages: - - json - message: 'Detected wildcard access granted to sts:AssumeRole. This means anyone with your AWS account ID and the name of the role can assume the role. Instead, limit to a specific identity in your account, like this: `arn:aws:iam:::root`.' + - regex + message: A gitleaks slack-config-refresh-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: HIGH - likelihood: HIGH + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A06:2017 - Security Misconfiguration - - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - aws + - gitleaks patterns: - - pattern-inside: | - "Statement": [...] - - pattern-inside: | - {..., "Effect": "Allow", ..., "Action": "sts:AssumeRole", ...} - - pattern: | - "Principal": {..., "AWS": "*", ...} - severity: ERROR - - id: kotlin.lang.security.anonymous-ldap-bind.anonymous-ldap-bind + - pattern-regex: (?i)(xoxe-\d-[A-Z0-9]{146}) + severity: INFO + - id: generic.secrets.gitleaks.slack-legacy-bot-token.slack-legacy-bot-token languages: - - kt - message: Detected anonymous LDAP bind. This permits anonymous users to execute LDAP statements. Consider enforcing authentication for LDAP. See https://docs.oracle.com/javase/tutorial/jndi/ldap/auth_mechs.html for more information. + - regex + message: A gitleaks slack-legacy-bot-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-287: Improper Authentication' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A02:2017 - Broken Authentication - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#LDAP_ANONYMOUS + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - kotlin - pattern: | - $ENV.put($CTX.SECURITY_AUTHENTICATION, "none") - ... - $DCTX = InitialDirContext($ENV, ...) - severity: WARNING - - id: kotlin.lang.security.ecb-cipher.ecb-cipher + - gitleaks + patterns: + - pattern-regex: (xoxb-[0-9]{8,14}\-[a-zA-Z0-9]{18,26}) + severity: INFO + - id: generic.secrets.gitleaks.slack-legacy-token.slack-legacy-token languages: - - kt - message: Cipher in ECB mode is detected. ECB mode produces the same output for the same input each time which allows an attacker to intercept and replay the data. Further, ECB mode does not provide any integrity checking. See https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY. + - regex + message: A gitleaks slack-legacy-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#ECB_MODE + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - kotlin + - gitleaks patterns: - - pattern-either: - - pattern: | - val $VAR : Cipher = $CIPHER.getInstance($MODE) - - pattern: | - var $VAR : Cipher = $CIPHER.getInstance($MODE) - - pattern: | - val $VAR = $CIPHER.getInstance($MODE) - - pattern: | - var $VAR = $CIPHER.getInstance($MODE) - - metavariable-regex: - metavariable: $MODE - regex: .*ECB.* - severity: WARNING - - id: kotlin.lang.security.no-null-cipher.no-null-cipher + - pattern-regex: (xox[os]-\d+-\d+-\d+-[a-fA-F\d]+) + severity: INFO + - id: generic.secrets.gitleaks.slack-legacy-workspace-token.slack-legacy-workspace-token languages: - - kt - - scala - message: 'NullCipher was detected. This will not encrypt anything; the cipher text will be the same as the plain text. Use a valid, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + - regex + message: A gitleaks slack-legacy-workspace-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#NULL_CIPHER + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - kotlin - pattern: NullCipher(...) - severity: WARNING - - id: kotlin.lang.security.use-of-md5.use-of-md5 + - gitleaks + patterns: + - pattern-regex: (xox[ar]-(?:\d-)?[0-9a-zA-Z]{8,48}) + severity: INFO + - id: generic.secrets.gitleaks.slack-user-token.slack-user-token languages: - - kt - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - regex + message: A gitleaks slack-user-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-328: Use of Weak Hash' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_MD5 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - kotlin - pattern-either: - - pattern: | - $VAR = $MD.getInstance("MD5") - - pattern: | - $DU.getMd5Digest().digest(...) - severity: WARNING - - id: kotlin.lang.security.use-of-sha1.use-of-sha1 + - gitleaks + patterns: + - pattern-regex: (xox[pe](?:-[0-9]{10,13}){3}-[a-zA-Z0-9-]{28,34}) + severity: INFO + - id: generic.secrets.gitleaks.slack-webhook-url.slack-webhook-url languages: - - kt - message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - regex + message: A gitleaks slack-webhook-url was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_SHA1 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - kotlin - pattern-either: - - patterns: - - pattern: | - $VAR = $MD.getInstance("$ALGO") - - metavariable-regex: - metavariable: $ALGO - regex: (SHA1|SHA-1) - - pattern: | - $DU.getSha1Digest().digest(...) - severity: WARNING - - id: kotlin.lang.security.weak-rsa.use-of-weak-rsa-key + - gitleaks + patterns: + - pattern-regex: (https?:\/\/)?hooks.slack.com\/(services|workflows)\/[A-Za-z0-9+\/]{43,46} + severity: INFO + - id: generic.secrets.gitleaks.snyk-api-token.snyk-api-token languages: - - kt - message: RSA keys should be at least 2048 bits based on NIST recommendation. + - regex + message: A gitleaks snyk-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-326: Inadequate Encryption Strength' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#RSA_KEY_SIZE + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - kotlin + - gitleaks patterns: - - pattern-either: - - pattern: | - $KEY = $G.getInstance("RSA") - ... - $KEY.initialize($BITS) - - metavariable-comparison: - comparison: $BITS < 2048 - metavariable: $BITS - severity: WARNING - - id: php.doctrine.security.audit.doctrine-orm-dangerous-query.doctrine-orm-dangerous-query + - pattern-regex: (?i)(?:snyk_token|snyk_key|snyk_api_token|snyk_api_key|snyk_oauth_token)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.square-access-token.square-access-token languages: - - php - message: '`$QUERY` Detected string concatenation with a non-literal variable in a Doctrine QueryBuilder method. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead.' + - regex + message: A gitleaks square-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/query-builder.html#security-safely-preventing-sql-injection - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - doctrine - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $SINK - - pattern-either: - - pattern: $QUERY->add(...,$SINK,...) - - pattern: $QUERY->select(...,$SINK,...) - - pattern: $QUERY->addSelect(...,$SINK,...) - - pattern: $QUERY->delete(...,$SINK,...) - - pattern: $QUERY->update(...,$SINK,...) - - pattern: $QUERY->insert(...,$SINK,...) - - pattern: $QUERY->from(...,$SINK,...) - - pattern: $QUERY->join(...,$SINK,...) - - pattern: $QUERY->innerJoin(...,$SINK,...) - - pattern: $QUERY->leftJoin(...,$SINK,...) - - pattern: $QUERY->rightJoin(...,$SINK,...) - - pattern: $QUERY->where(...,$SINK,...) - - pattern: $QUERY->andWhere(...,$SINK,...) - - pattern: $QUERY->orWhere(...,$SINK,...) - - pattern: $QUERY->groupBy(...,$SINK,...) - - pattern: $QUERY->addGroupBy(...,$SINK,...) - - pattern: $QUERY->having(...,$SINK,...) - - pattern: $QUERY->andHaving(...,$SINK,...) - - pattern: $QUERY->orHaving(...,$SINK,...) - - pattern: $QUERY->orderBy(...,$SINK,...) - - pattern: $QUERY->addOrderBy(...,$SINK,...) - - pattern: $QUERY->set($SINK,...) - - pattern: $QUERY->setValue($SINK,...) - - pattern-either: - - pattern-inside: | - $Q = $X->createQueryBuilder(); - ... - - pattern-inside: | - $Q = new QueryBuilder(...); - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern: sprintf(...) - - pattern: | - "...".$SMTH - severity: WARNING - - id: php.lang.security.assert-use.assert-use + - gitleaks + patterns: + - pattern-regex: (?i)\b((EAAA|sq0atp-)[0-9A-Za-z\-_]{22,60})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.squarespace-access-token.squarespace-access-token languages: - - php - message: Calling assert with user input is equivalent to eval'ing. + - regex + message: A gitleaks squarespace-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://www.php.net/manual/en/function.assert - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/AssertsSniff.php + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - mode: taint - pattern-sinks: - - patterns: - - pattern: assert($SINK, ...); - - pattern-not: assert("...", ...); - - pattern: $SINK - pattern-sources: - - pattern-either: - - patterns: - - pattern-either: - - pattern: $_GET - - pattern: $_POST - - pattern: $_COOKIE - - pattern: $_REQUEST - - pattern: $_SERVER - - patterns: - - pattern: | - Route::$METHOD($ROUTENAME, function(..., $ARG, ...) { ... }) - - focus-metavariable: $ARG - severity: ERROR - - id: php.lang.security.base-convert-loses-precision.base-convert-loses-precision + - gitleaks + patterns: + - pattern-regex: (?i)(?:squarespace)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.stripe-access-token.stripe-access-token languages: - - php - message: The function base_convert uses 64-bit numbers internally, and does not correctly convert large numbers. It is not suitable for random tokens such as those used for session tokens or CSRF tokens. + - regex + message: A gitleaks stripe-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-190: Integer Overflow or Wraparound' - impact: LOW + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://www.php.net/base_convert - - https://www.sjoerdlangkemper.nl/2017/03/15/dont-use-base-convert-on-random-tokens/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - audit + - vuln technology: - - php - mode: taint - pattern-sanitizers: - - patterns: - - pattern: substr(..., $LENGTH) - - metavariable-comparison: - comparison: $LENGTH <= 7 - metavariable: $LENGTH - pattern-sinks: - - pattern: base_convert(...) - pattern-sources: - - pattern: hash(...) - - pattern: hash_hmac(...) - - pattern: sha1(...) - - pattern: md5(...) - - patterns: - - pattern: random_bytes($N) - - metavariable-comparison: - comparison: $N > 7 - metavariable: $N - - patterns: - - pattern: openssl_random_pseudo_bytes($N) - - metavariable-comparison: - comparison: $N > 7 - metavariable: $N - - patterns: - - pattern: $OBJ->get_random_bytes($N) - - metavariable-comparison: - comparison: $N > 7 - metavariable: $N - severity: WARNING - - id: php.lang.security.curl-ssl-verifypeer-off.curl-ssl-verifypeer-off + - gitleaks + patterns: + - pattern-regex: (?i)\b((sk|rk)_(test|live|prod)_[0-9a-z]{10,99})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.sumologic-access-id.sumologic-access-id languages: - - php - message: SSL verification is disabled but should not be (currently CURLOPT_SSL_VERIFYPEER= $IS_VERIFIED) + - regex + message: A gitleaks sumologic-access-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://www.saotn.org/dont-turn-off-curlopt_ssl_verifypeer-fix-php-configuration/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php + - gitleaks patterns: - - pattern-either: - - pattern: | - $ARG = $IS_VERIFIED; - ... - curl_setopt(..., CURLOPT_SSL_VERIFYPEER, $ARG); - - pattern: curl_setopt(..., CURLOPT_SSL_VERIFYPEER, $IS_VERIFIED) - - metavariable-regex: - metavariable: $IS_VERIFIED - regex: 0|false|null - severity: ERROR - - id: php.lang.security.deserialization.extract-user-data + - pattern-regex: (?i:(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3})(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(su[a-zA-Z0-9]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.sumologic-access-token.sumologic-access-token languages: - - php - message: Do not call 'extract()' on user-controllable data. If you must, then you must also provide the EXTR_SKIP flag to prevent overwriting existing variables. + - regex + message: A gitleaks sumologic-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-502: Deserialization of Untrusted Data' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures + - A07:2021 - Identification and Authentication Failures references: - - https://www.php.net/manual/en/function.extract.php#refsect1-function.extract-notes + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - mode: taint - pattern-sanitizers: - - pattern: extract($VAR, EXTR_SKIP,...) - pattern-sinks: - - pattern: extract(...) - pattern-sources: - - pattern-either: - - pattern: $_GET[...] - - pattern: $_FILES[...] - - pattern: $_POST[...] - severity: ERROR - - fix: echo htmlentities($...VARS); - id: php.lang.security.injection.echoed-request.echoed-request + - gitleaks + patterns: + - pattern-regex: (?i)(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.telegram-bot-api-token.telegram-bot-api-token languages: - - php - message: '`Echo`ing user input risks cross-site scripting vulnerability. You should use `htmlentities()` when showing data to users.' + - regex + message: A gitleaks telegram-bot-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://www.php.net/manual/en/function.htmlentities.php - - https://www.php.net/manual/en/reserved.variables.request.php - - https://www.php.net/manual/en/reserved.variables.post.php - - https://www.php.net/manual/en/reserved.variables.get.php - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - mode: taint - pattern-sanitizers: - - pattern: htmlentities(...) - - pattern: htmlspecialchars(...) - - pattern: strip_tags(...) - - pattern: isset(...) - - pattern: empty(...) - - pattern: esc_html(...) - - pattern: esc_attr(...) - - pattern: wp_kses(...) - - pattern: e(...) - - pattern: twig_escape_filter(...) - - pattern: xss_clean(...) - - pattern: html_escape(...) - - pattern: Html::escape(...) - - pattern: Xss::filter(...) - - pattern: escapeHtml(...) - - pattern: escapeHtml(...) - - pattern: escapeHtmlAttr(...) - pattern-sinks: - - pattern: echo $...VARS; - pattern-sources: - - pattern: $_REQUEST - - pattern: $_GET - - pattern: $_POST - severity: ERROR - - fix: print(htmlentities($...VARS)); - id: php.lang.security.injection.printed-request.printed-request + - gitleaks + patterns: + - pattern-regex: (?i:(?:telegr)(?:[0-9a-z\(-_\t .\\]{0,40})(?:[\s|']|[\s|"]){0,3})(?:=|\|\|:|<=|=>|:|\?=|\()(?:'|\"|\s|=|\x60){0,5}([0-9]{5,16}:A[a-z0-9_\-]{34})(?:['|\"|\n|\r|\s|\x60|;|\\]|$) + severity: INFO + - id: generic.secrets.gitleaks.travisci-access-token.travisci-access-token languages: - - php - message: '`Printing user input risks cross-site scripting vulnerability. You should use `htmlentities()` when showing data to users.' + - regex + message: A gitleaks travisci-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://www.php.net/manual/en/function.htmlentities.php - - https://www.php.net/manual/en/reserved.variables.request.php - - https://www.php.net/manual/en/reserved.variables.post.php - - https://www.php.net/manual/en/reserved.variables.get.php - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - mode: taint - pattern-sanitizers: - - pattern: htmlentities(...) - - pattern: htmlspecialchars(...) - - pattern: strip_tags(...) - - pattern: isset(...) - - pattern: empty(...) - - pattern: esc_html(...) - - pattern: esc_attr(...) - - pattern: wp_kses(...) - - pattern: e(...) - - pattern: twig_escape_filter(...) - - pattern: xss_clean(...) - - pattern: html_escape(...) - - pattern: Html::escape(...) - - pattern: Xss::filter(...) - - pattern: escapeHtml(...) - - pattern: escapeHtml(...) - - pattern: escapeHtmlAttr(...) - pattern-sinks: - - pattern: print($...VARS); - pattern-sources: - - pattern: $_REQUEST - - pattern: $_GET - - pattern: $_POST - severity: ERROR - - id: php.lang.security.injection.tainted-filename.tainted-filename + - gitleaks + patterns: + - pattern-regex: (?i)(?:travis)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.twilio-api-key.twilio-api-key languages: - - php - message: File name based on user input risks server-side request forgery. + - regex + message: A gitleaks twilio-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A10_2021-Server-Side_Request_Forgery_%28SSRF%29 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: basename($PATH, ...) - - pattern-inside: linkinfo($PATH, ...) - - pattern-inside: readlink($PATH, ...) - - pattern-inside: realpath($PATH, ...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: opcache_compile_file($FILENAME, ...) - - pattern-inside: opcache_invalidate($FILENAME, ...) - - pattern-inside: opcache_is_script_cached($FILENAME, ...) - - pattern-inside: runkit7_import($FILENAME, ...) - - pattern-inside: readline_read_history($FILENAME, ...) - - pattern-inside: readline_write_history($FILENAME, ...) - - pattern-inside: rar_open($FILENAME, ...) - - pattern-inside: zip_open($FILENAME, ...) - - pattern-inside: gzfile($FILENAME, ...) - - pattern-inside: gzopen($FILENAME, ...) - - pattern-inside: readgzfile($FILENAME, ...) - - pattern-inside: hash_file($ALGO, $FILENAME, ...) - - pattern-inside: hash_update_file($CONTEXT, $FILENAME, ...) - - pattern-inside: pg_trace($FILENAME, ...) - - pattern-inside: dio_open($FILENAME, ...) - - pattern-inside: finfo_file($FINFO, $FILENAME, ...) - - pattern-inside: mime_content_type($FILENAME, ...) - - pattern-inside: chgrp($FILENAME, ...) - - pattern-inside: chmod($FILENAME, ...) - - pattern-inside: chown($FILENAME, ...) - - pattern-inside: clearstatcache($CLEAR_REALPATH_CACHE, $FILENAME, ...) - - pattern-inside: file_exists($FILENAME, ...) - - pattern-inside: file_get_contents($FILENAME, ...) - - pattern-inside: file_put_contents($FILENAME, ...) - - pattern-inside: file($FILENAME, ...) - - pattern-inside: fileatime($FILENAME, ...) - - pattern-inside: filectime($FILENAME, ...) - - pattern-inside: filegroup($FILENAME, ...) - - pattern-inside: fileinode($FILENAME, ...) - - pattern-inside: filemtime($FILENAME, ...) - - pattern-inside: fileowner($FILENAME, ...) - - pattern-inside: fileperms($FILENAME, ...) - - pattern-inside: filesize($FILENAME, ...) - - pattern-inside: filetype($FILENAME, ...) - - pattern-inside: fnmatch($PATTERN, $FILENAME, ...) - - pattern-inside: fopen($FILENAME, ...) - - pattern-inside: is_dir($FILENAME, ...) - - pattern-inside: is_executable($FILENAME, ...) - - pattern-inside: is_file($FILENAME, ...) - - pattern-inside: is_link($FILENAME, ...) - - pattern-inside: is_readable($FILENAME, ...) - - pattern-inside: is_uploaded_file($FILENAME, ...) - - pattern-inside: is_writable($FILENAME, ...) - - pattern-inside: lchgrp($FILENAME, ...) - - pattern-inside: lchown($FILENAME, ...) - - pattern-inside: lstat($FILENAME, ...) - - pattern-inside: parse_ini_file($FILENAME, ...) - - pattern-inside: readfile($FILENAME, ...) - - pattern-inside: stat($FILENAME, ...) - - pattern-inside: touch($FILENAME, ...) - - pattern-inside: unlink($FILENAME, ...) - - pattern-inside: xattr_get($FILENAME, ...) - - pattern-inside: xattr_list($FILENAME, ...) - - pattern-inside: xattr_remove($FILENAME, ...) - - pattern-inside: xattr_set($FILENAME, ...) - - pattern-inside: xattr_supported($FILENAME, ...) - - pattern-inside: enchant_broker_request_pwl_dict($BROKER, $FILENAME, ...) - - pattern-inside: pspell_config_personal($CONFIG, $FILENAME, ...) - - pattern-inside: pspell_config_repl($CONFIG, $FILENAME, ...) - - pattern-inside: pspell_new_personal($FILENAME, ...) - - pattern-inside: exif_imagetype($FILENAME, ...) - - pattern-inside: getimagesize($FILENAME, ...) - - pattern-inside: image2wbmp($IMAGE, $FILENAME, ...) - - pattern-inside: imagecreatefromavif($FILENAME, ...) - - pattern-inside: imagecreatefrombmp($FILENAME, ...) - - pattern-inside: imagecreatefromgd2($FILENAME, ...) - - pattern-inside: imagecreatefromgd2part($FILENAME, ...) - - pattern-inside: imagecreatefromgd($FILENAME, ...) - - pattern-inside: imagecreatefromgif($FILENAME, ...) - - pattern-inside: imagecreatefromjpeg($FILENAME, ...) - - pattern-inside: imagecreatefrompng($FILENAME, ...) - - pattern-inside: imagecreatefromtga($FILENAME, ...) - - pattern-inside: imagecreatefromwbmp($FILENAME, ...) - - pattern-inside: imagecreatefromwebp($FILENAME, ...) - - pattern-inside: imagecreatefromxbm($FILENAME, ...) - - pattern-inside: imagecreatefromxpm($FILENAME, ...) - - pattern-inside: imageloadfont($FILENAME, ...) - - pattern-inside: imagexbm($IMAGE, $FILENAME, ...) - - pattern-inside: iptcembed($IPTC_DATA, $FILENAME, ...) - - pattern-inside: mailparse_msg_extract_part_file($MIMEMAIL, $FILENAME, ...) - - pattern-inside: mailparse_msg_extract_whole_part_file($MIMEMAIL, $FILENAME, ...) - - pattern-inside: mailparse_msg_parse_file($FILENAME, ...) - - pattern-inside: fdf_add_template($FDF_DOCUMENT, $NEWPAGE, $FILENAME, ...) - - pattern-inside: fdf_get_ap($FDF_DOCUMENT, $FIELD, $FACE, $FILENAME, ...) - - pattern-inside: fdf_open($FILENAME, ...) - - pattern-inside: fdf_save($FDF_DOCUMENT, $FILENAME, ...) - - pattern-inside: fdf_set_ap($FDF_DOCUMENT, $FIELD_NAME, $FACE, $FILENAME, ...) - - pattern-inside: ps_add_launchlink($PSDOC, $LLX, $LLY, $URX, $URY, $FILENAME, ...) - - pattern-inside: ps_add_pdflink($PSDOC, $LLX, $LLY, $URX, $URY, $FILENAME, ...) - - pattern-inside: ps_open_file($PSDOC, $FILENAME, ...) - - pattern-inside: ps_open_image_file($PSDOC, $TYPE, $FILENAME, ...) - - pattern-inside: posix_access($FILENAME, ...) - - pattern-inside: posix_mkfifo($FILENAME, ...) - - pattern-inside: posix_mknod($FILENAME, ...) - - pattern-inside: ftok($FILENAME, ...) - - pattern-inside: fann_cascadetrain_on_file($ANN, $FILENAME, ...) - - pattern-inside: fann_read_train_from_file($FILENAME, ...) - - pattern-inside: fann_train_on_file($ANN, $FILENAME, ...) - - pattern-inside: highlight_file($FILENAME, ...) - - pattern-inside: php_strip_whitespace($FILENAME, ...) - - pattern-inside: stream_resolve_include_path($FILENAME, ...) - - pattern-inside: swoole_async_read($FILENAME, ...) - - pattern-inside: swoole_async_readfile($FILENAME, ...) - - pattern-inside: swoole_async_write($FILENAME, ...) - - pattern-inside: swoole_async_writefile($FILENAME, ...) - - pattern-inside: swoole_load_module($FILENAME, ...) - - pattern-inside: tidy_parse_file($FILENAME, ...) - - pattern-inside: tidy_repair_file($FILENAME, ...) - - pattern-inside: get_meta_tags($FILENAME, ...) - - pattern-inside: yaml_emit_file($FILENAME, ...) - - pattern-inside: yaml_parse_file($FILENAME, ...) - - pattern-inside: curl_file_create($FILENAME, ...) - - pattern-inside: ftp_chmod($FTP, $PERMISSIONS, $FILENAME, ...) - - pattern-inside: ftp_delete($FTP, $FILENAME, ...) - - pattern-inside: ftp_mdtm($FTP, $FILENAME, ...) - - pattern-inside: ftp_size($FTP, $FILENAME, ...) - - pattern-inside: rrd_create($FILENAME, ...) - - pattern-inside: rrd_fetch($FILENAME, ...) - - pattern-inside: rrd_graph($FILENAME, ...) - - pattern-inside: rrd_info($FILENAME, ...) - - pattern-inside: rrd_last($FILENAME, ...) - - pattern-inside: rrd_lastupdate($FILENAME, ...) - - pattern-inside: rrd_tune($FILENAME, ...) - - pattern-inside: rrd_update($FILENAME, ...) - - pattern-inside: snmp_read_mib($FILENAME, ...) - - pattern-inside: ssh2_sftp_chmod($SFTP, $FILENAME, ...) - - pattern-inside: ssh2_sftp_realpath($SFTP, $FILENAME, ...) - - pattern-inside: ssh2_sftp_unlink($SFTP, $FILENAME, ...) - - pattern-inside: apache_lookup_uri($FILENAME, ...) - - pattern-inside: md5_file($FILENAME, ...) - - pattern-inside: sha1_file($FILENAME, ...) - - pattern-inside: simplexml_load_file($FILENAME, ...) - - pattern: $FILENAME - pattern-sources: - - patterns: - - pattern-either: - - pattern: $_GET - - pattern: $_POST - - pattern: $_COOKIE - - pattern: $_REQUEST - - pattern: $_SERVER - severity: WARNING - - id: php.lang.security.injection.tainted-object-instantiation.tainted-object-instantiation + - gitleaks + patterns: + - pattern-regex: SK[0-9a-fA-F]{32} + severity: INFO + - id: generic.secrets.gitleaks.twitch-api-token.twitch-api-token languages: - - php - message: <- A new object is created where the class name is based on user input. This could lead to remote code execution, as it allows to instantiate any class in the application. + - regex + message: A gitleaks twitch-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-470: Use of Externally-Controlled Input to Select Classes or Code (''Unsafe Reflection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: new $SINK(...) - - pattern: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern: $_GET - - pattern: $_POST - - pattern: $_COOKIE - - pattern: $_REQUEST - - pattern: $_SERVER - severity: WARNING - - id: php.lang.security.injection.tainted-session.tainted-session + - gitleaks + patterns: + - pattern-regex: (?i)(?:twitch)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.twitter-access-secret.twitter-access-secret languages: - - php - message: Session key based on user input risks session poisoning. The user can determine the key used for the session, and thus write any session variable. Session variables are typically trusted to be set only by the application, and manipulating the session can result in access control issues. + - regex + message: A gitleaks twitter-access-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-284: Improper Access Control' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://en.wikipedia.org/wiki/Session_poisoning + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: $A . $B - - pattern: bin2hex(...) - - pattern: crc32(...) - - pattern: crypt(...) - - pattern: filter_input(...) - - pattern: filter_var(...) - - pattern: hash(...) - - pattern: md5(...) - - pattern: preg_filter(...) - - pattern: preg_grep(...) - - pattern: preg_match_all(...) - - pattern: sha1(...) - - pattern: sprintf(...) - - pattern: str_contains(...) - - pattern: str_ends_with(...) - - pattern: str_starts_with(...) - - pattern: strcasecmp(...) - - pattern: strchr(...) - - pattern: stripos(...) - - pattern: stristr(...) - - pattern: strnatcasecmp(...) - - pattern: strnatcmp(...) - - pattern: strncmp(...) - - pattern: strpbrk(...) - - pattern: strpos(...) - - pattern: strripos(...) - - pattern: strrpos(...) - - pattern: strspn(...) - - pattern: strstr(...) - - pattern: strtok(...) - - pattern: substr_compare(...) - - pattern: substr_count(...) - - pattern: vsprintf(...) - pattern-sinks: - - patterns: - - pattern-inside: $_SESSION[$KEY] = $VAL; - - pattern: $KEY - pattern-sources: - - patterns: - - pattern-either: - - pattern: $_GET - - pattern: $_POST - - pattern: $_COOKIE - - pattern: $_REQUEST - severity: WARNING - - id: php.lang.security.injection.tainted-sql-string.tainted-sql-string + - gitleaks + patterns: + - pattern-regex: (?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{45})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.twitter-access-token.twitter-access-token languages: - - php - message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`$mysqli->prepare("INSERT INTO test(id, label) VALUES (?, ?)");`) or a safe library. + - regex + message: A gitleaks twitter-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/www-community/attacks/SQL_Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - mode: taint - pattern-sanitizers: - - pattern-either: - - pattern: mysqli_real_escape_string(...) - - pattern: real_escape_string(...) - - pattern: $MYSQLI->real_escape_string(...) - pattern-sinks: - - pattern-either: - - patterns: - - pattern: | - sprintf($SQLSTR, ...) - - metavariable-regex: - metavariable: $SQLSTR - regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - - patterns: - - pattern: | - "...$EXPR..." - - metavariable-regex: - metavariable: $EXPR - regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - - patterns: - - pattern: | - "$SQLSTR".$EXPR - - metavariable-regex: - metavariable: $SQLSTR - regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - pattern-sources: - - patterns: - - pattern-either: - - pattern: $_GET - - pattern: $_POST - - pattern: $_COOKIE - - pattern: $_REQUEST - severity: ERROR - - id: php.lang.security.injection.tainted-url-host.tainted-url-host + - gitleaks + patterns: + - pattern-regex: (?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{15,25}-[a-zA-Z0-9]{20,40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.twitter-api-key.twitter-api-key languages: - - php - message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. + - regex + message: A gitleaks twitter-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + likelihood: LOW owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) + - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - mode: taint - pattern-sinks: - - pattern-either: - - patterns: - - pattern: | - sprintf($URLSTR, ...) - - metavariable-pattern: - language: generic - metavariable: $URLSTR - pattern: $SCHEME://%s - - patterns: - - pattern: | - "...{$EXPR}..." - - pattern-regex: | - .*://\{.* - - patterns: - - pattern: | - "...$EXPR..." - - pattern-regex: | - .*://\$.* - - patterns: - - pattern: | - "...".$EXPR - - pattern-regex: | - .*://["'].* - pattern-sources: - - patterns: - - pattern-either: - - pattern: $_GET - - pattern: $_POST - - pattern: $_COOKIE - - pattern: $_REQUEST - severity: WARNING - - id: php.lang.security.md5-used-as-password.md5-used-as-password + - gitleaks + patterns: + - pattern-regex: (?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.twitter-api-secret.twitter-api-secret languages: - - php - message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as bcrypt. You can use `password_hash($PASSWORD, PASSWORD_BCRYPT, $OPTIONS);`. + - regex + message: A gitleaks twitter-api-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://tools.ietf.org/html/rfc6151 - - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision - - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords - - https://github.com/returntocorp/semgrep-rules/issues/1609 - - https://www.php.net/password_hash + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - md5 - mode: taint - pattern-sinks: - - patterns: - - pattern: $FUNCTION(...) - - metavariable-regex: - metavariable: $FUNCTION - regex: (?i)(.*password.*) - pattern-sources: - - patterns: - - pattern-either: - - pattern: md5(...) - - pattern: hash('md5', ...) - severity: WARNING - - id: php.lang.security.openssl-cbc-static-iv.openssl-cbc-static-iv + - gitleaks + patterns: + - pattern-regex: (?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{50})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.twitter-bearer-token.twitter-bearer-token languages: - - php - message: Static IV used with AES in CBC mode. Static IVs enable chosen-plaintext attacks against encrypted data. + - regex + message: A gitleaks twitter-bearer-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: HIGH + confidence: LOW cwe: - - 'CWE-329: Generation of Predictable IV with CBC Mode' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://csrc.nist.gov/publications/detail/sp/800-38a/final + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - - openssl + - gitleaks patterns: - - pattern-either: - - pattern: openssl_encrypt($D, $M, $K, $FLAGS, "...",...); - - pattern: openssl_decrypt($D, $M, $K, $FLAGS, "...",...); - - metavariable-comparison: - comparison: re.match(".*-CBC",$M) - metavariable: $M - severity: ERROR - - id: php.lang.security.phpinfo-use.phpinfo-use + - pattern-regex: (?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(A{22}[a-zA-Z0-9%]{80,100})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.typeform-api-token.typeform-api-token languages: - - php - message: The 'phpinfo' function may reveal sensitive information about your environment. + - regex + message: A gitleaks typeform-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://www.php.net/manual/en/function.phpinfo - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/PhpinfosSniff.php + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - pattern: phpinfo(...); - severity: ERROR - - id: php.lang.security.redirect-to-request-uri.redirect-to-request-uri + - gitleaks + patterns: + - pattern-regex: (?i)(?:typeform)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(tfp_[a-z0-9\-_\.=]{59})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.vault-batch-token.vault-batch-token languages: - - php - message: Redirecting to the current request URL may redirect to another domain, if the current path starts with two slashes. E.g. in https://www.example.com//attacker.com, the value of REQUEST_URI is //attacker.com, and redirecting to it will redirect to that domain. + - regex + message: A gitleaks vault-batch-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: LOW - likelihood: MEDIUM + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control + - A07:2021 - Identification and Authentication Failures references: - - https://www.php.net/manual/en/reserved.variables.server.php - - https://owasp.org/www-project-top-ten/2017/A5_2017-Broken_Access_Control.html + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php + - gitleaks patterns: - - pattern-either: - - pattern: | - header('$LOCATION' . $_SERVER['REQUEST_URI']); - - pattern: | - header('$LOCATION' . $_SERVER['REQUEST_URI'] . $MORE); - - metavariable-regex: - metavariable: $LOCATION - regex: ^(?i)location:\s*$ - severity: WARNING - - id: php.lang.security.tainted-exec.tainted-exec + - pattern-regex: (?i)\b(hvb\.[a-z0-9_-]{138,212})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.vault-service-token.vault-service-token languages: - - php - message: Executing non-constant commands. This can lead to command injection. You should use `escapeshellarg()` when using command. + - regex + message: A gitleaks vault-service-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true cwe2022-top25: true - impact: HIGH - likelihood: HIGH + impact: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://www.stackhawk.com/blog/php-command-injection/ - - https://brightsec.com/blog/code-injection-php/ - - https://www.acunetix.com/websitesecurity/php-security-2/ + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - mode: taint - pattern-sanitizers: - - pattern: escapeshellarg(...) - pattern-sinks: - - pattern: exec(...) - - pattern: system(...) - - pattern: popen(...) - - pattern: passthru(...) - - pattern: shell_exec(...) - - pattern: pcntl_exec(...) - - pattern: proc_open(...) - pattern-sources: - - pattern: $_REQUEST - - pattern: $_GET - - pattern: $_POST - - pattern: $_COOKIE - severity: ERROR - - id: php.laravel.security.laravel-api-route-sql-injection.laravel-api-route-sql-injection + - gitleaks + patterns: + - pattern-regex: (?i)\b(hvs\.[a-z0-9_-]{90,100})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.yandex-api-key.yandex-api-key languages: - - php - message: HTTP method [$METHOD] to Laravel route $ROUTE_NAME is vulnerable to SQL injection via string concatenation or unsafe interpolation. + - regex + message: A gitleaks yandex-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Laravel_Cheat_Sheet.md + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - - laravel - mode: taint - pattern-sanitizers: - - patterns: - - pattern: | - DB::raw("...",[...]) - pattern-sinks: - - patterns: - - pattern: | - DB::raw(...) - pattern-sources: - - patterns: - - focus-metavariable: $ARG - - pattern-inside: | - Route::$METHOD($ROUTE_NAME, function(...,$ARG,...){...}) - severity: WARNING - - id: php.laravel.security.laravel-sql-injection.laravel-sql-injection + - gitleaks + patterns: + - pattern-regex: (?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(AQVN[A-Za-z0-9_\-]{35,38})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.yandex-aws-access-token.yandex-aws-access-token languages: - - php - message: Detected a SQL query based on user input. This could lead to SQL injection, which could potentially result in sensitive data being exfiltrated by attackers. Instead, use parameterized queries and prepared statements. + - regex + message: A gitleaks yandex-aws-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://laravel.com/docs/8.x/queries + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - laravel - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: $SQL - - pattern-either: - - pattern-inside: DB::table(...)->whereRaw($SQL, ...) - - pattern-inside: DB::table(...)->orWhereRaw($SQL, ...) - - pattern-inside: DB::table(...)->groupByRaw($SQL, ...) - - pattern-inside: DB::table(...)->havingRaw($SQL, ...) - - pattern-inside: DB::table(...)->orHavingRaw($SQL, ...) - - pattern-inside: DB::table(...)->orderByRaw($SQL, ...) - - patterns: - - pattern: $EXPRESSION - - pattern-either: - - pattern-inside: DB::table(...)->selectRaw($EXPRESSION, ...) - - pattern-inside: DB::table(...)->fromRaw($EXPRESSION, ...) - - patterns: - - pattern: $COLUMNS - - pattern-either: - - pattern-inside: DB::table(...)->whereNull($COLUMNS, ...) - - pattern-inside: DB::table(...)->orWhereNull($COLUMN) - - pattern-inside: DB::table(...)->whereNotNull($COLUMNS, ...) - - pattern-inside: DB::table(...)->whereRowValues($COLUMNS, ...) - - pattern-inside: DB::table(...)->orWhereRowValues($COLUMNS, ...) - - pattern-inside: DB::table(...)->find($ID, $COLUMNS) - - pattern-inside: DB::table(...)->paginate($PERPAGE, $COLUMNS, ...) - - pattern-inside: DB::table(...)->simplePaginate($PERPAGE, $COLUMNS, ...) - - pattern-inside: DB::table(...)->cursorPaginate($PERPAGE, $COLUMNS, ...) - - pattern-inside: DB::table(...)->getCountForPagination($COLUMNS) - - pattern-inside: DB::table(...)->aggregate($FUNCTION, $COLUMNS) - - pattern-inside: DB::table(...)->numericAggregate($FUNCTION, $COLUMNS) - - pattern-inside: DB::table(...)->insertUsing($COLUMNS, ...) - - pattern-inside: DB::table(...)->select($COLUMNS) - - pattern-inside: DB::table(...)->get($COLUMNS) - - pattern-inside: DB::table(...)->count($COLUMNS) - - patterns: - - pattern: $COLUMN - - pattern-either: - - pattern-inside: DB::table(...)->whereIn($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereIn($COLUMN, ...) - - pattern-inside: DB::table(...)->whereNotIn($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereNotIn($COLUMN, ...) - - pattern-inside: DB::table(...)->whereIntegerInRaw($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereIntegerInRaw($COLUMN, ...) - - pattern-inside: DB::table(...)->whereIntegerNotInRaw($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereIntegerNotInRaw($COLUMN, ...) - - pattern-inside: DB::table(...)->whereBetweenColumns($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereBetween($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereBetweenColumns($COLUMN, ...) - - pattern-inside: DB::table(...)->whereNotBetween($COLUMN, ...) - - pattern-inside: DB::table(...)->whereNotBetweenColumns($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereNotBetween($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereNotBetweenColumns($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereNotNull($COLUMN) - - pattern-inside: DB::table(...)->whereDate($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereDate($COLUMN, ...) - - pattern-inside: DB::table(...)->whereTime($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereTime($COLUMN, ...) - - pattern-inside: DB::table(...)->whereDay($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereDay($COLUMN, ...) - - pattern-inside: DB::table(...)->whereMonth($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereMonth($COLUMN, ...) - - pattern-inside: DB::table(...)->whereYear($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereYear($COLUMN, ...) - - pattern-inside: DB::table(...)->whereJsonContains($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereJsonContains($COLUMN, ...) - - pattern-inside: DB::table(...)->whereJsonDoesntContain($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereJsonDoesntContain($COLUMN, ...) - - pattern-inside: DB::table(...)->whereJsonLength($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhereJsonLength($COLUMN, ...) - - pattern-inside: DB::table(...)->having($COLUMN, ...) - - pattern-inside: DB::table(...)->orHaving($COLUMN, ...) - - pattern-inside: DB::table(...)->havingBetween($COLUMN, ...) - - pattern-inside: DB::table(...)->orderBy($COLUMN, ...) - - pattern-inside: DB::table(...)->orderByDesc($COLUMN) - - pattern-inside: DB::table(...)->latest($COLUMN) - - pattern-inside: DB::table(...)->oldest($COLUMN) - - pattern-inside: DB::table(...)->forPageBeforeId($PERPAGE, $LASTID, $COLUMN) - - pattern-inside: DB::table(...)->forPageAfterId($PERPAGE, $LASTID, $COLUMN) - - pattern-inside: DB::table(...)->value($COLUMN) - - pattern-inside: DB::table(...)->pluck($COLUMN, ...) - - pattern-inside: DB::table(...)->implode($COLUMN, ...) - - pattern-inside: DB::table(...)->min($COLUMN) - - pattern-inside: DB::table(...)->max($COLUMN) - - pattern-inside: DB::table(...)->sum($COLUMN) - - pattern-inside: DB::table(...)->avg($COLUMN) - - pattern-inside: DB::table(...)->average($COLUMN) - - pattern-inside: DB::table(...)->increment($COLUMN, ...) - - pattern-inside: DB::table(...)->decrement($COLUMN, ...) - - pattern-inside: DB::table(...)->where($COLUMN, ...) - - pattern-inside: DB::table(...)->orWhere($COLUMN, ...) - - pattern-inside: DB::table(...)->addSelect($COLUMN) - - patterns: - - pattern: $QUERY - - pattern-inside: DB::unprepared($QUERY) - pattern-sources: - - patterns: - - pattern-either: - - pattern: $_GET - - pattern: $_POST - - pattern: $_COOKIE - - pattern: $_REQUEST - - pattern: $_SERVER - severity: WARNING - - id: php.laravel.security.laravel-unsafe-validator.laravel-unsafe-validator + - gitleaks + patterns: + - pattern-regex: (?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(YC[a-zA-Z0-9_\-]{38})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.gitleaks.zendesk-secret-key.zendesk-secret-key languages: - - php - message: Found a request argument passed to an `ignore()` definition in a Rule constraint. This can lead to SQL injection. + - regex + message: A gitleaks zendesk-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://laravel.com/docs/9.x/validation#rule-unique + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - php - - laravel - mode: taint - pattern-sinks: - - patterns: - - pattern: | - Illuminate\Validation\Rule::unique(...)->ignore(...,$IGNORE,...) - - focus-metavariable: $IGNORE - pattern-sources: - - patterns: - - pattern: | - public function $F(...,Request $R,...){...} - - focus-metavariable: $R - - patterns: - - pattern-either: - - pattern: | - $this->$PROPERTY - - pattern: | - $this->$PROPERTY->$GET - - metavariable-pattern: - metavariable: $PROPERTY - patterns: - - pattern-either: - - pattern: query - - pattern: request - - pattern: headers - - pattern: cookies - - pattern: cookie - - pattern: files - - pattern: file - - pattern: allFiles - - pattern: input - - pattern: all - - pattern: post - - pattern: json - - pattern-either: - - pattern-inside: | - class $CL extends Illuminate\Http\Request {...} - - pattern-inside: | - class $CL extends Illuminate\Foundation\Http\FormRequest {...} - severity: ERROR - - id: problem-based-packs.insecure-transport.go-stdlib.bypass-tls-verification.bypass-tls-verification + - gitleaks + patterns: + - pattern-regex: (?i)(?:zendesk)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) + severity: INFO + - id: generic.secrets.security.detected-amazon-mws-auth-token.detected-amazon-mws-auth-token languages: - - go - message: Checks for disabling of TLS/SSL certificate verification. This should only be used for debugging purposes because it leads to vulnerability to MTM attacks. + - regex + message: Amazon MWS Auth Token detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: HIGH - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://stackoverflow.com/questions/12122159/how-to-do-a-https-request-with-bad-certificate + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - go - vulnerability: Insecure Transport - pattern-either: - - pattern: | - tls.Config{..., InsecureSkipVerify: true, ...} - - pattern: | - $CONFIG = &tls.Config{...} - ... - $CONFIG.InsecureSkipVerify = true - severity: WARNING - - id: problem-based-packs.insecure-transport.go-stdlib.disallow-old-tls-versions.disallow-old-tls-versions + - secrets + - aws + pattern-regex: amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} + severity: ERROR + - id: generic.secrets.security.detected-artifactory-password.detected-artifactory-password languages: - - go - message: Detects creations of tls configuration objects with an insecure MinVersion of TLS. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities. + - regex + message: Artifactory token detected metadata: category: security - confidence: HIGH - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: HIGH - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://stackoverflow.com/questions/26429751/java-http-clients-and-poodle + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/Yelp/detect-secrets/blob/master/detect_secrets/plugins/artifactory.py subcategory: - - vuln + - audit technology: - - go - vulnerability: Insecure Transport + - secrets + - artifactory + paths: + exclude: + - '*.svg' + - '*go.sum' + - '*package.json' + - '*cargo.lock' + - '*package-lock.json' + - '*bundle.js' + - '*pnpm-lock*' + - '*Podfile.lock' + - '*/openssl/*.h' + - '*.xcscmblueprint' patterns: - - pattern-either: - - pattern: | - tls.Config{..., MinVersion: $TLS.$VERSION, ...} - - pattern: | - $CONFIG = &tls.Config{...} - ... - $CONFIG.MinVersion = $TLS.$VERSION - - metavariable-regex: - metavariable: $VERSION - regex: (VersionTLS10|VersionTLS11|VersionSSL30) - severity: WARNING - - fix-regex: - count: 1 - regex: '[fF][tT][pP]://' - replacement: sftp:// - id: problem-based-packs.insecure-transport.go-stdlib.ftp-request.ftp-request + - pattern-regex: (?\bAP[\dABCDEF][a-zA-Z0-9]{8,}) + - pattern-regex: .*(?i)arti[-_]?factory.* + - pattern-not-regex: .*(?i)sha(1|2|3|118|256|512).* + - pattern-not-regex: (?i)-----\s*?BEGIN[ A-Z0-9_-]*? KEY( BLOCK)?-----[\s\S]*?-----\s*?END[ A-Z0-9_-]*?\s*?----- + - metavariable-analysis: + analyzer: entropy + metavariable: $ITEM + - pattern-not-regex: (\w|\.|\*)\1{4} + severity: ERROR + - id: generic.secrets.security.detected-artifactory-token.detected-artifactory-token languages: - - go - message: Checks for outgoing connections to ftp servers with the ftp package. FTP does not encrypt traffic, possibly leading to PII being sent plaintext over the network. Instead, connect via the SFTP protocol. + - regex + message: Artifactory token detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://godoc.org/github.com/jlaffaye/ftp#Dial - - https://github.com/jlaffaye/ftp + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/Yelp/detect-secrets/blob/master/detect_secrets/plugins/artifactory.py subcategory: - - vuln + - audit technology: - - ftp - vulnerability: Insecure Transport - pattern-either: - - pattern: | - ftp.Dial("=~/^[fF][tT][pP]://.*/", ...) - - pattern: | - ftp.DialTimeout("=~/^[fF][tT][pP]://.*/", ...) - - pattern: | - ftp.Connect("=~/^[fF][tT][pP]://.*/") - - pattern: | - $URL = "=~/^[fF][tT][pP]://.*/" - ... - ftp.Dial($URL, ...) - - pattern: | - $URL = "=~/^[fF][tT][pP]://.*/" - ... - ftp.DialTimeout($URL, ...) - - pattern: | - $URL = "=~/^[fF][tT][pP]://.*/" - ... - ftp.Connect($URL) - severity: WARNING - - id: problem-based-packs.insecure-transport.go-stdlib.gorequest-http-request.gorequest-http-request + - secrets + - artifactory + paths: + exclude: + - '*.svg' + - '*go.sum' + - '*package.json' + - '*package-lock.json' + - '*bundle.js' + - '*pnpm-lock*' + - '*Podfile.lock' + - '*/openssl/*.h' + - '*.xcscmblueprint' + - '*cargo.lock' + patterns: + - pattern-regex: | + \bAKC[a-zA-Z0-9]{10,} + - pattern-not-regex: | + sha(128|256|512).* + - pattern-not-regex: (?s)---BEGIN.*---\Z + severity: ERROR + - id: generic.secrets.security.detected-aws-access-key-id-value.detected-aws-access-key-id-value languages: - - go - message: Checks for requests to http (unencrypted) sites using gorequest, a popular HTTP client library. This is dangerous because it could result in plaintext PII being passed around the network. + - regex + message: AWS Access Key ID Value detected. This is a sensitive credential and should not be hardcoded here. Instead, read this value from an environment variable or keep it in a separate, private file. metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: HIGH - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/parnurzeal/gorequest + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - gorequest - vulnerability: Insecure Transport - pattern-either: - - patterns: - - pattern-inside: | - $REQ = gorequest.New() - ... - $RES = ... - - pattern: | - $REQ.$FUNC("=~/[hH][tT][tT][pP]://.*/") - - metavariable-regex: - metavariable: $FUNC - regex: (Get|Post|Delete|Head|Put|Patch) - - patterns: - - pattern: gorequest.New().$FUNC("=~/[hH][tT][tT][pP]://.*/") - - metavariable-regex: - metavariable: $FUNC - regex: (Get|Post|Delete|Head|Put|Patch) - severity: WARNING - - id: problem-based-packs.insecure-transport.go-stdlib.grequests-http-request.grequests-http-request + - secrets + - aws + patterns: + - pattern-regex: \b(A3T[A-Z0-9]|AKIA|AGPA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}\b + - pattern-not-regex: (?i)example|sample|test|fake + severity: ERROR + - id: generic.secrets.security.detected-aws-account-id.detected-aws-account-id languages: - - go - message: Checks for requests to http (unencrypted) sites using grequests, a popular HTTP client library. This is dangerous because it could result in plaintext PII being passed around the network. + - generic + message: AWS Account ID detected. While not considered sensitive information, it is important to use them and share them carefully. For that reason it would be preferrable avoiding to hardcoded it here. Instead, read the value from an environment variable or keep the value in a separate, private file. metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://godoc.org/github.com/levigross/grequests#DoRegularRequest - - https://github.com/levigross/grequests + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - grequests - vulnerability: Insecure Transport + - secrets + - aws patterns: - pattern-either: - pattern: | - grequests.$FUNC(...,"=~/[hH][tT][tT][pP]://.*/", ...) + $ACCOUNT_ID = $SECRET - pattern: | - $FUNC(...,"=~/[hH][tT][tT][pP]://.*/", ...) + $ACCOUNT_ID : $SECRET + - pattern: | + $ACCOUNT_ID => $SECRET + - pattern: | + $ACCOUNT_ID = "$SECRET" + - pattern: | + $ACCOUNT_ID : "$SECRET" + - pattern: | + $ACCOUNT_ID => "$SECRET" + - pattern: | + "$ACCOUNT_ID" = "$SECRET" + - pattern: | + "$ACCOUNT_ID" : "$SECRET" + - pattern: | + "$ACCOUNT_ID" => "$SECRET" + - metavariable-analysis: + analyzer: entropy + metavariable: $SECRET - metavariable-regex: - metavariable: $FUNC - regex: (Get|Head|Post|Put|Delete|Patch|Options|Req|DoRegularRequest) - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: problem-based-packs.insecure-transport.go-stdlib.http-customized-request.http-customized-request + metavariable: $SECRET + regex: ^((?!(12345|0000).*)[0-9]{12})$ + - metavariable-regex: + metavariable: $ACCOUNT_ID + regex: (AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?("|')? + severity: ERROR + - id: generic.secrets.security.detected-aws-appsync-graphql-key.detected-aws-appsync-graphql-key languages: - - go - message: Checks for requests sent via http.NewRequest to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. + - regex + message: AWS AppSync GraphQL Key detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://golang.org/pkg/net/http/#NewRequest + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - go - vulnerability: Insecure Transport - pattern: | - http.NewRequest(..., "=~/[hH][tT][tT][pP]://.*/", ...) - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: problem-based-packs.insecure-transport.go-stdlib.http-request.http-request + - secrets + - appsync + pattern-regex: da2-[a-z0-9]{26} + severity: ERROR + - id: generic.secrets.security.detected-aws-secret-access-key.detected-aws-secret-access-key languages: - - go - message: Checks for requests sent via http.$FUNC to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. + - regex + message: AWS Secret Access Key detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://golang.org/pkg/net/http/#Get + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - go - vulnerability: Insecure Transport + - secrets + - aws patterns: - - pattern-either: - - pattern: | - http.$FUNC("=~/[hH][tT][tT][pP]://.*/", ...) - - patterns: - - pattern-inside: | - $CLIENT := &http.Client{...} - ... - - pattern: | - client.$FUNC("=~/[hH][tT][tT][pP]://.*/", ...) - - pattern-not: http.$FUNC("=~/[hH][tT][tT][pP]://127.0.0.1.*/", ...) - - pattern-not: client.$FUNC("=~/[hH][tT][tT][pP]://127.0.0.1.*/", ...) - - pattern-not: http.$FUNC("=~/[hH][tT][tT][pP]://localhost.*/", ...) - - pattern-not: client.$FUNC("=~/[hH][tT][tT][pP]://localhost.*/", ...) - - metavariable-regex: - metavariable: $FUNC - regex: (Get|Post|Head|PostForm) - severity: WARNING - - id: problem-based-packs.insecure-transport.go-stdlib.sling-http-request.sling-http-request + - pattern-regex: (("|'|`)?((?i)aws)_?\w*((?i)secret)_?\w*("|'|`)?\s{0,50}(:|=>|=)\s{0,50}("|'|`)?[A-Za-z0-9/+=]{40}("|'|`)?) + - pattern-not-regex: (?i)example|sample|test|fake|xxxxxx + severity: ERROR + - id: generic.secrets.security.detected-aws-session-token.detected-aws-session-token languages: - - go - message: Checks for requests to http (unencrypted) sites using gorequest, a popular HTTP client library. This is dangerous because it could result in plaintext PII being passed around the network. + - regex + message: AWS Session Token detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://godoc.org/github.com/dghubble/sling#Sling.Add - - https://github.com/dghubble/sling + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - sling - vulnerability: Insecure Transport - pattern-either: - - patterns: - - pattern-inside: | - $REQ = sling.New() - ... - $RES = ... - - pattern: | - $REQ.$FUNC("=~/[hH][tT][tT][pP]://.*/") - - metavariable-regex: - metavariable: $FUNC - regex: (Get|Post|Delete|Head|Put|Options|Patch|Base|Connect) - - patterns: - - pattern: sling.New().$FUNC("=~/[hH][tT][tT][pP]://.*/") - - metavariable-regex: - metavariable: $FUNC - regex: (Get|Post|Delete|Head|Put|Options|Patch|Base|Connect) - - patterns: - - pattern-inside: | - $REQ = sling.New() - ... - $URL = "=~/[hH][tT][tT][pP]://.*/" - ... - $RES = ... - - pattern: | - $REQ.$FUNC($URL) - - metavariable-regex: - metavariable: $FUNC - regex: (Get|Post|Delete|Head|Put|Options|Patch|Base|Connect) - - patterns: - - pattern-inside: | - $URL = "=~/[hH][tT][tT][pP]://.*/" - ... - $RES = ... - - pattern: | - sling.New().$FUNC($URL) - - metavariable-regex: - metavariable: $FUNC - regex: (Get|Post|Delete|Head|Put|Options|Patch|Base|Connect) - severity: WARNING - - id: problem-based-packs.insecure-transport.go-stdlib.telnet-request.telnet-request + - secrets + - aws + patterns: + - pattern-regex: ((?i)AWS_SESSION_TOKEN)\s*(:|=>|=)\s*(?P[A-Za-z0-9/+=]{16,}) + - pattern-not-regex: (?i)example|sample|test|fake + - metavariable-analysis: + analyzer: entropy + metavariable: $TOKEN + severity: ERROR + - id: generic.secrets.security.detected-bcrypt-hash.detected-bcrypt-hash languages: - - go - message: Checks for attempts to connect to an insecure telnet server using the package telnet. This is bad because it can lead to man in the middle attacks. + - regex + message: bcrypt hash detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://godoc.org/github.com/reiver/go-telnet + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures subcategory: - - vuln + - audit technology: - - go-telnet - vulnerability: Insecure Transport - pattern: | - telnet.DialToAndCall(...) - severity: WARNING - - id: problem-based-packs.insecure-transport.java-spring.bypass-tls-verification.bypass-tls-verification + - secrets + - bcrypt + pattern-regex: \$2[aby]?\$[\d]+\$[./A-Za-z0-9]{53} + severity: ERROR + - id: generic.secrets.security.detected-codeclimate.detected-codeclimate languages: - - java - message: Checks for redefinitions of functions that check TLS/SSL certificate verification. This can lead to vulnerabilities, as simple errors in the code can result in lack of proper certificate validation. This should only be used for debugging purposes because it leads to vulnerability to MTM attacks. + - regex + message: CodeClimate detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: HIGH - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://stackoverflow.com/questions/4072585/disabling-ssl-certificate-validation-in-spring-resttemplate - - https://stackoverflow.com/questions/35530558/how-to-fix-unsafe-implementation-of-x509trustmanager-in-android-app?rq=1 + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - spring - vulnerability: Insecure Transport - pattern-either: - - pattern: | - new HostnameVerifier() { - ... - public boolean verify(String hostname, SSLSession session) { - ... - } - ... - }; - - pattern: | - public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { - ... - TrustStrategy $FUNCNAME = (X509Certificate[] chain, String authType) -> ...; - ... - } - - pattern: | - TrustStrategy $FUNCNAME= new TrustStrategy() { - ... - public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { - ... - } - ... - }; - severity: WARNING - - fix-regex: - count: 1 - regex: '[fF][tT][pP]://' - replacement: sftp:// - id: problem-based-packs.insecure-transport.java-spring.spring-ftp-request.spring-ftp-request + - secrets + - codeclimate + pattern-regex: (?i)codeclima.{0,50}["|'|`]?[0-9a-f]{64}["|'|`]? + severity: ERROR + - id: generic.secrets.security.detected-etc-shadow.detected-etc-shadow languages: - - java - message: Checks for outgoing connections to ftp servers via Spring plugin ftpSessionFactory. FTP does not encrypt traffic, possibly leading to PII being sent plaintext over the network. + - regex + message: linux shadow file detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://docs.spring.io/spring-integration/api/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.html#setClientMode-int- + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures subcategory: - - vuln + - audit technology: - - spring - vulnerability: Insecure Transport - pattern-either: - - pattern: | - $SF = new DefaultFtpSessionFactory(...); - ... - $SF.setHost("=~/^[fF][tT][pP]://.*/"); - ... - $SF.$FUNC(...); - - pattern: | - $SF = new DefaultFtpSessionFactory(...); - ... - String $URL = "=~/^[fF][tT][pP]://.*/"; - ... - $SF.setHost($URL); - ... - $SF.$FUNC(...); - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: problem-based-packs.insecure-transport.java-spring.spring-http-request.spring-http-request + - secrets + patterns: + - pattern-regex: ^(\s*)(?Proot:[x!*]*:[0-9]*:[0-9]*) + - focus-metavariable: $ROOT + severity: ERROR + - id: generic.secrets.security.detected-facebook-access-token.detected-facebook-access-token languages: - - java - message: Checks for requests sent via Java Spring RestTemplate API to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. + - regex + message: Facebook Access Token detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#delete-java.lang.String-java.util.Map- - - https://www.baeldung.com/rest-template + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - spring - vulnerability: Insecure Transport - patterns: - - pattern-either: - - pattern: | - $RESTTEMP = new RestTemplate(...); - ... - $RESTTEMP.$FUNC("=~/[hH][tT][tT][pP]://.*/", ...); - - pattern: | - $RESTTEMP = new RestTemplate(...); - ... - String $URL = "=~/[hH][tT][tT][pP]://.*/"; - ... - $RESTTEMP.$FUNC($URL, ...); - - pattern: | - $RESTTEMP = new RestTemplate(...); - ... - $URL = new URI(..., "=~/[hH][tT][tT][pP]://.*/", ...); - ... - $RESTTEMP.$FUNC($URL, ...); - - metavariable-regex: - metavariable: $FUNC - regex: (delete|doExecute|exchange|getForEntity|getForObject|headForHeaders|optionsForAllow|patchForObject|postForEntity|postForLocation|postForObject|put) - severity: WARNING - - id: problem-based-packs.insecure-transport.java-stdlib.bypass-tls-verification.bypass-tls-verification + - secrets + - facebook + pattern-either: + - pattern-regex: EAACEdEose0cBA[0-9A-Za-z]+ + - pattern-regex: EAAAACZAVC6ygB[0-9A-Za-z]+ + - pattern-regex: EAAAAZAw4[0-9A-Za-z]+ + severity: ERROR + - id: generic.secrets.security.detected-facebook-oauth.detected-facebook-oauth languages: - - java - message: Checks for redefinitions of the checkServerTrusted function in the X509TrustManager class that disables TLS/SSL certificate verification. This should only be used for debugging purposes because it leads to vulnerability to MTM attacks. + - regex + message: Facebook OAuth detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://riptutorial.com/java/example/16517/temporarily-disable-ssl-verification--for-testing-purposes- - - https://stackoverflow.com/questions/35530558/how-to-fix-unsafe-implementation-of-x509trustmanager-in-android-app?rq=1 + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport - patterns: - - pattern: | - new X509TrustManager() { - ... - public void checkClientTrusted(X509Certificate[] certs, String authType) {...} - ... - } - - pattern-not: | - new X509TrustManager() { - ... - public void checkServerTrusted(X509Certificate[] certs, String authType) { - ... - throw new CertificateException(...); - ... - } - ... - } - - pattern-not: | - new X509TrustManager() { - ... - public void checkServerTrusted(X509Certificate[] certs, String authType) { - ... - throw new IllegalArgumentException(...); - ... - } - ... - } - severity: WARNING - - id: problem-based-packs.insecure-transport.java-stdlib.disallow-old-tls-versions1.disallow-old-tls-versions1 + - secrets + - facebook + pattern-regex: '[fF][aA][cC][eE][bB][oO][oO][kK].*[tT][oO][kK][eE][nN].*[''|"]?[0-9a-f]{32}[''|"]?' + severity: ERROR + - id: generic.secrets.security.detected-generic-api-key.detected-generic-api-key languages: - - java - message: Detects direct creations of SSLConnectionSocketFactories that don't disallow SSL v2, SSL v3, and TLS v1. SSLSocketFactory can be used to validate the identity of the HTTPS server against a list of trusted certificates. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities. + - regex + message: Generic API Key detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: HIGH - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://stackoverflow.com/questions/26429751/java-http-clients-and-poodle + - https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport + - secrets patterns: - - pattern: | - new SSLConnectionSocketFactory(...); - - pattern-not: | - new SSLConnectionSocketFactory(..., new String[] {"TLSv1.2", "TLSv1.3"}, ...); - - pattern-not: | - new SSLConnectionSocketFactory(..., new String[] {"TLSv1.3", "TLSv1.2"}, ...); - - pattern-not: | - new SSLConnectionSocketFactory(..., new String[] {"TLSv1.3"}, ...); - - pattern-not: | - new SSLConnectionSocketFactory(..., new String[] {"TLSv1.2"}, ...); - - pattern-not-inside: | - (SSLConnectionSocketFactory $SF) = new SSLConnectionSocketFactory(...); ... (TlsConfig $TLSCONFIG) = TlsConfig.custom(). ... .setSupportedProtocols(TLS.V_1_2). ... .build(); ... HttpClientConnectionManager cm = $CM.create(). ... .setSSLSocketFactory($SF). ... .setDefaultTlsConfig($TLSCONFIG). ... .build(); - - pattern-not-inside: | - (SSLConnectionSocketFactory $SF) = new SSLConnectionSocketFactory(...); ... (TlsConfig $TLSCONFIG) = TlsConfig.custom(). ... .setSupportedProtocols(TLS.V_1_3). ... .build(); ... HttpClientConnectionManager cm = $CM.create(). ... .setSSLSocketFactory($SF). ... .setDefaultTlsConfig($TLSCONFIG). ... .build(); - severity: WARNING - - id: problem-based-packs.insecure-transport.java-stdlib.disallow-old-tls-versions2.disallow-old-tls-versions2 + - pattern-regex: '[aA][pP][iI]_?[kK][eE][yY][=_:\s-]+[''|"]?(?[0-9a-zA-Z]{32,45})[''|"]?' + - metavariable-analysis: + analyzer: entropy + metavariable: $SECRET + severity: ERROR + - id: generic.secrets.security.detected-generic-secret.detected-generic-secret languages: - - java - message: Detects setting client protocols to insecure versions of TLS and SSL. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities. + - regex + message: Generic Secret detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://stackoverflow.com/questions/26504653/is-it-possible-to-disable-sslv3-for-all-java-applications + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport + - secrets patterns: - - pattern: $VALUE. ... .setProperty("jdk.tls.client.protocols", "$PATTERNS"); - - metavariable-pattern: - language: generic - metavariable: $PATTERNS - patterns: - - pattern-either: - - pattern: TLS1 - - pattern-regex: ^(.*TLSv1|.*SSLv.*)$ - - pattern-regex: ^(.*TLSv1,.*) - severity: WARNING - - fix-regex: - count: 1 - regex: '[fF][tT][pP]://' - replacement: sftp:// - id: problem-based-packs.insecure-transport.java-stdlib.ftp-request.ftp-request + - pattern-regex: '[sS][eE][cC][rR][eE][tT][:= \t]*[''|\"]?(?[0-9a-zA-Z]{32,45})[''|\"]?' + - metavariable-analysis: + analyzer: entropy + metavariable: $SECRET + severity: ERROR + - id: generic.secrets.security.detected-github-token.detected-github-token languages: - - java - message: Checks for outgoing connections to ftp servers. FTP does not encrypt traffic, possibly leading to PII being sent plaintext over the network. + - generic + message: GitHub Token detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://www.codejava.net/java-se/ftp/connect-and-login-to-a-ftp-server - - https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.blog/changelog/2021-03-04-authentication-token-format-updates/ subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport - pattern-either: - - pattern: | - FTPClient $FTPCLIENT = new FTPClient(); - ... - $FTPCLIENT.connect(...); - - pattern: | - URL $URL = new URL("=~/^[fF][tT][pP]://.*/"); - ... - URLConnection $CONN = $URL.openConnection(...); - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: problem-based-packs.insecure-transport.java-stdlib.http-components-request.http-components-request + - secrets + - github + patterns: + - pattern-either: + - pattern: | + $VAR = $SECRET + - pattern: | + $VAR: $SECRET + - pattern: | + $VAR = '$SECRET' + - pattern: | + $VAR: '$SECRET' + - pattern: | + '$VAR' = '$SECRET' + - pattern: | + '$VAR': '$SECRET' + - pattern: | + "[hH][tT][tT][pP][sS]?://.*$SECRET.*" + - metavariable-regex: + metavariable: $SECRET + regex: gh[pousr]_[A-Za-z0-9_]{36,251} + - metavariable-analysis: + analyzer: entropy + metavariable: $SECRET + severity: ERROR + - id: generic.secrets.security.detected-google-api-key.detected-google-api-key languages: - - java - message: Checks for requests sent via Apache HTTP Components to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. + - regex + message: Google API Key Detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://hc.apache.org/httpcomponents-client-ga/quickstart.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport - pattern-either: - - pattern: | - $HTTPCLIENT = HttpClients.$CREATE(...); - ... - $HTTPREQ = new $HTTPFUNC("=~/[hH][tT][tT][pP]://.*/"); - ... - $RESPONSE = $HTTPCLIENT.execute($HTTPREQ); - - pattern: | - $HTTPCLIENT = HttpClients.$CREATE(...); - ... - $RESPONSE = $HTTPCLIENT.execute(new $HTTPFUNC("=~/[hH][tT][tT][pP]://.*/")); - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: problem-based-packs.insecure-transport.java-stdlib.httpclient-http-request.httpclient-http-request + - secrets + - google + patterns: + - pattern-regex: \bAIzaSy[0-9A-Za-z-_]{33}\b + - pattern-not-regex: \bAIzaSy[0-9A-Za-z-_]{33}\b[=] + severity: ERROR + - id: generic.secrets.security.detected-google-cloud-api-key.detected-google-cloud-api-key languages: - - java - message: Checks for requests sent via HttpClient to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. + - regex + message: Google Cloud API Key detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://openjdk.java.net/groups/net/httpclient/intro.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport - pattern-either: - - patterns: - - pattern: | - URI.create("=~/[hH][tT][tT][pP]://.*/", ...) - - pattern-inside: | - HttpClient $CLIENT = ...; - ... - HttpRequest $REQ = ...; - ... - $CLIENT.sendAsync(...); - - patterns: - - pattern: | - URI.create("=~/[hH][tT][tT][pP]://.*/", ...) - - pattern-inside: | - HttpClient $CLIENT = ...; - ... - HttpRequest $REQ = ...; - ... - $CLIENT.send(...); - - patterns: - - pattern: | - URI.create($URI) - - pattern-inside: | - String $URI = "=~/[hH][tT][tT][pP]://.*/"; - ... - HttpClient $CLIENT = ...; - ... - HttpRequest $REQ = ...; - ... - $CLIENT.send(...); - - patterns: - - pattern: | - URI.create($URI) - - pattern-inside: | - String $URI = "=~/[hH][tT][tT][pP]://.*/"; - ... - HttpClient $CLIENT = ...; - ... - HttpRequest $REQ = ...; - ... - $CLIENT.sendAsync(...); - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: problem-based-packs.insecure-transport.java-stdlib.httpget-http-request.httpget-http-request + - secrets + - google-cloud + pattern-regex: AIza[0-9A-Za-z\\-_]{35} + severity: ERROR + - id: generic.secrets.security.detected-google-gcm-service-account.detected-google-gcm-service-account languages: - - java - message: Detected an HTTP request sent via HttpGet. This could lead to sensitive information being sent over an insecure channel. Instead, it is recommended to send requests over HTTPS. + - regex + message: Google (GCM) Service account detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport - patterns: - - pattern: | - "=~/[Hh][Tt][Tt][Pp]://.*/" - - pattern-inside: | - $R = new HttpGet("=~/[Hh][Tt][Tt][Pp]://.*/"); - ... - $CLIENT. ... .execute($R, ...); - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: problem-based-packs.insecure-transport.java-stdlib.httpurlconnection-http-request.httpurlconnection-http-request + - secrets + - google-cloud + pattern-regex: (("|'|`)?type("|'|`)?\s{0,50}(:|=>|=)\s{0,50}("|'|`)?service_account("|'|`)?,?) + severity: ERROR + - id: generic.secrets.security.detected-google-oauth-access-token.detected-google-oauth-access-token languages: - - java - message: Detected an HTTP request sent via HttpURLConnection. This could lead to sensitive information being sent over an insecure channel. Instead, it is recommended to send requests over HTTPS. + - regex + message: Google OAuth Access Token detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport - patterns: - - pattern: | - "=~/[Hh][Tt][Tt][Pp]://.*/" - - pattern-either: - - pattern-inside: | - URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); - ... - $CON = (HttpURLConnection) $URL.openConnection(...); - ... - $CON.$FUNC(...); - - pattern-inside: | - URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); - ... - $CON = $URL.openConnection(...); - ... - $CON.$FUNC(...); - severity: WARNING - - id: problem-based-packs.insecure-transport.java-stdlib.telnet-request.telnet-request + - secrets + - google + pattern-regex: ya29\.[0-9A-Za-z\-_]+ + severity: ERROR + - id: generic.secrets.security.detected-google-oauth.detected-google-oauth-url languages: - - java - message: Checks for attempts to connect through telnet. This is insecure as the telnet protocol supports no encryption, and data passes through unencrypted. + - regex + message: Google OAuth url detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://commons.apache.org/proper/commons-net/javadocs/api-3.6/org/apache/commons/net/telnet/TelnetClient.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport - pattern: | - $TELNETCLIENT = new TelnetClient(...); - ... - $TELNETCLIENT.connect(...); - severity: WARNING - - id: problem-based-packs.insecure-transport.java-stdlib.tls-renegotiation.tls-renegotiation + - secrets + - google + pattern-regex: '[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com' + severity: ERROR + - id: generic.secrets.security.detected-heroku-api-key.detected-heroku-api-key languages: - - java - message: Checks for cases where java applications are allowing unsafe renegotiation. This leaves the application vulnerable to a man-in-the-middle attack where chosen plain text is injected as prefix to a TLS connection. + - regex + message: Heroku API Key detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM likelihood: LOW - owasp: A03:2017 - Sensitive Data Exposure + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://www.oracle.com/java/technologies/javase/tlsreadme.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport - pattern: | - java.lang.System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", true); - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: problem-based-packs.insecure-transport.java-stdlib.unirest-http-request.unirest-http-request + - secrets + - heroku + pattern-regex: '[hH][eE][rR][oO][kK][uU].*[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}' + severity: ERROR + - id: generic.secrets.security.detected-hockeyapp.detected-hockeyapp languages: - - java - message: Checks for requests sent via Unirest to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. + - regex + message: HockeyApp detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://kong.github.io/unirest-java/#requests + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - unirest - vulnerability: Insecure Transport - pattern-either: - - pattern: | - Unirest.get("=~/[hH][tT][tT][pP]://.*/") - - pattern: | - Unirest.post("=~/[hH][tT][tT][pP]://.*/") - severity: WARNING - - id: problem-based-packs.insecure-transport.js-node.bypass-tls-verification.bypass-tls-verification + - secrets + - hockeyapp + pattern-regex: (?i)hockey.{0,50}(\\\"|'|`)?[0-9a-f]{32}(\\\"|'|`)? + severity: ERROR + - id: generic.secrets.security.detected-jwt-token.detected-jwt-token languages: - - javascript - - typescript - message: Checks for setting the environment variable NODE_TLS_REJECT_UNAUTHORIZED to 0, which disables TLS verification. This should only be used for debugging purposes. Setting the option rejectUnauthorized to false bypasses verification against the list of trusted CAs, which also leads to insecure transport. These options lead to vulnerability to MTM attacks, and should not be used. + - regex + message: JWT token detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-321: Use of Hard-coded Cryptographic Key' impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A02:2021 - Cryptographic Failures references: - - https://nodejs.org/api/https.html#https_https_request_options_callback - - https://stackoverflow.com/questions/20433287/node-js-request-cert-has-expired#answer-29397100 + - https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + source-rule-url: https://github.com/Yelp/detect-secrets/blob/master/detect_secrets/plugins/jwt.py subcategory: - - vuln + - audit technology: - - node.js - vulnerability: Insecure Transport - pattern-either: - - pattern: | - process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; - - pattern: | - {rejectUnauthorized:false} - severity: WARNING - - id: problem-based-packs.insecure-transport.js-node.disallow-old-tls-versions1.disallow-old-tls-versions1 + - secrets + - jwt + pattern-regex: eyJ[A-Za-z0-9-_=]{14,}\.[A-Za-z0-9-_=]{13,}\.?[A-Za-z0-9-_.+/=]*? + severity: ERROR + - id: generic.secrets.security.detected-kolide-api-key.detected-kolide-api-key languages: - - javascript - - typescript - message: Detects direct creations of $HTTPS servers that don't disallow SSL v2, SSL v3, and TLS v1. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities. + - regex + message: Kolide API Key detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://us-cert.cisa.gov/ncas/alerts/TA14-290A - - https://stackoverflow.com/questions/40434934/how-to-disable-the-ssl-3-0-and-tls-1-0-in-nodejs - - https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures subcategory: - - vuln + - audit technology: - - node.js - vulnerability: Insecure Transport - patterns: - - pattern-either: - - pattern-inside: | - $CONST = require('crypto'); - ... - - pattern-inside: | - $CONST = require('constants'); - ... - - pattern-inside: | - $HTTPS = require('https'); - ... - - pattern: | - $HTTPS.createServer(...).$FUNC(...); - - pattern-not: | - $HTTPS.createServer({secureOptions: $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_SSLv2 }, ...).$FUNC(...); - - pattern-not: | - $HTTPS.createServer({secureOptions: $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv2 |$CONST.SSL_OP_NO_SSLv3 }, ...).$FUNC(...); - - pattern-not: | - $HTTPS.createServer({secureOptions: $CONST.SSL_OP_NO_SSLv2 |$CONST.SSL_OP_NO_SSLv3 |$CONST.SSL_OP_NO_TLSv1 }, ...).$FUNC(...); - - pattern-not: | - $HTTPS.createServer({secureOptions: $CONST.SSL_OP_NO_SSLv2 |$CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv3}, ...).$FUNC(...); - - pattern-not: | - $HTTPS.createServer({secureOptions:$CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_SSLv2 |$CONST.SSL_OP_NO_TLSv1}, ...).$FUNC(...); - - pattern-not: | - $HTTPS.createServer({secureOptions:$CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_TLSv1| $CONST.SSL_OP_NO_SSLv2}, ...).$FUNC(...); - severity: WARNING - - id: problem-based-packs.insecure-transport.js-node.disallow-old-tls-versions2.disallow-old-tls-versions2 + - secrets + - kolide + pattern-regex: k2sk_v[0-9]_[0-9a-zA-Z]{24} + severity: ERROR + - id: generic.secrets.security.detected-mailchimp-api-key.detected-mailchimp-api-key languages: - - javascript - - typescript - message: Detects creations of $HTTPS servers from option objects that don't disallow SSL v2, SSL v3, and TLS v1. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities. + - regex + message: MailChimp API Key detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://us-cert.cisa.gov/ncas/alerts/TA14-290A - - https://stackoverflow.com/questions/40434934/how-to-disable-the-ssl-3-0-and-tls-1-0-in-nodejs - - https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - node.js - vulnerability: Insecure Transport - patterns: - - pattern-either: - - pattern-inside: | - $CONST = require('crypto'); - ... - - pattern-inside: | - $CONST = require('constants'); - ... - - pattern-inside: | - $HTTPS = require('https'); - ... - - pattern: | - $OPTIONS = {}; - ... - $HTTPS.createServer($OPTIONS, ...); - - pattern-not: | - $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_SSLv2}; - ... - $HTTPS.createServer($OPTIONS, ...); - - pattern-not: | - $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv2 | $CONST.SSL_OP_NO_SSLv3}; - ... - $HTTPS.createServer($OPTIONS, ...); - - pattern-not: | - $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_SSLv2 | $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv3}; - ... - $HTTPS.createServer($OPTIONS, ...); - - pattern-not: | - $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_SSLv2 | $CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_TLSv1}; - ... - $HTTPS.createServer($OPTIONS, ...); - - pattern-not: | - $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_SSLv2 | $CONST.SSL_OP_NO_TLSv1}; - ... - $HTTPS.createServer($OPTIONS, ...); - - pattern-not: | - $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv2}; - ... - $HTTPS.createServer($OPTIONS, ...); - severity: WARNING - - id: problem-based-packs.insecure-transport.js-node.ftp-request.ftp-request + - secrets + - mailchimp + pattern-regex: '[0-9a-f]{32}-us[0-9]{1,2}' + severity: ERROR + - id: generic.secrets.security.detected-mailgun-api-key.detected-mailgun-api-key languages: - - javascript - - typescript - message: 'Checks for lack of usage of the "secure: true" option when sending ftp requests through the nodejs ftp module. This leads to unencrypted traffic being sent to the ftp server. There are other options such as "implicit" that still does not encrypt all traffic. ftp is the most utilized npm ftp module.' + - regex + message: Mailgun API Key detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://www.npmjs.com/package/ftp - - https://openbase.io/js/ftp + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - node.js - vulnerability: Insecure Transport - patterns: - - pattern-inside: | - $X = require('ftp'); - ... - $C = new $X(); - ... - - pattern-not-inside: | - $OPTIONS = {secure: true}; - ... - - pattern: | - $C.connect($OPTIONS,...); - - pattern-not: | - $C.connect({...,secure: true}); - severity: WARNING - - id: problem-based-packs.insecure-transport.js-node.http-request.http-request + - secrets + - mailgun + pattern-regex: key-[0-9a-zA-Z]{32} + severity: ERROR + - id: generic.secrets.security.detected-npm-registry-auth-token.detected-npm-registry-auth-token languages: - - javascript - message: Checks for requests sent to http:// URLs. This is dangerous as the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, only send requests to https:// URLs. + - generic + message: NPM registry authentication token detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://nodejs.org/api/http.html#http_http_request_options_callback + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures subcategory: - - vuln + - audit technology: - - node.js - vulnerability: Insecure Transport + - secrets + - npm + paths: + include: + - '*npmrc*' patterns: - - pattern-inside: | - $HTTP = require('http'); - ... - - pattern-either: - - pattern: | - $HTTP.request("=~/http://.*/",...); - - pattern: | - $HTTP.get("=~/http://.*/", ...) - - pattern: | - $VAR = new URL("=~/http://.*/"); - ... - $HTTP.request($VAR, ...); - - pattern: | - $VAR = {...,hostname: "..."}; - ... - $HTTP.request(..., $VAR, ...); - - pattern: | - $HTTP.request(..., {...,hostname: "..."}, ...); - - pattern-not: | - $VAR = {...,protocol: "https"}; - ... - $HTTP.request(..., $VAR, ...); - - pattern-not: | - $HTTP.request(..., {...,protocol: "https"}, ...); - severity: WARNING - - id: problem-based-packs.insecure-transport.js-node.rest-http-client-support.rest-http-client-support + - pattern: $AUTHTOKEN = $VALUE + - metavariable-regex: + metavariable: $AUTHTOKEN + regex: _(authToken|auth|password) + - pattern-not: $AUTHTOKEN = ${...} + severity: ERROR + - id: generic.secrets.security.detected-outlook-team.detected-outlook-team languages: - - javascript - message: Checks for requests to http (unencrypted) sites using some of node js's most popular REST/HTTP libraries, including node-rest-client, axios, and got. + - regex + message: Outlook Team detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://www.npmjs.com/package/axios - - https://www.npmjs.com/package/got - - https://www.npmjs.com/package/node-rest-client + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - node.js - vulnerability: Insecure Transport - patterns: - - pattern-either: - - pattern-inside: | - $CLIENT = require('node-rest-client').Client; - ... - $C = new $CLIENT(); - ... - - pattern-inside: | - $C = require('axios'); - ... - - pattern-inside: | - $C = require('got'); - ... - - pattern-either: - - pattern: | - $C.$REQ("=~/http://.*/", ...) - - pattern: | - $C("=~/http://.*/", ...) - - pattern: | - $C({...,url: "=~/http://.*/"}) - - pattern: | - $C.$REQ({...,url: "=~/http://.*/"}) - severity: WARNING - - id: problem-based-packs.insecure-transport.js-node.telnet-request.telnet-request + - secrets + - outlook + pattern-regex: https://outlook\.office\.com/webhook/[0-9a-f-]{36} + severity: ERROR + - id: generic.secrets.security.detected-paypal-braintree-access-token.detected-paypal-braintree-access-token languages: - - javascript - message: Checks for creation of telnet servers or attempts to connect through telnet. This is insecure as the telnet protocol supports no encryption, and data passes through unencrypted. + - regex + message: PayPal Braintree Access Token detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://www.npmjs.com/package/telnet - - https://www.npmjs.com/package/telnet-client + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - node.js - vulnerability: Insecure Transport - patterns: - - pattern-either: - - pattern-inside: | - $TEL = require('telnet-client'); - ... - $SERVER = new $TEL(); - ... - - pattern-inside: | - $SERVER = require('telnet'); - ... - - pattern-either: - - pattern: | - $SERVER.on(...) - - pattern: | - $SERVER.connect(...) - - pattern: | - $SERVER.createServer(...) - severity: WARNING - - id: problem-based-packs.insecure-transport.ruby-stdlib.http-client-requests.http-client-requests + - secrets + - paypal + - braintree + pattern-regex: access_token\$production\$[0-9a-z]{16}\$[0-9a-z]{32} + severity: ERROR + - id: generic.secrets.security.detected-pgp-private-key-block.detected-pgp-private-key-block languages: - - ruby - message: Checks for requests to http (unencrypted) sites using some of ruby's most popular REST/HTTP libraries, including httparty and restclient. + - regex + message: Something that looks like a PGP private key block is detected. This is a potential hardcoded secret that could be leaked if this code is committed. Instead, remove this code block from the commit. metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/rest-client/rest-client - - https://github.com/jnunemaker/httparty/tree/master/docs + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - httparty - - rest-client - vulnerability: Insecure Transport - pattern-either: - - pattern: | - HTTParty.$PARTYVERB("=~/[hH][tT][tT][pP]://.*/", ...) - - pattern: | - $STRING = "=~/[hH][tT][tT][pP]://.*/" - ... - HTTParty.$PARTYVERB($STRING, ...) - - pattern: | - RestClient.$RESTVERB "=~/[hH][tT][tT][pP]://.*/", ... - - pattern: | - RestClient::Request.execute(..., url: "=~/[hH][tT][tT][pP]://.*/", ...) - severity: WARNING - - id: problem-based-packs.insecure-transport.ruby-stdlib.net-ftp-request.net-ftp-request + - secrets + pattern-regex: '-----BEGIN PGP PRIVATE KEY BLOCK-----' + severity: ERROR + - id: generic.secrets.security.detected-picatic-api-key.detected-picatic-api-key languages: - - ruby - message: Checks for outgoing connections to ftp servers with the 'net/ftp' package. FTP does not encrypt traffic, possibly leading to PII being sent plaintext over the network. Instead, connect via the SFTP protocol. + - regex + message: Picatic API Key detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://docs.ruby-lang.org/en/2.0.0/Net/FTP.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - ruby - vulnerability: Insecure Transport - pattern-either: - - pattern: | - $FTP = Net::FTP.new('...') - ... - $FTP.login - - pattern: | - Net::FTP.open('...') do |ftp| - ... - ftp.login - end - severity: WARNING - - id: problem-based-packs.insecure-transport.ruby-stdlib.net-http-request.net-http-request + - secrets + - picatic + pattern-regex: sk_live_[0-9a-z]{32} + severity: ERROR + - id: generic.secrets.security.detected-private-key.detected-private-key languages: - - ruby - message: Checks for requests sent to http:// URLs. This is dangerous as the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, only send requests to https:// URLs. + - generic + message: Private Key detected. This is a sensitive credential and should not be hardcoded here. Instead, store this in a separate, private file. metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://ruby-doc.org/stdlib-2.6.5/libdoc/net/http/rdoc/Net/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - ruby - vulnerability: Insecure Transport + - secrets patterns: - pattern-either: - - pattern: | - $URI = URI('=~/[hH][tT][tT][pP]://.*/') - ... - Net::HTTP::$FUNC.new $URI - - pattern: | - $URI = URI('=~/[hH][tT][tT][pP]://.*/') - ... - Net::HTTP.$FUNC($URI, ...) - - pattern: | - Net::HTTP.$FUNC(URI('=~/[hH][tT][tT][pP]://.*/'), ...) - - metavariable-regex: - metavariable: $FUNC - regex: ([gG]et|post_form|[pP]ost|get_response|get_print|Head|Patch|Put|Proppatch|Lock|Unlock|Options|Propfind|Delete|Move|Copy|Trace|Mkcol) - severity: WARNING - - id: problem-based-packs.insecure-transport.ruby-stdlib.net-telnet-request.net-telnet-request + - patterns: + - pattern: '-----BEGIN $TYPE PRIVATE KEY----- $KEY' + - metavariable-regex: + metavariable: $TYPE + regex: (?i)([dr]sa|ec|openssh|encrypted)? + - patterns: + - pattern: | + -----BEGIN PRIVATE KEY----- + $KEY + - metavariable-analysis: + analyzer: entropy + metavariable: $KEY + severity: ERROR + - id: generic.secrets.security.detected-sauce-token.detected-sauce-token languages: - - ruby - message: Checks for creation of telnet servers or attempts to connect through telnet. This is insecure as the telnet protocol supports no encryption, and data passes through unencrypted. + - regex + message: Sauce Token detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://docs.ruby-lang.org/en/2.2.0/Net/Telnet.html - - https://www.rubydoc.info/gems/net-ssh-telnet2/0.1.0/Net/SSH/Telnet + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - ruby - vulnerability: Insecure Transport - pattern-either: - - pattern: | - Net::Telnet::new(...) - - pattern: | - Net::SSH::Telnet.new(...) - severity: WARNING - - id: problem-based-packs.insecure-transport.ruby-stdlib.openuri-request.openuri-request + - secrets + - sauce + pattern-regex: (?i)sauce.{0,50}(\\\"|'|`)?[0-9a-f-]{36}(\\\"|'|`)? + severity: ERROR + - id: generic.secrets.security.detected-sendgrid-api-key.detected-sendgrid-api-key languages: - - ruby - message: Checks for requests to http and ftp (unencrypted) sites using OpenURI. + - regex + message: SendGrid API Key detected metadata: category: security - confidence: MEDIUM - cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM - owasp: A03:2017 - Sensitive Data Exposure + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://ruby-doc.org/stdlib-2.6.3/libdoc/open-uri/rdoc/OpenURI.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/narendrakadali/gitrob/blob/master/rules/contentsignatures.json subcategory: - - vuln + - audit technology: - - open-uri - vulnerability: Insecure Transport - pattern-either: - - pattern: | - URI.open('=~/[hH][tT][tT][pP]://.*/', ...) - - pattern: | - $URI = URI.parse('=~/[hH][tT][tT][pP]://.*/', ...) - ... - $URI.open - - pattern: | - URI.open('=~/^[fF][tT][pP]://.*/', ...) - - pattern: | - $URI = URI.parse('=~/^[fF][tT][pP]://.*/', ...) - ... - $URI.open - severity: WARNING - - id: python.aws-lambda.security.dangerous-asyncio-create-exec.dangerous-asyncio-create-exec + - secrets + - sendgrid + pattern-regex: SG\.[a-zA-Z0-9]{22}\.[a-zA-Z0-9-]{43}\b + severity: ERROR + - id: generic.secrets.security.detected-slack-token.detected-slack-token languages: - - python - message: Detected 'create_subprocess_exec' function with argument tainted by `event` object. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. + - regex + message: Slack Token detected metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.create_subprocess_exec - - https://docs.python.org/3/library/shlex.html + - https://github.com/davidburkitt/python-secret-scanner/blob/335a1f6dab8de59cf39063e57aea39a58951e939/patterns.txt#L58 + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - python - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $CMD - - pattern-either: - - pattern: asyncio.create_subprocess_exec($PROG, $CMD, ...) - - pattern: asyncio.create_subprocess_exec($PROG, [$CMD, ...], ...) - - pattern: asyncio.subprocess.create_subprocess_exec($PROG, $CMD, ...) - - pattern: asyncio.subprocess.create_subprocess_exec($PROG, [$CMD, ...], ...) - - pattern: asyncio.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...) - - pattern: asyncio.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...], ...) - - pattern: asyncio.subprocess.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...) - - pattern: asyncio.subprocess.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...], ...) - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... + - secrets + - slack + pattern-either: + - pattern-regex: (xox[pboa]-[0-9]{12}-[0-9]{12}-[0-9]{12}-[a-z0-9]{32}) + - pattern-regex: xox.-[0-9]{12}-[0-9]{12}-[0-9a-zA-Z]{24} severity: ERROR - - id: python.aws-lambda.security.dangerous-asyncio-exec.dangerous-asyncio-exec + - id: generic.secrets.security.detected-slack-webhook.detected-slack-webhook languages: - - python - message: Detected subprocess function '$LOOP.subprocess_exec' with argument tainted by `event` object. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. + - regex + message: Slack Webhook detected metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec - - https://docs.python.org/3/library/shlex.html + - https://api.slack.com/messaging/webhooks + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - python - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $CMD - - pattern-either: - - pattern: $LOOP.subprocess_exec($PROTOCOL, $CMD, ...) - - pattern: $LOOP.subprocess_exec($PROTOCOL, [$CMD, ...], ...) - - pattern: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...) - - pattern: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...], ...) - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... + - secrets + - slack + pattern-regex: https://hooks\.slack\.com/services/T[a-zA-Z0-9_]{8,10}/B[a-zA-Z0-9_]{8,10}/[a-zA-Z0-9_]{24} severity: ERROR - - id: python.aws-lambda.security.dangerous-asyncio-shell.dangerous-asyncio-shell + - id: generic.secrets.security.detected-snyk-api-key.detected-snyk-api-key languages: - - python - message: Detected asyncio subprocess function with argument tainted by `event` object. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. + - regex + message: Snyk API Key detected metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://docs.python.org/3/library/asyncio-subprocess.html - - https://docs.python.org/3/library/shlex.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures subcategory: - - vuln + - audit technology: - - python - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $CMD - - pattern-either: - - pattern: $LOOP.subprocess_shell($PROTOCOL, $CMD) - - pattern: asyncio.subprocess.create_subprocess_shell($CMD, ...) - - pattern: asyncio.create_subprocess_shell($CMD, ...) - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... + - secrets + - snyk + pattern-regex: (?i)snyk.{0,50}['|"|`]?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}['"\s]? severity: ERROR - - id: python.aws-lambda.security.dangerous-spawn-process.dangerous-spawn-process + - id: generic.secrets.security.detected-softlayer-api-key.detected-softlayer-api-key languages: - - python - message: Detected `os` function with argument tainted by `event` object. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here. + - regex + message: SoftLayer API Key detected metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/Yelp/detect-secrets/blob/master/detect_secrets/plugins/softlayer.py subcategory: - - vuln + - audit technology: - - python - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $CMD - - pattern-either: - - patterns: - - pattern: os.$METHOD($MODE, $CMD, ...) - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) - - patterns: - - pattern-inside: os.$METHOD($MODE, $BASH, ["-c", $CMD,...],...) - - metavariable-regex: - metavariable: $METHOD - regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-inside: os.$METHOD($MODE, $BASH, "-c", $CMD,...) - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... + - secrets + - softlayer + pattern-regex: (?i)softlayer.{0,50}["|'|`]?[a-z0-9]{64}["|'|`]? severity: ERROR - - id: python.aws-lambda.security.dangerous-subprocess-use.dangerous-subprocess-use + - id: generic.secrets.security.detected-sonarqube-docs-api-key.detected-sonarqube-docs-api-key languages: - - python - message: Detected subprocess function with argument tainted by an `event` object. If this data can be controlled by a malicious actor, it may be an instance of command injection. The default option for `shell` is False, and this is secure by default. Consider removing the `shell=True` or setting it to False explicitely. Using `shell=False` means you have to split the command string into an array of strings for the command and its arguments. You may consider using 'shlex.split()' for this purpose. + - regex + message: SonarQube Docs API Key detected metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://docs.python.org/3/library/subprocess.html - - https://docs.python.org/3/library/shlex.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - python - - aws-lambda - mode: taint - pattern-sanitizers: - - pattern: shlex.split(...) - - pattern: pipes.quote(...) - - pattern: shlex.quote(...) - pattern-sinks: - - patterns: - - pattern: subprocess.$FUNC(..., shell=True, ...) - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... + - secrets + - sonarqube + paths: + exclude: + - '*.svg' + - '*go.sum' + - '*cargo.lock' + - '*package.json' + - '*yarn.lock' + - '*package-lock.json' + - '*bundle.js' + - '*pnpm-lock*' + - '*Podfile.lock' + - '*/openssl/*.h' + - '*.xcscmblueprint' + pattern-regex: (?i)sonar.{0,50}(\\\"|'|`)?[0-9a-f]{40}(\\\"|'|`)? severity: ERROR - - id: python.aws-lambda.security.dangerous-system-call.dangerous-system-call + - id: generic.secrets.security.detected-square-access-token.detected-square-access-token languages: - - python - message: Detected `os` function with argument tainted by `event` object. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. + - regex + message: Square Access Token detected metadata: - asvs: - control_id: 5.2.4 Dyanmic Code Execution Features - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - python - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $CMD - - pattern-either: - - pattern: os.system($CMD,...) - - pattern: os.popen($CMD,...) - - pattern: os.popen2($CMD,...) - - pattern: os.popen3($CMD,...) - - pattern: os.popen4($CMD,...) - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... + - secrets + - square + pattern-regex: sq0atp-[0-9A-Za-z\-_]{22} severity: ERROR - - id: python.aws-lambda.security.dynamodb-filter-injection.dynamodb-filter-injection + - id: generic.secrets.security.detected-square-oauth-secret.detected-square-oauth-secret languages: - - python - message: Detected DynamoDB query filter that is tainted by `$EVENT` object. This could lead to NoSQL injection if the variable is user-controlled and not properly sanitized. Explicitly assign query params instead of passing data from `$EVENT` directly to DynamoDB client. + - regex + message: Square OAuth Secret detected metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-943: Improper Neutralization of Special Elements in Data Query Logic' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A01:2017 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://medium.com/appsecengineer/dynamodb-injection-1db99c2454ac + - https://github.com/Yelp/detect-secrets/blob/master/tests/plugins/square_oauth_test.py + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - python - - boto3 - - aws-lambda - - dynamodb - mode: taint - pattern-sanitizers: - - patterns: - - pattern: | - {...} - pattern-sinks: - - patterns: - - focus-metavariable: $SINK - - pattern-either: - - pattern: $TABLE.scan(..., ScanFilter = $SINK, ...) - - pattern: $TABLE.query(..., QueryFilter = $SINK, ...) - - pattern-either: - - patterns: - - pattern-inside: | - $TABLE = $DB.Table(...) - ... - - pattern-inside: | - $DB = boto3.resource('dynamodb', ...) - ... - - pattern-inside: | - $TABLE = boto3.client('dynamodb', ...) - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... + - secrets + - square + pattern-regex: sq0csp-[0-9A-Za-z\\\-_]{43} severity: ERROR - - id: python.aws-lambda.security.mysql-sqli.mysql-sqli + - id: generic.secrets.security.detected-ssh-password.detected-ssh-password languages: - - python - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute(''SELECT * FROM projects WHERE status = %s'', (''active''))`' + - regex + message: SSH Password detected metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html - - https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-executemany.html + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - - vuln + - audit technology: - - aws-lambda - - mysql - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $CURSOR.execute($QUERY,...) - - pattern: $CURSOR.executemany($QUERY,...) - - pattern-either: - - pattern-inside: | - import mysql - ... - - pattern-inside: | - import mysql.cursors - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... - severity: WARNING - - id: python.aws-lambda.security.psycopg-sqli.psycopg-sqli + - secrets + - ssh + pattern-regex: sshpass -p\s*['|\\\"][^%] + severity: ERROR + - id: generic.secrets.security.detected-stripe-api-key.detected-stripe-api-key languages: - - python - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute(''SELECT * FROM projects WHERE status = %s'', ''active'')`' + - regex + message: Stripe API Key detected metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://www.psycopg.org/docs/cursor.html#cursor.execute - - https://www.psycopg.org/docs/cursor.html#cursor.executemany - - https://www.psycopg.org/docs/cursor.html#cursor.mogrify + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - aws-lambda - - psycopg - - psycopg2 - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $CURSOR.execute($QUERY,...) - - pattern: $CURSOR.executemany($QUERY,...) - - pattern: $CURSOR.mogrify($QUERY,...) - - pattern-inside: | - import psycopg2 - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... - severity: WARNING - - id: python.aws-lambda.security.pymssql-sqli.pymssql-sqli + - secrets + - stripe + pattern-regex: sk_live_[0-9a-zA-Z]{24} + severity: ERROR + - id: generic.secrets.security.detected-stripe-restricted-api-key.detected-stripe-restricted-api-key languages: - - python - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute(''SELECT * FROM projects WHERE status = %s'', ''active'')`' + - regex + message: Stripe Restricted API Key detected metadata: category: security confidence: MEDIUM cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + subcategory: + - audit + technology: + - secrets + - stripe + pattern-regex: rk_live_[0-9a-zA-Z]{24} + severity: ERROR + - id: generic.secrets.security.detected-telegram-bot-api-key.detected-telegram-bot-api-key + languages: + - regex + message: Telegram Bot API Key detected + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://pypi.org/project/pymssql/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - aws-lambda - - pymssql - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern: $CURSOR.execute($QUERY,...) - - pattern-inside: | - import pymssql - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... - severity: WARNING - - id: python.aws-lambda.security.pymysql-sqli.pymysql-sqli + - secrets + - telegram + patterns: + - pattern-regex: '[0-9]+:AA[0-9A-Za-z\-_]{33}' + - pattern-not-regex: go\.mod.* + - pattern-not-regex: v[\d]+\.[\d]+\.[\d]+.* + severity: ERROR + - id: generic.secrets.security.detected-twilio-api-key.detected-twilio-api-key languages: - - python - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute(''SELECT * FROM projects WHERE status = %s'', (''active''))`' + - regex + message: Twilio API Key detected metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://pypi.org/project/PyMySQL/#id4 + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json subcategory: - - vuln + - audit technology: - - aws-lambda - - pymysql - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern: $CURSOR.execute($QUERY,...) - - pattern-either: - - pattern-inside: | - import pymysql - ... - - pattern-inside: | - import pymysql.cursors - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... - severity: WARNING - - id: python.aws-lambda.security.sqlalchemy-sqli.sqlalchemy-sqli + - secrets + - twilio + pattern-regex: SK[0-9a-fA-F]{32} + severity: ERROR + - id: generic.secrets.security.detected-username-and-password-in-uri.detected-username-and-password-in-uri languages: - - python - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute(''SELECT * FROM projects WHERE status = ?'', ''active'')`' + - generic + message: Username and password in URI detected metadata: category: security confidence: MEDIUM cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A07:2021 - Identification and Authentication Failures references: - - https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Connection.execute + - https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go subcategory: - vuln technology: - - aws-lambda - - sqlalchemy - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern: $CURSOR.execute($QUERY,...) - - pattern-inside: | - import sqlalchemy - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... + - secrets + patterns: + - pattern: $PROTOCOL://$...USERNAME:$...PASSWORD@$END + - metavariable-regex: + metavariable: $...USERNAME + regex: \A({?)([A-Za-z])([A-Za-z0-9_-]){5,31}(}?)\Z + - metavariable-regex: + metavariable: $...PASSWORD + regex: (?!.*[\s])(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]){6,32} + - metavariable-regex: + metavariable: $PROTOCOL + regex: (.*http.*)|(.*sql.*)|(.*ftp.*)|(.*smtp.*) + severity: ERROR + - id: generic.secrets.security.google-maps-apikeyleak.google-maps-apikeyleak + languages: + - generic + message: Detects potential Google Maps API keys in code + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-538: Insertion of Sensitive Information into Externally-Accessible File or Directory' + description: Detects potential Google Maps API keys in code + impact: HIGH + likelihood: MEDIUM + owasp: + - A3:2017 Sensitive Data Exposure + references: + - https://ozguralp.medium.com/unauthorized-google-maps-api-key-usage-cases-and-why-you-need-to-care-1ccb28bf21e + severity: MEDIUM + subcategory: + - audit + technology: + - Google Maps + patterns: + - pattern-regex: ^(AIza[0-9A-Za-z_-]{35}(?!\S))$ severity: WARNING - - id: python.aws-lambda.security.tainted-code-exec.tainted-code-exec + - id: generic.unicode.security.bidi.contains-bidirectional-characters languages: + - bash + - c + - cpp + - csharp + - go + - java + - javascript + - json + - kotlin + - lua + - ocaml + - php - python - message: Detected the use of `exec/eval`.This can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources. + - ruby + - rust + - scala + - sh + - typescript + - yaml + message: This code contains bidirectional (bidi) characters. While this is useful for support of right-to-left languages such as Arabic or Hebrew, it can also be used to trick language parsers into executing code in a manner that is different from how it is displayed in code editing and review tools. If this is not what you were expecting, please review this code in an editor that can reveal hidden Unicode characters. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://trojansource.codes/ + subcategory: + - audit + technology: + - unicode + patterns: + - pattern-either: + - pattern-regex: ‪ + - pattern-regex: ‫ + - pattern-regex: ‭ + - pattern-regex: ‮ + - pattern-regex: ⁦ + - pattern-regex: ⁧ + - pattern-regex: ⁨ + - pattern-regex: ‬ + - pattern-regex: ⁩ + severity: WARNING + - id: generic.visualforce.security.ncino.html.usesriforcdns.use-sri-for-cdns + languages: + - generic + message: 'Consuming CDNs without including a SubResource Integrity (SRI) can expose your application and its users to compromised code. SRIs allow you to consume specific versions of content where if even a single byte is compromised, the resource will not be loaded. Add an integrity attribute to your + - pattern-not: + severity: ERROR + - id: generic.visualforce.security.ncino.xml.cspheaderattribute.csp-header-attribute languages: - - python - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates which will safely render HTML instead. + - generic + message: Visualforce Pages must have the cspHeader attribute set to true. This attribute is available in API version 55 or higher. metadata: category: security - confidence: MEDIUM + confidence: HIGH cwe: - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true @@ -14395,91 +10041,58 @@ rules: - A07:2017 - Cross-Site Scripting (XSS) - A03:2021 - Injection references: - - https://owasp.org/Top10/A03_2021-Injection + - https://help.salesforce.com/s/articleView?id=sf.csp_trusted_sites.htm&type=5 subcategory: - vuln technology: - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: '"$HTMLSTR" % ...' - - pattern: '"$HTMLSTR".format(...)' - - pattern: '"$HTMLSTR" + ...' - - pattern: f"$HTMLSTR{...}..." - - patterns: - - pattern-inside: | - $HTML = "$HTMLSTR" - ... - - pattern-either: - - pattern: $HTML % ... - - pattern: $HTML.format(...) - - pattern: $HTML + ... - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - - pattern-not-inside: | - print(...) - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... - severity: WARNING - - id: python.aws-lambda.security.tainted-pickle-deserialization.tainted-pickle-deserialization + - salesforce + - visualforce + paths: + include: + - '*.page' + patterns: + - pattern: ... + - pattern-not: ... + - pattern-not: ...... + - pattern-not: ...... + severity: INFO + - id: generic.visualforce.security.ncino.xml.visualforceapiversion.visualforce-page-api-version languages: - - python - message: Avoid using `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. + - generic + message: Visualforce Pages must use API version 55 or higher for required use of the cspHeader attribute set to true. metadata: category: security - confidence: MEDIUM + confidence: HIGH cwe: - - 'CWE-502: Deserialization of Untrusted Data' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: HIGH owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://docs.python.org/3/library/pickle.html - - https://davidhamann.de/2020/04/05/exploiting-python-pickle/ + - https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_pages.htm subcategory: - vuln technology: - - python - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $SINK - - pattern-either: - - pattern: pickle.load($SINK,...) - - pattern: pickle.loads($SINK,...) - - pattern: _pickle.load($SINK,...) - - pattern: _pickle.loads($SINK,...) - - pattern: cPickle.load($SINK,...) - - pattern: cPickle.loads($SINK,...) - - pattern: dill.load($SINK,...) - - pattern: dill.loads($SINK,...) - - pattern: shelve.open($SINK,...) - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... + - salesforce + - visualforce + paths: + include: + - '*.page-meta.xml' + patterns: + - pattern-inside: + - pattern-either: + - pattern-regex: '[>][0-9].[0-9][<]' + - pattern-regex: '[>][1-4][0-9].[0-9][<]' + - pattern-regex: '[>][5][0-4].[0-9][<]' severity: WARNING - - id: python.aws-lambda.security.tainted-sql-string.tainted-sql-string + - id: go.aws-lambda.security.database-sqli.database-sqli languages: - - python - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + - go + message: Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use prepared statements with the 'Prepare' and 'PrepareContext' calls. metadata: category: security confidence: MEDIUM @@ -14493,10937 +10106,82277 @@ rules: - A01:2017 - Injection - A03:2021 - Injection references: - - https://owasp.org/www-community/attacks/SQL_Injection + - https://pkg.go.dev/database/sql#DB.Query subcategory: - vuln technology: - aws-lambda + - database + - sql mode: taint pattern-sinks: - patterns: + - focus-metavariable: $QUERY - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR" % ... - - pattern: | - "$SQLSTR".format(...) - - pattern: | - f"$SQLSTR{...}..." - - metavariable-regex: - metavariable: $SQLSTR - regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*= - - pattern-not-inside: | - print(...) + - pattern: $DB.Exec($QUERY,...) + - pattern: $DB.ExecContent($QUERY,...) + - pattern: $DB.Query($QUERY,...) + - pattern: $DB.QueryContext($QUERY,...) + - pattern: $DB.QueryRow($QUERY,...) + - pattern: $DB.QueryRowContext($QUERY,...) + - pattern-inside: | + import "database/sql" + ... pattern-sources: - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context): - ... - severity: ERROR - - id: python.boto3.security.hardcoded-token.hardcoded-token + - pattern-either: + - pattern-inside: | + func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...} + ... + lambda.Start($HANDLER, ...) + - patterns: + - pattern-inside: | + func $HANDLER($EVENT $TYPE) {...} + ... + lambda.Start($HANDLER, ...) + - pattern-not-inside: | + func $HANDLER($EVENT context.Context) {...} + ... + lambda.Start($HANDLER, ...) + - focus-metavariable: $EVENT + severity: WARNING + - id: go.aws-lambda.security.tainted-sql-string.tainted-sql-string languages: - - python - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - - https://bento.dev/checks/boto3/hardcoded-access-token/ - - https://aws.amazon.com/blogs/security/what-to-do-if-you-inadvertently-expose-an-aws-access-key/ + - https://owasp.org/www-community/attacks/SQL_Injection subcategory: - vuln technology: - - boto3 - - secrets + - aws-lambda mode: taint + pattern-sanitizers: + - pattern: strconv.Atoi(...) pattern-sinks: - patterns: - pattern-either: - - pattern: $W(...,$TOKEN="$VALUE",...) - - pattern: $BOTO. ... .$W(...,$TOKEN="$VALUE",...) - - metavariable-regex: - metavariable: $TOKEN - regex: (aws_session_token|aws_access_key_id|aws_secret_access_key) - - metavariable-pattern: - language: generic - metavariable: $VALUE - patterns: + - patterns: + - pattern: | + "$SQLSTR" + ... + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(\s*select|\s*delete|\s*insert|\s*create|\s*update|\s*alter|\s*drop).* + - patterns: - pattern-either: - - pattern-regex: ^AKI - - pattern-regex: ^[A-Za-z0-9/+=]+$ - - metavariable-analysis: - analyzer: entropy - metavariable: $VALUE + - pattern: fmt.Fprintf($F, "$SQLSTR", ...) + - pattern: fmt.Sprintf("$SQLSTR", ...) + - pattern: fmt.Printf("$SQLSTR", ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).* + - pattern-not-inside: | + log.$PRINT(...) pattern-sources: - - pattern: | - "..." - severity: WARNING - - id: python.cryptography.security.empty-aes-key.empty-aes-key - languages: - - python - message: Potential empty AES encryption key. Using an empty key in AES encryption can result in weak encryption and may allow attackers to easily decrypt sensitive data. Ensure that a strong, non-empty key is used for AES encryption. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - - 'CWE-310: Cryptographic Issues' - functional-categories: - - crypto::search::key-length::pycrypto - - crypto::search::key-length::pycryptodome - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: A6:2017 misconfiguration - references: - - https://cwe.mitre.org/data/definitions/327.html - - https://cwe.mitre.org/data/definitions/310.html - subcategory: - - vuln - technology: - - python - - pycrypto - - pycryptodome - patterns: - - pattern: AES.new("",...) - severity: WARNING - - fix: AES - id: python.cryptography.security.insecure-cipher-algorithms-arc4.insecure-cipher-algorithm-arc4 + - patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...} + ... + lambda.Start($HANDLER, ...) + - patterns: + - pattern-inside: | + func $HANDLER($EVENT $TYPE) {...} + ... + lambda.Start($HANDLER, ...) + - pattern-not-inside: | + func $HANDLER($EVENT context.Context) {...} + ... + lambda.Start($HANDLER, ...) + - focus-metavariable: $EVENT + severity: ERROR + - id: go.gorilla.security.audit.handler-assignment-from-multiple-sources.handler-assignment-from-multiple-sources languages: - - python - message: ARC4 (Alleged RC4) is a stream cipher with serious weaknesses in its initial stream output. Its use is strongly discouraged. ARC4 does not use mode constructions. Use a strong symmetric cipher such as EAS instead. With the `cryptography` package it is recommended to use the `Fernet` which is a secure implementation of AES in CBC mode with a 128-bit key. Alternatively, keep using the `Cipher` class from the hazmat primitives but use the AES algorithm instead. + - go + message: 'Variable $VAR is assigned from two different sources: ''$Y'' and ''$R''. Make sure this is intended, as this could cause logic bugs if they are treated as they are the same object.' metadata: - bandit-code: B304 category: security confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::cryptography + - 'CWE-289: Authentication Bypass by Alternate Name' impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW references: - - https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#weak-ciphers - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L98 + - https://cwe.mitre.org/data/definitions/289.html subcategory: - - vuln + - audit technology: - - cryptography - patterns: - - pattern: cryptography.hazmat.primitives.ciphers.algorithms.$ARC4($KEY) - - pattern-inside: cryptography.hazmat.primitives.ciphers.Cipher(...) - - metavariable-regex: - metavariable: $ARC4 - regex: ^(ARC4)$ - - focus-metavariable: $ARC4 + - gorilla + mode: taint + pattern-sinks: + - patterns: + - pattern: | + $Y, err := store.Get(...) + ... + $VAR := $Y.Values[...] + ... + $VAR = $R + - focus-metavariable: $R + - patterns: + - pattern: | + $Y, err := store.Get(...) + ... + var $VAR $INT = $Y.Values["..."].($INT) + ... + $VAR = $R + - focus-metavariable: $R + pattern-sources: + - patterns: + - pattern-inside: | + func $HANDLER(..., $R *http.Request, ...) { + ... + } + - focus-metavariable: $R + - pattern-either: + - pattern: $R.query severity: WARNING - - fix: AES - id: python.cryptography.security.insecure-cipher-algorithms-blowfish.insecure-cipher-algorithm-blowfish + - fix-regex: + regex: (HttpOnly\s*:\s+)false + replacement: \1true + id: go.gorilla.security.audit.session-cookie-missing-httponly.session-cookie-missing-httponly languages: - - python - message: Blowfish is a block cipher developed by Bruce Schneier. It is known to be susceptible to attacks when using weak keys. The author has recommended that users of Blowfish move to newer algorithms such as AES. With the `cryptography` package it is recommended to use `Fernet` which is a secure implementation of AES in CBC mode with a 128-bit key. Alternatively, keep using the `Cipher` class from the hazmat primitives but use the AES algorithm instead. + - go + message: A session cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie which mitigates XSS attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' in the Options struct. metadata: - bandit-code: B304 category: security confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::cryptography - impact: MEDIUM - likelihood: MEDIUM + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A05:2021 - Security Misconfiguration references: - - https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#weak-ciphers - - https://tools.ietf.org/html/rfc5469 - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L98 + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 subcategory: - - vuln + - audit technology: - - cryptography + - gorilla patterns: - - pattern: cryptography.hazmat.primitives.ciphers.algorithms.$BLOWFISH($KEY) - - metavariable-regex: - metavariable: $BLOWFISH - regex: ^(Blowfish)$ - - focus-metavariable: $BLOWFISH + - pattern-not-inside: | + &sessions.Options{ + ..., + HttpOnly: true, + ..., + } + - pattern: | + &sessions.Options{ + ..., + } severity: WARNING - - fix: AES - id: python.cryptography.security.insecure-cipher-algorithms.insecure-cipher-algorithm-idea + - fix-regex: + regex: (Secure\s*:\s+)false + replacement: \1true + id: go.gorilla.security.audit.session-cookie-missing-secure.session-cookie-missing-secure languages: - - python - message: IDEA (International Data Encryption Algorithm) is a block cipher created in 1991. It is an optional component of the OpenPGP standard. This cipher is susceptible to attacks when using weak keys. It is recommended that you do not use this cipher for new applications. Use a strong symmetric cipher such as EAS instead. With the `cryptography` package it is recommended to use `Fernet` which is a secure implementation of AES in CBC mode with a 128-bit key. Alternatively, keep using the `Cipher` class from the hazmat primitives but use the AES algorithm instead. + - go + message: A session cookie was detected without setting the 'Secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'Secure' flag by setting 'Secure' to 'true' in the Options struct. metadata: - bandit-code: B304 category: security confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::cryptography - impact: MEDIUM - likelihood: MEDIUM + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A05:2021 - Security Misconfiguration references: - - https://tools.ietf.org/html/rfc5469 - - https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#cryptography.hazmat.primitives.ciphers.algorithms.IDEA - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L98 + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 subcategory: - - vuln + - audit technology: - - cryptography + - gorilla patterns: - - pattern: cryptography.hazmat.primitives.ciphers.algorithms.$IDEA($KEY) - - metavariable-regex: - metavariable: $IDEA - regex: ^(IDEA)$ - - focus-metavariable: $IDEA + - pattern-not-inside: | + &sessions.Options{ + ..., + Secure: true, + ..., + } + - pattern: | + &sessions.Options{ + ..., + } severity: WARNING - - fix: cryptography.hazmat.primitives.ciphers.modes.GCM($IV) - id: python.cryptography.security.insecure-cipher-mode-ecb.insecure-cipher-mode-ecb + - fix-regex: + regex: (SameSite\s*:\s+)http.SameSiteNoneMode + replacement: \1http.SameSiteDefaultMode + id: go.gorilla.security.audit.session-cookie-samesitenone.session-cookie-samesitenone languages: - - python - message: ECB (Electronic Code Book) is the simplest mode of operation for block ciphers. Each block of data is encrypted in the same way. This means identical plaintext blocks will always result in identical ciphertext blocks, which can leave significant patterns in the output. Use a different, cryptographically strong mode instead, such as GCM. + - go + message: Found SameSiteNoneMode setting in Gorilla session options. Consider setting SameSite to Lax, Strict or Default for enhanced security. metadata: - bandit-code: B305 category: security confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::mode::cryptography + - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' impact: LOW likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A05:2021 - Security Misconfiguration references: - - https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#insecure-modes - - https://crypto.stackexchange.com/questions/20941/why-shouldnt-i-use-ecb-encryption - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L101 + - https://pkg.go.dev/github.com/gorilla/sessions#Options subcategory: - audit technology: - - cryptography - pattern: cryptography.hazmat.primitives.ciphers.modes.ECB($IV) + - gorilla + patterns: + - pattern-inside: | + &sessions.Options{ + ..., + SameSite: http.SameSiteNoneMode, + ..., + } + - pattern: | + &sessions.Options{ + ..., + } severity: WARNING - - fix: SHA256 - id: python.cryptography.security.insecure-hash-algorithms-md5.insecure-hash-algorithm-md5 + - id: go.gorilla.security.audit.websocket-missing-origin-check.websocket-missing-origin-check languages: - - python - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - go + message: 'The Origin header in the HTTP WebSocket handshake is used to guarantee that the connection accepted by the WebSocket is from a trusted origin domain. Failure to enforce can lead to Cross Site Request Forgery (CSRF). As per "gorilla/websocket" documentation: "A CheckOrigin function should carefully validate the request origin to prevent cross-site request forgery."' metadata: - bandit-code: B303 category: security confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::cryptography - impact: MEDIUM + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A01:2021 - Broken Access Control references: - - https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/#md5 - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + - https://pkg.go.dev/github.com/gorilla/websocket#Upgrader subcategory: - - vuln + - audit technology: - - cryptography + - gorilla patterns: - - pattern: cryptography.hazmat.primitives.hashes.$MD5() - - metavariable-regex: - metavariable: $MD5 - regex: ^(MD5)$ - - focus-metavariable: $MD5 + - pattern-inside: | + import ("github.com/gorilla/websocket") + ... + - patterns: + - pattern-not-inside: | + $UPGRADER = websocket.Upgrader{..., CheckOrigin: $FN ,...} + ... + - pattern-not-inside: | + $UPGRADER.CheckOrigin = $FN2 + ... + - pattern: | + $UPGRADER.Upgrade(...) severity: WARNING - - fix: | - SHA256 - id: python.cryptography.security.insecure-hash-algorithms.insecure-hash-algorithm-sha1 + - id: go.gorm.security.audit.gorm-dangerous-methods-usage.gorm-dangerous-method-usage languages: - - python - message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - go + message: Detected usage of dangerous method $METHOD which does not escape inputs (see link in references). If the argument is user-controlled, this can lead to SQL injection. When using $METHOD function, do not trust user-submitted data and only allow approved list of input (possibly, use an allowlist approach). metadata: - bandit-code: B303 category: security - confidence: MEDIUM + confidence: HIGH cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::cryptography + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: HIGH owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/#sha-1 - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + - https://gorm.io/docs/security.html#SQL-injection-Methods + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - cryptography - patterns: - - pattern: cryptography.hazmat.primitives.hashes.$SHA(...) - - metavariable-pattern: - metavariable: $SHA - pattern: | - SHA1 - - focus-metavariable: $SHA + - gorm + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern-either: + - pattern: strconv.Atoi(...) + - pattern: | + ($X: bool) + pattern-sinks: + - patterns: + - pattern-inside: | + import ("gorm.io/gorm") + ... + - patterns: + - pattern-inside: | + func $VAL(..., $GORM *gorm.DB,... ) { + ... + } + - pattern-either: + - pattern: | + $GORM. ... .$METHOD($VALUE) + - pattern: | + $DB := $GORM. ... .$ANYTHING(...) + ... + $DB. ... .$METHOD($VALUE) + - focus-metavariable: $VALUE + - metavariable-regex: + metavariable: $METHOD + regex: ^(Order|Exec|Raw|Group|Having|Distinct|Select|Pluck)$ + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ severity: WARNING - - fix: | - 2048 - id: python.cryptography.security.insufficient-dsa-key-size.insufficient-dsa-key-size + - fix-regex: + regex: (.*)WithInsecure\(.*?\) + replacement: \1WithTransportCredentials(credentials.NewTLS()) + id: go.grpc.security.grpc-client-insecure-connection.grpc-client-insecure-connection languages: - - python - message: Detected an insufficient key size for DSA. NIST recommends a key size of 2048 or higher. + - go + message: 'Found an insecure gRPC connection using ''grpc.WithInsecure()''. This creates a connection without encryption to a gRPC server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. Instead, establish a secure connection with an SSL certificate using the ''grpc.WithTransportCredentials()'' function. You can create a create credentials using a ''tls.Config{}'' struct with ''credentials.NewTLS()''. The final fix looks like this: ''grpc.WithTransportCredentials(credentials.NewTLS())''.' metadata: category: security - confidence: MEDIUM + confidence: HIGH cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::key-length::cryptography - impact: MEDIUM - likelihood: MEDIUM + - 'CWE-300: Channel Accessible by Non-Endpoint' + impact: LOW + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://www.cosic.esat.kuleuven.be/ecrypt/ecrypt2/documents/D.SPA.20.pdf - - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/dsa/ - - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py + - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption subcategory: - - vuln + - audit technology: - - cryptography - patterns: - - pattern-either: - - pattern: cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key(..., key_size=$SIZE, ...) - - pattern: cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key($SIZE, ...) - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - - focus-metavariable: $SIZE - severity: WARNING - - fix: | - SECP256R1 - id: python.cryptography.security.insufficient-ec-key-size.insufficient-ec-key-size + - grpc + pattern: $GRPC.Dial($ADDR, ..., $GRPC.WithInsecure(...), ...) + severity: ERROR + - id: go.grpc.security.grpc-server-insecure-connection.grpc-server-insecure-connection languages: - - python - message: Detected an insufficient curve size for EC. NIST recommends a key size of 224 or higher. For example, use 'ec.SECP256R1'. + - go + message: Found an insecure gRPC server without 'grpc.Creds()' or options with credentials. This allows for a connection without encryption to this server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. Include credentials derived from an SSL certificate in order to create a secure gRPC connection. You can create credentials using 'credentials.NewServerTLSFromFile("cert.pem", "cert.key")'. metadata: category: security - confidence: MEDIUM + confidence: HIGH cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::key-length::cryptography - impact: MEDIUM - likelihood: MEDIUM + - 'CWE-300: Channel Accessible by Non-Endpoint' + impact: LOW + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf - - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/#elliptic-curves - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py + - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption subcategory: - audit technology: - - cryptography - patterns: - - pattern-inside: cryptography.hazmat.primitives.asymmetric.ec.generate_private_key(...) - - pattern: cryptography.hazmat.primitives.asymmetric.ec.$SIZE - - metavariable-pattern: - metavariable: $SIZE - pattern-either: - - pattern: SECP192R1 - - pattern: SECT163K1 - - pattern: SECT163R2 - - focus-metavariable: $SIZE - severity: WARNING - - fix: | - 2048 - id: python.cryptography.security.insufficient-rsa-key-size.insufficient-rsa-key-size + - grpc + mode: taint + pattern-sinks: + - pattern: grpc.NewServer($OPT, ...) + requires: OPTIONS and not CREDS + - pattern: grpc.NewServer() + requires: EMPTY_CONSTRUCTOR + pattern-sources: + - label: OPTIONS + pattern: grpc.ServerOption{ ... } + - label: CREDS + pattern: grpc.Creds(...) + - label: EMPTY_CONSTRUCTOR + pattern: grpc.NewServer() + severity: ERROR + - id: go.jwt-go.security.audit.jwt-parse-unverified.jwt-go-parse-unverified languages: - - python - message: Detected an insufficient key size for RSA. NIST recommends a key size of 2048 or higher. + - go + message: Detected the decoding of a JWT token without a verify step. Don't use `ParseUnverified` unless you know what you're doing This method parses the token but doesn't validate the signature. It's only ever useful in cases where you know the signature is valid (because it has been checked previously in the stack) and you want to extract values from it. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::key-length::cryptography - impact: MEDIUM - likelihood: MEDIUM + - 'CWE-345: Insufficient Verification of Data Authenticity' + impact: LOW + likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A08:2021 - Software and Data Integrity Failures references: - - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/ - - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py + - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ subcategory: - audit technology: - - cryptography + - jwt patterns: - - pattern-either: - - pattern: cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key(..., key_size=$SIZE, ...) - - pattern: cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key($EXP, $SIZE, ...) - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - - focus-metavariable: $SIZE + - pattern-inside: | + import "github.com/dgrijalva/jwt-go" + ... + - pattern: | + $JWT.ParseUnverified(...) severity: WARNING - - id: python.cryptography.security.mode-without-authentication.crypto-mode-without-authentication + - id: go.jwt-go.security.jwt-none-alg.jwt-go-none-algorithm languages: - - python - message: 'An encryption mode of operation is being used without proper message authentication. This can potentially result in the encrypted content to be decrypted by an attacker. Consider instead use an AEAD mode of operation like GCM. ' + - go + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. metadata: category: security - confidence: MEDIUM + confidence: HIGH cwe: - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM + impact: LOW likelihood: LOW owasp: - A03:2017 - Sensitive Data Exposure - A02:2021 - Cryptographic Failures references: - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ subcategory: - audit technology: - - cryptography + - jwt patterns: - pattern-either: - - patterns: - - pattern: | - Cipher(..., $HAZMAT_MODE(...),...) - - pattern-not-inside: | - Cipher(..., $HAZMAT_MODE(...),...) - ... - HMAC(...) - - pattern-not-inside: | - Cipher(..., $HAZMAT_MODE(...),...) - ... - hmac.HMAC(...) - - metavariable-pattern: - metavariable: $HAZMAT_MODE - patterns: - - pattern-either: - - pattern: modes.CTR - - pattern: modes.CBC - - pattern: modes.CFB - - pattern: modes.OFB + - pattern-inside: | + import "github.com/golang-jwt/jwt" + ... + - pattern-inside: | + import "github.com/dgrijalva/jwt-go" + ... + - pattern-either: + - pattern: | + jwt.SigningMethodNone + - pattern: jwt.UnsafeAllowNoneSignatureType severity: ERROR - - fix: | - True - id: python.distributed.security.require-encryption + - id: go.jwt-go.security.jwt.hardcoded-jwt-key languages: - - python - message: Initializing a security context for Dask (`distributed`) without "require_encryption" keyword argument may silently fail to provide security. + - go + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security confidence: MEDIUM cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + interfile: true + likelihood: HIGH owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2021 - Identification and Authentication Failures references: - - https://distributed.dask.org/en/latest/tls.html?highlight=require_encryption#parameters + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html subcategory: - vuln technology: - - distributed + - jwt + - secrets + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $TOKEN.SignedString($F) + - focus-metavariable: $F + pattern-sources: + - patterns: + - pattern-inside: | + []byte("$F") + severity: WARNING + - id: go.lang.best-practice.channel-guarded-with-mutex.channel-guarded-with-mutex + languages: + - go + message: Detected a channel guarded with a mutex. Channels already have an internal mutex, so this is unnecessary. Remove the mutex. See https://hackmongo.com/page/golang-antipatterns/#guarded-channel for more information. + metadata: + category: best-practice + technology: + - go + pattern-either: + - pattern: | + $MUX.Lock() + $VALUE <- $CHANNEL + $MUX.Unlock() + - pattern: | + $MUX.Lock() + $VALUE = <- $CHANNEL + $MUX.Unlock() + severity: WARNING + - id: go.lang.best-practice.hidden-goroutine.hidden-goroutine + languages: + - go + message: Detected a hidden goroutine. Function invocations are expected to synchronous, and this function will execute asynchronously because all it does is call a goroutine. Instead, remove the internal goroutine and call the function using 'go'. + metadata: + category: best-practice + technology: + - go patterns: + - pattern-not: | + func $FUNC(...) { + go func() { + ... + }(...) + $MORE + } - pattern: | - distributed.security.Security(..., require_encryption=$VAL, ...) - - metavariable-pattern: - metavariable: $VAL - pattern: | - False - - focus-metavariable: $VAL + func $FUNC(...) { + go func() { + ... + }(...) + } severity: WARNING - - id: python.django.security.audit.avoid-insecure-deserialization.avoid-insecure-deserialization + - id: go.lang.correctness.looppointer.exported_loop_pointer languages: - - python - message: Avoid using insecure deserialization library, backed by `pickle`, `_pickle`, `cpickle`, `dill`, `shelve`, or `yaml`, which are known to lead to remote code execution vulnerabilities. + - go + message: '`$VALUE` is a loop pointer that may be exported from the loop. This pointer is shared between loop iterations, so the exported reference will always point to the last loop value, which is likely unintentional. To fix, copy the pointer to a new pointer within the loop.' metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures + category: correctness references: - - https://docs.python.org/3/library/pickle.html - subcategory: - - vuln + - https://github.com/kyoh86/looppointer technology: - - django - mode: taint - pattern-sinks: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - pickle.$PICKLEFUNC(...) - - pattern: | - _pickle.$PICKLEFUNC(...) - - pattern: | - cPickle.$PICKLEFUNC(...) - - pattern: | - shelve.$PICKLEFUNC(...) - - metavariable-regex: - metavariable: $PICKLEFUNC - regex: dumps|dump|load|loads - - patterns: - - pattern: dill.$DILLFUNC(...) - - metavariable-regex: - metavariable: $DILLFUNC - regex: dump|dump_session|dumps|load|load_session|loads - - patterns: - - pattern: yaml.$YAMLFUNC(...) - - pattern-not: yaml.$YAMLFUNC(..., Dumper=SafeDumper, ...) - - pattern-not: yaml.$YAMLFUNC(..., Dumper=yaml.SafeDumper, ...) - - pattern-not: yaml.$YAMLFUNC(..., Loader=SafeLoader, ...) - - pattern-not: yaml.$YAMLFUNC(..., Loader=yaml.SafeLoader, ...) - - metavariable-regex: - metavariable: $YAMLFUNC - regex: dump|dump_all|load|load_all - pattern-sources: - - pattern-either: - - patterns: - - pattern-inside: | - def $INSIDE(..., $PARAM, ...): - ... - - pattern-either: - - pattern: request.$REQFUNC(...) - - pattern: request.$REQFUNC.get(...) - - pattern: request.$REQFUNC[...] - severity: ERROR - - id: python.django.security.django-no-csrf-token.django-no-csrf-token + - go + pattern-either: + - pattern: | + for _, $VALUE := range $SOURCE { + <... &($VALUE) ...> + } + - pattern: | + for _, $VALUE := range $SOURCE { + <... func() { <... &$VALUE ...> } ...> + } + - pattern: | + for _, $VALUE := range $SOURCE { + <... $ANYTHING(..., <... &$VALUE ...>, ...) ...> + } + severity: WARNING + - id: go.lang.correctness.overflow.overflow.integer-overflow-int16 languages: - - generic - message: Manually-created forms in django templates should specify a csrf_token to prevent CSRF attacks + - go + message: Detected conversion of the result of a strconv.Atoi command to an int16. This could lead to an integer overflow, which could possibly result in unexpected behavior and even privilege escalation. Instead, use `strconv.ParseInt`. metadata: - category: security - confidence: MEDIUM - cwe: 'CWE-352: Cross-Site Request Forgery (CSRF)' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://docs.djangoproject.com/en/4.2/howto/csrf/ - subcategory: - - guardrail + category: correctness technology: - - django - paths: - include: - - '*.html' + - go patterns: - - pattern: ... - - pattern-either: - - pattern: | -
...
- - pattern: | -
...
- - pattern: | -
...
- - metavariable-regex: - metavariable: $METHOD - regex: (?i)(post|put|delete|patch) - - pattern-not-inside: ...{% csrf_token %}... - - pattern-not-inside: ...{{ $VAR.csrf_token }}... + - pattern: | + $F, $ERR := strconv.Atoi($NUM) + ... + int16($F) + - metavariable-comparison: + comparison: $NUM > 32767 or $NUM < -32768 + metavariable: $NUM + strip: true severity: WARNING - - id: python.django.security.django-using-request-post-after-is-valid.django-using-request-post-after-is-valid + - id: go.lang.correctness.overflow.overflow.integer-overflow-int32 languages: - - python - message: Use $FORM.cleaned_data[] instead of request.POST[] after form.is_valid() has been executed to only access sanitized data + - go + message: Detected conversion of the result of a strconv.Atoi command to an int32. This could lead to an integer overflow, which could possibly result in unexpected behavior and even privilege escalation. Instead, use `strconv.ParseInt`. metadata: - category: security - confidence: MEDIUM - cwe: 'CWE-20: Improper Input Validation' - impact: MEDIUM - likelihood: MEDIUM + category: correctness + technology: + - go + patterns: + - pattern: | + $F, $ERR := strconv.Atoi($NUM) + ... + int32($F) + - metavariable-comparison: + comparison: $NUM > 2147483647 or $NUM < -2147483648 + metavariable: $NUM + strip: true + severity: WARNING + - fix: | + 0600 + id: go.lang.correctness.permissions.file_permission.incorrect-default-permission + languages: + - go + message: Detected file permissions that are set to more than `0600` (user/owner can read and write). Setting file permissions to higher than `0600` is most likely unnecessary and violates the principle of least privilege. Instead, set permissions to be `0600` or less for os.Chmod, os.Mkdir, os.OpenFile, os.MkdirAll, and ioutil.WriteFile + metadata: + category: correctness + cwe: 'CWE-276: Incorrect Default Permissions' references: - - https://docs.djangoproject.com/en/4.2/ref/forms/api/#accessing-clean-data - subcategory: - - guardrail + - https://github.com/securego/gosec/blob/master/rules/fileperms.go + source_rule_url: https://github.com/securego/gosec technology: - - django + - go patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-inside: | - if $FORM.is_valid(): - ... - pattern-either: - - pattern: request.POST[...] - - pattern: request.POST.get(...) + - pattern: os.Chmod($NAME, $PERM) + - pattern: os.Mkdir($NAME, $PERM) + - pattern: os.OpenFile($NAME, $FLAG, $PERM) + - pattern: os.MkdirAll($NAME, $PERM) + - pattern: ioutil.WriteFile($NAME, $DATA, $PERM) + - metavariable-comparison: + base: 8 + comparison: $PERM > 0o600 + metavariable: $PERM + - focus-metavariable: + - $PERM severity: WARNING - - id: python.django.security.hashids-with-django-secret.hashids-with-django-secret + - id: go.lang.correctness.use-filepath-join.use-filepath-join languages: - - python - message: The Django 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 Django secret key can be obtained by attackers, through the HashIDs. + - go + message: '`path.Join(...)` always joins using a forward slash. This may cause issues on Windows or other systems using a different delimiter. Use `filepath.Join(...)` instead which uses OS-specific path separators.' metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + category: correctness + confidence: LOW impact: HIGH likelihood: LOW - owasp: - - A02:2021 – Cryptographic Failures references: - - https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-SECRET_KEY - - http://carnage.github.io/2015/08/cryptanalysis-of-hashids + - https://parsiya.net/blog/2019-03-09-path.join-considered-harmful/ + - https://go.dev/src/path/path.go?s=4034:4066#L145 subcategory: - - vuln + - audit technology: - - django + - go + mode: taint + pattern-sanitizers: + - pattern: | + url.Parse(...) + ... + pattern-sinks: + - pattern: path.Join(...) + pattern-sources: + - patterns: + - pattern: | + ($STR : string) + - pattern-not: | + "..." + - patterns: + - pattern-inside: | + import "path" + ... + - pattern: path.$FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: ^(Base|Clean|Dir|Split)$ + - patterns: + - pattern-inside: | + import "path/filepath" + ... + - pattern: filepath.$FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: ^(Base|Clean|Dir|FromSlash|Glob|Rel|Split|SplitList|ToSlash|VolumeName)$ + severity: WARNING + - id: go.lang.correctness.useless-eqeq.eqeq-is-bad + languages: + - go + message: Detected useless comparison operation `$X == $X` or `$X != $X`. This will always return 'True' or 'False' and therefore is not necessary. Instead, remove this comparison operation or use another comparison expression that is not deterministic. + metadata: + category: correctness + technology: + - go + patterns: + - pattern-not-inside: assert(...) + - pattern-either: + - pattern: $X == $X + - pattern: $X != $X + - pattern-not: 1 == 1 + severity: INFO + - id: go.lang.correctness.useless-eqeq.hardcoded-eq-true-or-false + languages: + - go + message: Detected useless if statement. 'if (True)' and 'if (False)' always result in the same behavior, and therefore is not necessary in the code. Remove the 'if (False)' expression completely or just the 'if (True)' comparison depending on which expression is in the code. + metadata: + category: correctness + technology: + - go pattern-either: - - pattern: hashids.Hashids(..., salt=django.conf.settings.SECRET_KEY, ...) - - pattern: hashids.Hashids(django.conf.settings.SECRET_KEY, ...) - severity: ERROR - - id: python.django.security.injection.code.user-eval-format-string.user-eval-format-string + - pattern: if (true) { ... } + - pattern: if (false) { ... } + severity: INFO + - id: go.lang.maintainability.useless-ifelse.useless-if-conditional languages: - - python - message: Found user data in a call to 'eval'. This is extremely dangerous because it can enable an attacker to execute remote code. See https://owasp.org/www-community/attacks/Code_Injection for more information. + - go + message: Detected an if block that checks for the same condition on both branches (`$X`). The second condition check is useless as it is the same as the first, and therefore can be removed from the code, + metadata: + category: maintainability + technology: + - go + pattern: | + if ($X) { + ... + } else if ($X) { + ... + } + severity: WARNING + - id: go.lang.maintainability.useless-ifelse.useless-if-body + languages: + - go + message: Detected identical statements in the if body and the else body of an if-statement. This will lead to the same code being executed no matter what the if-expression evaluates to. Instead, remove the if statement. + metadata: + category: maintainability + technology: + - go + pattern: | + if ($X) { + $S + } else { + $S + } + severity: WARNING + - id: go.lang.security.audit.crypto.bad_imports.insecure-module-used + languages: + - go + message: The package `net/http/cgi` is on the import blocklist. The package is vulnerable to httpoxy attacks (CVE-2015-5386). It is recommended to use `net/http` or a web framework to build a web application instead. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM likelihood: MEDIUM owasp: - - A03:2021 - Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html + - https://godoc.org/golang.org/x/crypto/sha3 + source-rule-url: https://github.com/securego/gosec subcategory: - - vuln + - audit technology: - - django - patterns: - - pattern-inside: | - def $F(...): - ... - - pattern-either: - - pattern: eval(..., $STR % request.$W.get(...), ...) - - pattern: | - $V = request.$W.get(...) - ... - eval(..., $STR % $V, ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = $STR % $V - ... - eval(..., $S, ...) - - pattern: eval(..., "..." % request.$W(...), ...) - - pattern: | - $V = request.$W(...) - ... - eval(..., $STR % $V, ...) - - pattern: | - $V = request.$W(...) - ... - $S = $STR % $V - ... - eval(..., $S, ...) - - pattern: eval(..., $STR % request.$W[...], ...) - - pattern: | - $V = request.$W[...] - ... - eval(..., $STR % $V, ...) - - pattern: | - $V = request.$W[...] - ... - $S = $STR % $V - ... - eval(..., $S, ...) - - pattern: eval(..., $STR.format(..., request.$W.get(...), ...), ...) - - pattern: | - $V = request.$W.get(...) - ... - eval(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = $STR.format(..., $V, ...) - ... - eval(..., $S, ...) - - pattern: eval(..., $STR.format(..., request.$W(...), ...), ...) - - pattern: | - $V = request.$W(...) - ... - eval(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W(...) - ... - $S = $STR.format(..., $V, ...) - ... - eval(..., $S, ...) - - pattern: eval(..., $STR.format(..., request.$W[...], ...), ...) - - pattern: | - $V = request.$W[...] - ... - eval(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W[...] - ... - $S = $STR.format(..., $V, ...) - ... - eval(..., $S, ...) - - pattern: | - $V = request.$W.get(...) - ... - eval(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = f"...{$V}..." - ... - eval(..., $S, ...) - - pattern: | - $V = request.$W(...) - ... - eval(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W(...) - ... - $S = f"...{$V}..." - ... - eval(..., $S, ...) - - pattern: | - $V = request.$W[...] + - go + pattern-either: + - patterns: + - pattern-inside: | + import "net/http/cgi" ... - eval(..., f"...{$V}...", ...) - pattern: | - $V = request.$W[...] - ... - $S = f"...{$V}..." - ... - eval(..., $S, ...) + cgi.$FUNC(...) severity: WARNING - - id: python.django.security.injection.code.user-eval.user-eval + - id: go.lang.security.audit.crypto.insecure_ssh.avoid-ssh-insecure-ignore-host-key languages: - - python - message: Found user data in a call to 'eval'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. + - go + message: Disabled host key verification detected. This allows man-in-the-middle attacks. Use the 'golang.org/x/crypto/ssh/knownhosts' package to do host key verification. See https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ to learn more about the problem and how to fix it. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM + - 'CWE-322: Key Exchange without Entity Authentication' + impact: LOW + likelihood: LOW owasp: - - A03:2021 - Injection + - A02:2021 - Cryptographic Failures references: - - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html - - https://owasp.org/www-community/attacks/Code_Injection + - https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ + - https://gist.github.com/Skarlso/34321a230cf0245018288686c9e70b2d + source-rule-url: https://github.com/securego/gosec subcategory: - - vuln + - audit technology: - - django - patterns: - - pattern-inside: | - def $F(...): - ... - - pattern-either: - - pattern: eval(..., request.$W.get(...), ...) - - pattern: | - $V = request.$W.get(...) - ... - eval(..., $V, ...) - - pattern: eval(..., request.$W(...), ...) - - pattern: | - $V = request.$W(...) - ... - eval(..., $V, ...) - - pattern: eval(..., request.$W[...], ...) - - pattern: | - $V = request.$W[...] - ... - eval(..., $V, ...) + - go + pattern: ssh.InsecureIgnoreHostKey() severity: WARNING - - id: python.django.security.injection.code.user-exec-format-string.user-exec-format-string + - fix: | + crypto/rand + id: go.lang.security.audit.crypto.math_random.math-random-used languages: - - python - message: Found user data in a call to 'exec'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. + - go + message: Do not use `math/rand`. Use `crypto/rand` instead. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH + - 'CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)' + impact: MEDIUM likelihood: MEDIUM owasp: - - A03:2021 - Injection + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/www-community/attacks/Code_Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#secure-random-number-generation subcategory: - vuln technology: - - django + - go patterns: - - pattern-inside: | - def $F(...): - ... - pattern-either: - - pattern: exec(..., $STR % request.$W.get(...), ...) - - pattern: | - $V = request.$W.get(...) - ... - exec(..., $STR % $V, ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = $STR % $V - ... - exec(..., $S, ...) - - pattern: exec(..., "..." % request.$W(...), ...) - - pattern: | - $V = request.$W(...) - ... - exec(..., $STR % $V, ...) - - pattern: | - $V = request.$W(...) - ... - $S = $STR % $V - ... - exec(..., $S, ...) - - pattern: exec(..., $STR % request.$W[...], ...) - - pattern: | - $V = request.$W[...] - ... - exec(..., $STR % $V, ...) - - pattern: | - $V = request.$W[...] - ... - $S = $STR % $V - ... - exec(..., $S, ...) - - pattern: exec(..., $STR.format(..., request.$W.get(...), ...), ...) - - pattern: | - $V = request.$W.get(...) - ... - exec(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = $STR.format(..., $V, ...) - ... - exec(..., $S, ...) - - pattern: exec(..., $STR.format(..., request.$W(...), ...), ...) - - pattern: | - $V = request.$W(...) - ... - exec(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W(...) - ... - $S = $STR.format(..., $V, ...) - ... - exec(..., $S, ...) - - pattern: exec(..., $STR.format(..., request.$W[...], ...), ...) - - pattern: | - $V = request.$W[...] - ... - exec(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W[...] - ... - $S = $STR.format(..., $V, ...) - ... - exec(..., $S, ...) - - pattern: | - $V = request.$W.get(...) - ... - exec(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = f"...{$V}..." - ... - exec(..., $S, ...) - - pattern: | - $V = request.$W(...) - ... - exec(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W(...) - ... - $S = f"...{$V}..." - ... - exec(..., $S, ...) - - pattern: | - $V = request.$W[...] - ... - exec(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W[...] - ... - $S = f"...{$V}..." - ... - exec(..., $S, ...) - - pattern: exec(..., base64.decodestring($S.format(..., request.$W.get(...), ...), ...), ...) - - pattern: exec(..., base64.decodestring($S % request.$W.get(...), ...), ...) - - pattern: exec(..., base64.decodestring(f"...{request.$W.get(...)}...", ...), ...) - - pattern: exec(..., base64.decodestring(request.$W.get(...), ...), ...) - - pattern: exec(..., base64.decodestring(bytes($S.format(..., request.$W.get(...), ...), ...), ...), ...) - - pattern: exec(..., base64.decodestring(bytes($S % request.$W.get(...), ...), ...), ...) - - pattern: exec(..., base64.decodestring(bytes(f"...{request.$W.get(...)}...", ...), ...), ...) - - pattern: exec(..., base64.decodestring(bytes(request.$W.get(...), ...), ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - exec(..., base64.decodestring($DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = base64.decodestring($DATA, ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = base64.decodestring(bytes($DATA, ...), ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - exec(..., base64.decodestring($DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = base64.decodestring($DATA, ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = base64.decodestring(bytes($DATA, ...), ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - exec(..., base64.decodestring($DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = base64.decodestring($DATA, ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = base64.decodestring(bytes($DATA, ...), ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - exec(..., base64.decodestring($DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = base64.decodestring($DATA, ...) - ... - exec(..., $INTERM, ...) - pattern: | - $DATA = request.$W - ... - exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) + import $RAND "$MATH" - pattern: | - $DATA = request.$W + import "$MATH" + - metavariable-regex: + metavariable: $MATH + regex: ^(math/rand(\/v[0-9]+)*)$ + - pattern-either: + - pattern-inside: | ... - $INTERM = base64.decodestring(bytes($DATA, ...), ...) + rand.$FUNC(...) + - pattern-inside: | ... - exec(..., $INTERM, ...) + $RAND.$FUNC(...) + - focus-metavariable: + - $MATH severity: WARNING - - id: python.django.security.injection.code.user-exec.user-exec + - fix: | + tls.Config{ $...CONF, MinVersion: tls.VersionTLS13 } + id: go.lang.security.audit.crypto.missing-ssl-minversion.missing-ssl-minversion languages: - - python - message: Found user data in a call to 'exec'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. + - go + message: '`MinVersion` is missing from this TLS configuration. By default, TLS 1.2 is currently used as the minimum when acting as a client, and TLS 1.0 when acting as a server. General purpose web applications should default to TLS 1.3 with all other protocols disabled. Only where it is known that a web server must support legacy clients with unsupported an insecure browsers (such as Internet Explorer 10), it may be necessary to enable TLS 1.0 to provide support. Add `MinVersion: tls.VersionTLS13'' to the TLS configuration to bump the minimum version to TLS 1.3.' metadata: category: security - confidence: MEDIUM + confidence: HIGH cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: LOW likelihood: MEDIUM owasp: - - A03:2021 - Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/www-community/attacks/Code_Injection + - https://golang.org/doc/go1.14#crypto/tls + - https://golang.org/pkg/crypto/tls/#:~:text=MinVersion + - https://www.us-cert.gov/ncas/alerts/TA14-290A + source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go subcategory: - - vuln + - guardrail technology: - - django + - go patterns: - - pattern-inside: | - def $F(...): - ... - - pattern-either: - - pattern: exec(..., request.$W.get(...), ...) - - pattern: | - $V = request.$W.get(...) - ... - exec(..., $V, ...) - - pattern: exec(..., request.$W(...), ...) - - pattern: | - $V = request.$W(...) - ... - exec(..., $V, ...) - - pattern: exec(..., request.$W[...], ...) - - pattern: | - $V = request.$W[...] - ... - exec(..., $V, ...) - - pattern: | - loop = asyncio.get_running_loop() - ... - await loop.run_in_executor(None, exec, request.$W[...]) - - pattern: | - $V = request.$W[...] - ... - loop = asyncio.get_running_loop() - ... - await loop.run_in_executor(None, exec, $V) - - pattern: | - loop = asyncio.get_running_loop() - ... - await loop.run_in_executor(None, exec, request.$W.get(...)) - - pattern: | - $V = request.$W.get(...) - ... - loop = asyncio.get_running_loop() - ... - await loop.run_in_executor(None, exec, $V) + - pattern: | + tls.Config{ $...CONF } + - pattern-not: | + tls.Config{..., MinVersion: ..., ...} severity: WARNING - - id: python.django.security.injection.command.command-injection-os-system.command-injection-os-system + - fix-regex: + regex: VersionSSL30 + replacement: VersionTLS13 + id: go.lang.security.audit.crypto.ssl.ssl-v3-is-insecure languages: - - python - message: Request data detected in os.system. This could be vulnerable to a command injection and should be avoided. If this must be done, use the 'subprocess' module instead and pass the arguments as a list. See https://owasp.org/www-community/attacks/Command_Injection for more information. + - go + message: SSLv3 is insecure because it has known vulnerabilities. Starting with go1.14, SSLv3 will be removed. Instead, use 'tls.VersionTLS13'. metadata: category: security - confidence: MEDIUM + confidence: HIGH cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: LOW likelihood: MEDIUM owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/www-community/attacks/Command_Injection + - https://golang.org/doc/go1.14#crypto/tls + - https://www.us-cert.gov/ncas/alerts/TA14-290A + source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go subcategory: - vuln technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: os.system(..., request.$W.get(...), ...) - - pattern: os.system(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: os.system(..., $S % request.$W.get(...), ...) - - pattern: os.system(..., f"...{request.$W.get(...)}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - os.system(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - os.system(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - os.system(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - os.system(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - os.system(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - os.system(..., $INTERM, ...) - - pattern: $A = os.system(..., request.$W.get(...), ...) - - pattern: $A = os.system(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $A = os.system(..., $S % request.$W.get(...), ...) - - pattern: $A = os.system(..., f"...{request.$W.get(...)}...", ...) - - pattern: return os.system(..., request.$W.get(...), ...) - - pattern: return os.system(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: return os.system(..., $S % request.$W.get(...), ...) - - pattern: return os.system(..., f"...{request.$W.get(...)}...", ...) - - pattern: os.system(..., request.$W(...), ...) - - pattern: os.system(..., $S.format(..., request.$W(...), ...), ...) - - pattern: os.system(..., $S % request.$W(...), ...) - - pattern: os.system(..., f"...{request.$W(...)}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - os.system(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - os.system(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - os.system(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - os.system(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - os.system(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - os.system(..., $INTERM, ...) - - pattern: $A = os.system(..., request.$W(...), ...) - - pattern: $A = os.system(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $A = os.system(..., $S % request.$W(...), ...) - - pattern: $A = os.system(..., f"...{request.$W(...)}...", ...) - - pattern: return os.system(..., request.$W(...), ...) - - pattern: return os.system(..., $S.format(..., request.$W(...), ...), ...) - - pattern: return os.system(..., $S % request.$W(...), ...) - - pattern: return os.system(..., f"...{request.$W(...)}...", ...) - - pattern: os.system(..., request.$W[...], ...) - - pattern: os.system(..., $S.format(..., request.$W[...], ...), ...) - - pattern: os.system(..., $S % request.$W[...], ...) - - pattern: os.system(..., f"...{request.$W[...]}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - os.system(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - os.system(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - os.system(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - os.system(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - os.system(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - os.system(..., $INTERM, ...) - - pattern: $A = os.system(..., request.$W[...], ...) - - pattern: $A = os.system(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $A = os.system(..., $S % request.$W[...], ...) - - pattern: $A = os.system(..., f"...{request.$W[...]}...", ...) - - pattern: return os.system(..., request.$W[...], ...) - - pattern: return os.system(..., $S.format(..., request.$W[...], ...), ...) - - pattern: return os.system(..., $S % request.$W[...], ...) - - pattern: return os.system(..., f"...{request.$W[...]}...", ...) - - pattern: os.system(..., request.$W, ...) - - pattern: os.system(..., $S.format(..., request.$W, ...), ...) - - pattern: os.system(..., $S % request.$W, ...) - - pattern: os.system(..., f"...{request.$W}...", ...) - - pattern: | - $DATA = request.$W - ... - os.system(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - os.system(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - os.system(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - os.system(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - os.system(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - os.system(..., $INTERM, ...) - - pattern: $A = os.system(..., request.$W, ...) - - pattern: $A = os.system(..., $S.format(..., request.$W, ...), ...) - - pattern: $A = os.system(..., $S % request.$W, ...) - - pattern: $A = os.system(..., f"...{request.$W}...", ...) - - pattern: return os.system(..., request.$W, ...) - - pattern: return os.system(..., $S.format(..., request.$W, ...), ...) - - pattern: return os.system(..., $S % request.$W, ...) - - pattern: return os.system(..., f"...{request.$W}...", ...) - severity: ERROR - - id: python.django.security.injection.command.subprocess-injection.subprocess-injection + - go + pattern: 'tls.Config{..., MinVersion: $TLS.VersionSSL30, ...}' + severity: WARNING + - id: go.lang.security.audit.crypto.tls.tls-with-insecure-cipher languages: - - python - message: Detected user input entering a `subprocess` call unsafely. This could result in a command injection vulnerability. An attacker could use this vulnerability to execute arbitrary commands on the host, which allows them to download malware, scan sensitive data, or run any command they wish on the server. Do not let users choose the command to run. In general, prefer to use Python API versions of system commands. If you must use subprocess, use a dictionary to allowlist a set of commands. + - go + message: Detected an insecure CipherSuite via the 'tls' module. This suite is considered weak. Use the function 'tls.CipherSuites()' to get a list of good cipher suites. See https://golang.org/pkg/crypto/tls/#InsecureCipherSuites for why and what other cipher suites to use. metadata: category: security confidence: HIGH cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: LOW + likelihood: HIGH owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + - https://golang.org/pkg/crypto/tls/#InsecureCipherSuites + source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls.go subcategory: - vuln technology: - - flask - mode: taint - options: - symbolic_propagation: true - pattern-sanitizers: - - patterns: - - pattern: $DICT[$KEY] - - focus-metavariable: $KEY - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: subprocess.$FUNC(...) - - pattern-not: subprocess.$FUNC("...", ...) - - pattern-not: subprocess.$FUNC(["...", ...], ...) - - pattern-not-inside: | - $CMD = ["...", ...] - ... - subprocess.$FUNC($CMD, ...) - - patterns: - - pattern: subprocess.$FUNC(["$SHELL", "-c", ...], ...) - - metavariable-regex: - metavariable: $SHELL - regex: ^(sh|bash|ksh|csh|tcsh|zsh)$ - - patterns: - - pattern: subprocess.$FUNC(["$INTERPRETER", ...], ...) - - metavariable-regex: - metavariable: $INTERPRETER - regex: ^(python|python\d)$ - pattern-sources: - - patterns: - - pattern-inside: | - def $FUNC(..., $REQUEST, ...): - ... - - focus-metavariable: $REQUEST - - metavariable-pattern: - metavariable: $REQUEST - patterns: - - pattern: request - - pattern-not-inside: request.build_absolute_uri - severity: ERROR - - id: python.django.security.injection.csv-writer-injection.csv-writer-injection + - go + pattern-either: + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_RC4_128_SHA, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_AES_128_CBC_SHA256, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ...}} + - pattern: | + tls.CipherSuite{..., TLS_RSA_WITH_RC4_128_SHA, ...} + - pattern: | + tls.CipherSuite{..., TLS_RSA_WITH_3DES_EDE_CBC_SHA, ...} + - pattern: | + tls.CipherSuite{..., TLS_RSA_WITH_AES_128_CBC_SHA256, ...} + - pattern: | + tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, ...} + - pattern: | + tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_RC4_128_SHA, ...} + - pattern: | + tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, ...} + - pattern: | + tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ...} + - pattern: | + tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ...} + severity: WARNING + - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-md5 languages: - - python - message: Detected user input into a generated CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs. + - go + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-1236: Improper Neutralization of Formula Elements in a CSV File' + - 'CWE-328: Use of Weak Hash' impact: MEDIUM likelihood: MEDIUM owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://github.com/raphaelm/defusedcsv - - https://owasp.org/www-community/attacks/CSV_Injection - - https://web.archive.org/web/20220516052229/https://www.contextis.com/us/blog/comma-separated-vulnerabilities + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://github.com/securego/gosec#available-rules subcategory: - vuln technology: - - django - - python - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - $WRITER = csv.writer(...) - - ... - - $WRITER.$WRITE(...) - - pattern: $WRITER.$WRITE(...) - - metavariable-regex: - metavariable: $WRITE - regex: ^(writerow|writerows|writeheader)$ - pattern-sources: - - patterns: - - pattern-inside: | - def $FUNC(..., $REQUEST, ...): - ... - - focus-metavariable: $REQUEST - - metavariable-pattern: - metavariable: $REQUEST - patterns: - - pattern: request - - pattern-not-inside: request.build_absolute_uri - severity: ERROR - - id: python.django.security.injection.email.xss-html-email-body.xss-html-email-body + - go + patterns: + - pattern-inside: | + import "crypto/md5" + ... + - pattern-either: + - pattern: | + md5.New() + - pattern: | + md5.Sum(...) + severity: WARNING + - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-sha1 languages: - - python - message: Found request data in an EmailMessage that is set to use HTML. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS. + - go + message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component (''Injection'')' + - 'CWE-328: Use of Weak Hash' impact: MEDIUM likelihood: MEDIUM owasp: - - A03:2021 - Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://www.damonkohler.com/2008/12/email-injection.html + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://github.com/securego/gosec#available-rules subcategory: - vuln technology: - - django + - go patterns: - pattern-inside: | - def $FUNC(...): - ... - $EMAIL.content_subtype = "html" - ... + import "crypto/sha1" + ... - pattern-either: - - pattern: django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.EmailMessage($SUBJ, $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) + sha1.New() - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + sha1.Sum(...) + severity: WARNING + - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-des + languages: + - go + message: Detected DES cipher algorithm which is insecure. The algorithm is considered weak and has been deprecated. Use AES instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://github.com/securego/gosec#available-rules + subcategory: + - vuln + technology: + - go + patterns: + - pattern-inside: | + import "crypto/des" + ... + - pattern-either: - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) + des.NewTripleDESCipher(...) - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) - - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) - - pattern: django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) + des.NewCipher(...) + severity: WARNING + - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-rc4 + languages: + - go + message: Detected RC4 cipher algorithm which is insecure. The algorithm has many known vulnerabilities. Use AES instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://github.com/securego/gosec#available-rules + subcategory: + - vuln + technology: + - go + patterns: + - pattern-inside: | + import "crypto/rc4" + ... + - pattern: rc4.NewCipher(...) + severity: WARNING + - fix: | + 2048 + id: go.lang.security.audit.crypto.use_of_weak_rsa_key.use-of-weak-rsa-key + languages: + - go + message: RSA keys should be at least 2048 bits + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms + source-rule-url: https://github.com/securego/gosec/blob/master/rules/rsa.go + subcategory: + - audit + technology: + - go + patterns: + - pattern-either: - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.EmailMessage($SUBJ, $DATA, ...) + rsa.GenerateKey(..., $BITS) - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) - - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) - - pattern: django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.EmailMessage($SUBJ, $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) - - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) - - pattern: django.core.mail.EmailMessage($SUBJ, request.$W, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.EmailMessage($SUBJ, $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W, ...) - - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W, ...) + rsa.GenerateMultiPrimeKey(..., $BITS) + - metavariable-comparison: + comparison: $BITS < 2048 + metavariable: $BITS + - focus-metavariable: + - $BITS severity: WARNING - - id: python.django.security.injection.email.xss-send-mail-html-message.xss-send-mail-html-message + - id: go.lang.security.audit.dangerous-command-write.dangerous-command-write languages: - - python - message: Found request data in 'send_mail(...)' that uses 'html_message'. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS. + - go + message: Detected non-static command inside Write. Audit the input to '$CW.Write'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. metadata: category: security - confidence: MEDIUM + confidence: LOW cwe: - - 'CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component (''Injection'')' - impact: MEDIUM - likelihood: MEDIUM + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW owasp: + - A01:2017 - Injection - A03:2021 - Injection references: - - https://www.damonkohler.com/2008/12/email-injection.html + - https://owasp.org/Top10/A03_2021-Injection subcategory: - - vuln + - audit technology: - - django + - go patterns: + - pattern: | + $CW.Write($BYTE) - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.send_mail(..., html_message=$DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) - - pattern: return django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) - - pattern: django.core.mail.send_mail(..., html_message=request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.send_mail(..., html_message=$DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W(...), ...) - - pattern: return django.core.mail.send_mail(..., html_message=request.$W(...), ...) - - pattern: django.core.mail.send_mail(..., html_message=request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.send_mail(..., html_message=$DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W[...], ...) - - pattern: return django.core.mail.send_mail(..., html_message=request.$W[...], ...) - - pattern: django.core.mail.send_mail(..., html_message=request.$W, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.send_mail(..., html_message=$DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W, ...) - - pattern: return django.core.mail.send_mail(..., html_message=request.$W, ...) - severity: WARNING - - id: python.django.security.injection.open-redirect.open-redirect + $CW,$ERR := $CMD.StdinPipe() + ... + - pattern-not: | + $CW.Write("...") + - pattern-not: | + $CW.Write([]byte("...")) + - pattern-not: | + $CW.Write([]byte("..."+"...")) + - pattern-not-inside: | + $BYTE = []byte("..."); + ... + - pattern-not-inside: | + $BYTE = []byte("..."+"..."); + ... + - pattern-inside: | + import "os/exec" + ... + severity: ERROR + - id: go.lang.security.audit.dangerous-exec-cmd.dangerous-exec-cmd languages: - - python - message: Data from request ($DATA) is passed to redirect(). This is an open redirect and could be exploited. Ensure you are redirecting to safe URLs by using django.utils.http.is_safe_url(). See https://cwe.mitre.org/data/definitions/601.html for more information. + - go + message: Detected non-static command inside exec.Cmd. Audit the input to 'exec.Cmd'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH likelihood: LOW owasp: - - A01:2021 - Broken Access Control + - A03:2021 - Injection references: - - https://www.djm.org.uk/posts/djangos-little-protections-word-redirect-dangers/ - - https://github.com/django/django/blob/d1b7bd030b1db111e1a3505b1fc029ab964382cc/django/utils/http.py#L231 + - https://owasp.org/Top10/A03_2021-Injection subcategory: - - vuln + - audit technology: - - django + - go + patterns: + - pattern-either: + - patterns: + - pattern: | + exec.Cmd {...,Path: $CMD,...} + - pattern-not: | + exec.Cmd {...,Path: "...",...} + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + - pattern-not-inside: | + $CMD = "..."; + ... + - patterns: + - pattern: | + exec.Cmd {...,Args: $ARGS,...} + - pattern-not: | + exec.Cmd {...,Args: []string{...},...} + - pattern-not-inside: | + $ARGS = []string{"...",...}; + ... + - pattern-not-inside: | + $CMD = "..."; + ... + $ARGS = []string{$CMD,...}; + ... + - pattern-not-inside: | + $CMD = exec.LookPath("..."); + ... + $ARGS = []string{$CMD,...}; + ... + - patterns: + - pattern: | + exec.Cmd {...,Args: []string{$CMD,...},...} + - pattern-not: | + exec.Cmd {...,Args: []string{"...",...},...} + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + - pattern-not-inside: | + $CMD = "..."; + ... + - patterns: + - pattern-either: + - pattern: | + exec.Cmd {...,Args: []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...} + - patterns: + - pattern: | + exec.Cmd {...,Args: []string{$CMD,"-c",$EXE,...},...} + - pattern-inside: | + $CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/"); + ... + - pattern-not: | + exec.Cmd {...,Args: []string{"...","...","...",...},...} + - pattern-not-inside: | + $EXE = "..."; + ... + - pattern-inside: | + import "os/exec" + ... + severity: ERROR + - id: go.lang.security.audit.dangerous-exec-command.dangerous-exec-command + languages: + - go + message: Detected non-static command inside Command. Audit the input to 'exec.Command'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - go patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + exec.Command($CMD,...) + - pattern: | + exec.CommandContext($CTX,$CMD,...) + - pattern-not: | + exec.Command("...",...) + - pattern-not: | + exec.CommandContext($CTX,"...",...) + - patterns: + - pattern-either: + - pattern: | + exec.Command("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) + - pattern: | + exec.CommandContext($CTX,"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) + - pattern-not: | + exec.Command("...","...","...",...) + - pattern-not: | + exec.CommandContext($CTX,"...","...","...",...) + - pattern-either: + - pattern: | + exec.Command("=~/\/bin\/env/","=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) + - pattern: | + exec.CommandContext($CTX,"=~/\/bin\/env/","=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) - pattern-inside: | - def $FUNC(...): - ... - - pattern-not-inside: | - def $FUNC(...): - ... - django.utils.http.is_safe_url(...) - ... - - pattern-not-inside: | - def $FUNC(...): - ... - if <... django.utils.http.is_safe_url(...) ...>: - ... + import "os/exec" + ... - pattern-not-inside: | - def $FUNC(...): - ... - django.utils.http.url_has_allowed_host_and_scheme(...) - ... + $CMD,$ERR := exec.LookPath("..."); + ... - pattern-not-inside: | - def $FUNC(...): - ... - if <... django.utils.http.url_has_allowed_host_and_scheme(...) ...>: - ... + $CMD = "..."; + ... + severity: ERROR + - id: go.lang.security.audit.dangerous-syscall-exec.dangerous-syscall-exec + languages: + - go + message: Detected non-static command inside Exec. Audit the input to 'syscall.Exec'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - go + patterns: - pattern-either: - - pattern: django.shortcuts.redirect(..., request.$W.get(...), ...) - - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: django.shortcuts.redirect(..., $S % request.$W.get(...), ...) - - pattern: django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.shortcuts.redirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.shortcuts.redirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.shortcuts.redirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.shortcuts.redirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: $A = django.shortcuts.redirect(..., request.$W.get(...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S % request.$W.get(...), ...) - - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: return django.shortcuts.redirect(..., request.$W.get(...), ...) - - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: return django.shortcuts.redirect(..., $S % request.$W.get(...), ...) - - pattern: return django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: django.shortcuts.redirect(..., request.$W(...), ...) - - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: django.shortcuts.redirect(..., $S % request.$W(...), ...) - - pattern: django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - django.shortcuts.redirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.shortcuts.redirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.shortcuts.redirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.shortcuts.redirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: $A = django.shortcuts.redirect(..., request.$W(...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S % request.$W(...), ...) - - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) - - pattern: return django.shortcuts.redirect(..., request.$W(...), ...) - - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: return django.shortcuts.redirect(..., $S % request.$W(...), ...) - - pattern: return django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) - - pattern: django.shortcuts.redirect(..., request.$W[...], ...) - - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: django.shortcuts.redirect(..., $S % request.$W[...], ...) - - pattern: django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - django.shortcuts.redirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.shortcuts.redirect(..., $STR % $DATA, ...) + - patterns: + - pattern: | + syscall.$METHOD($BIN,...) + - pattern-not: | + syscall.$METHOD("...",...) + - pattern-not-inside: | + $BIN,$ERR := exec.LookPath("..."); + ... + - pattern-not-inside: | + $BIN = "..."; + ... + - patterns: + - pattern: | + syscall.$METHOD($BIN,$ARGS,...) + - pattern-not: | + syscall.$METHOD($BIN,[]string{"...",...},...) + - pattern-not-inside: | + $ARGS := []string{"...",...}; + ... + - pattern-not-inside: | + $CMD = "..."; + ... + $ARGS = []string{$CMD,...}; + ... + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + $ARGS = []string{$CMD,...}; + ... + - patterns: + - pattern: | + syscall.$METHOD($BIN,[]string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...) + - pattern-not: | + syscall.$METHOD($BIN,[]string{"...","...","...",...},...) + - patterns: + - pattern: | + syscall.$METHOD($BIN,$ARGS,...) + - pattern-either: + - pattern-inside: | + $ARGS := []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...}; + ... + - pattern-inside: | + $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/"; + ... + $ARGS = []string{$CMD,"-c",$EXE,...}; + ... + - pattern-inside: | + $CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/"); + ... + $ARGS = []string{$CMD,"-c",$EXE,...}; + ... + - pattern-not-inside: | + $ARGS := []string{"...","...","...",...}; + ... + - pattern-not-inside: | + $CMD = "..."; + ... + $ARGS = []string{$CMD,"...","...",...}; + ... + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + $ARGS = []string{$CMD,"...","...",...}; + ... + - pattern-inside: | + import "syscall" + ... + - metavariable-regex: + metavariable: $METHOD + regex: (Exec|ForkExec) + severity: ERROR + - id: go.lang.security.audit.database.string-formatted-query.string-formatted-query + languages: + - go + message: String-formatted SQL query detected. This could lead to SQL injection if the string is not sanitized properly. Audit this call to ensure the SQL is not manipulable by external data. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://github.com/securego/gosec + subcategory: + - audit + technology: + - go + patterns: + - metavariable-regex: + metavariable: $OBJ + regex: (?i).*(db|database) + - pattern-not-inside: | + $VAR = "..." + "..." + ... + $OBJ.$SINK(..., $VAR, ...) + - pattern-not: $OBJ.Exec("...") + - pattern-not: $OBJ.ExecContext($CTX, "...") + - pattern-not: $OBJ.Query("...") + - pattern-not: $OBJ.QueryContext($CTX, "...") + - pattern-not: $OBJ.QueryRow("...") + - pattern-not: $OBJ.QueryRow($CTX, "...") + - pattern-not: $OBJ.QueryRowContext($CTX, "...") + - pattern-either: + - pattern: $OBJ.Exec($X + ...) + - pattern: $OBJ.ExecContext($CTX, $X + ...) + - pattern: $OBJ.Query($X + ...) + - pattern: $OBJ.QueryContext($CTX, $X + ...) + - pattern: $OBJ.QueryRow($X + ...) + - pattern: $OBJ.QueryRow($CTX, $X + ...) + - pattern: $OBJ.QueryRowContext($CTX, $X + ...) + - pattern: $OBJ.Exec(fmt.$P("...", ...)) + - pattern: $OBJ.ExecContext($CTX, fmt.$P("...", ...)) + - pattern: $OBJ.Query(fmt.$P("...", ...)) + - pattern: $OBJ.QueryContext($CTX, fmt.$P("...", ...)) + - pattern: $OBJ.QueryRow(fmt.$P("...", ...)) + - pattern: $OBJ.QueryRow($CTX, fmt.$U("...", ...)) + - pattern: $OBJ.QueryRowContext($CTX, fmt.$P("...", ...)) + - patterns: + - pattern-either: + - pattern: $QUERY = fmt.Fprintf($F, "$SQLSTR", ...) + - pattern: $QUERY = fmt.Sprintf("$SQLSTR", ...) + - pattern: $QUERY = fmt.Printf("$SQLSTR", ...) + - pattern: $QUERY = $X + ... + - pattern-either: + - pattern-inside: | + func $FUNC(...) { + ... + $OBJ.Query($QUERY, ...) + ... + } + - pattern-inside: | + func $FUNC(...) { + ... + $OBJ.ExecContext($CTX, $QUERY, ...) + ... + } + - pattern-inside: | + func $FUNC(...) { + ... + $OBJ.Exec($QUERY, ...) + ... + } + - pattern-inside: | + func $FUNC(...) { + ... + $OBJ.QueryRow($CTX, $QUERY) + ... + } + - pattern-inside: | + func $FUNC(...) { + ... + $OBJ.QueryRow($QUERY) + ... + } + - pattern-inside: | + func $FUNC(...) { + ... + $OBJ.QueryContext($CTX, $QUERY) + ... + } + - pattern-inside: | + func $FUNC(...) { + ... + $OBJ.QueryRowContext($CTX, $QUERY, ...) + ... + } + severity: WARNING + - id: go.lang.security.audit.md5-used-as-password.md5-used-as-password + languages: + - go + message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as bcrypt. You can use the `golang.org/x/crypto/bcrypt` package. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + interfile: true + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html + - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords + - https://github.com/returntocorp/semgrep-rules/issues/1609 + - https://pkg.go.dev/golang.org/x/crypto/bcrypt + subcategory: + - vuln + technology: + - md5 + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern: $FUNCTION(...) + - metavariable-regex: + metavariable: $FUNCTION + regex: (?i)(.*password.*) + pattern-sources: + - patterns: + - pattern-either: + - pattern: md5.New + - pattern: md5.Sum + severity: WARNING + - id: go.lang.security.audit.net.bind_all.avoid-bind-to-all-interfaces + languages: + - go + message: Detected a network listener listening on 0.0.0.0 or an empty string. This could unexpectedly expose the server publicly as it binds to all available interfaces. Instead, specify another IP address that is not 0.0.0.0 nor the empty string. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://github.com/securego/gosec + subcategory: + - audit + technology: + - go + pattern-either: + - pattern: tls.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) + - pattern: net.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) + - pattern: tls.Listen($NETWORK, "=~/^:.*$/", ...) + - pattern: net.Listen($NETWORK, "=~/^:.*$/", ...) + severity: WARNING + - fix-regex: + regex: (HttpOnly\s*:\s+)false + replacement: \1true + id: go.lang.security.audit.net.cookie-missing-httponly.cookie-missing-httponly + languages: + - go + message: A session cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie which mitigates XSS attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' in the Cookie. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go + - https://golang.org/src/net/http/cookie.go + subcategory: + - vuln + technology: + - go + patterns: + - pattern-not-inside: | + http.Cookie{ + ..., + HttpOnly: true, + ..., + } + - pattern: | + http.Cookie{ + ..., + } + severity: WARNING + - fix-regex: + regex: (Secure\s*:\s+)false + replacement: \1true + id: go.lang.security.audit.net.cookie-missing-secure.cookie-missing-secure + languages: + - go + message: A session cookie was detected without setting the 'Secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'Secure' flag by setting 'Secure' to 'true' in the Options struct. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go + - https://golang.org/src/net/http/cookie.go + subcategory: + - vuln + technology: + - go + patterns: + - pattern-not-inside: | + http.Cookie{ + ..., + Secure: true, + ..., + } + - pattern: | + http.Cookie{ + ..., + } + severity: WARNING + - id: go.lang.security.audit.net.dynamic-httptrace-clienttrace.dynamic-httptrace-clienttrace + languages: + - go + message: Detected a potentially dynamic ClientTrace. This occurred because semgrep could not find a static definition for '$TRACE'. Dynamic ClientTraces are dangerous because they deserialize function code to run when certain Request events occur, which could lead to code being run without your knowledge. Ensure that your ClientTrace is statically defined. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-913: Improper Control of Dynamically-Managed Code Resources' + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://github.com/returntocorp/semgrep-rules/issues/518 + subcategory: + - vuln + technology: + - go + patterns: + - pattern-not-inside: | + package $PACKAGE + ... + &httptrace.ClientTrace { ... } + ... + - pattern: httptrace.WithClientTrace($ANY, $TRACE) + severity: WARNING + - id: go.lang.security.audit.net.formatted-template-string.formatted-template-string + languages: + - go + message: Found a formatted template string passed to 'template.HTML()'. 'template.HTML()' does not escape contents. Be absolutely sure there is no user-controlled data in this template. If user data can reach this template, you may have a XSS vulnerability. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://golang.org/pkg/html/template/#HTML + subcategory: + - audit + technology: + - go + patterns: + - pattern-not: template.HTML("..." + "...") + - pattern-either: + - pattern: template.HTML($T + $X, ...) + - pattern: template.HTML(fmt.$P("...", ...), ...) - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA + $T = "..." ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] + $T = $FXN(..., $T, ...) ... - django.shortcuts.redirect(..., f"...{$DATA}...", ...) + template.HTML($T, ...) - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." + $T = fmt.$P("...", ...) ... - django.shortcuts.redirect(..., $INTERM, ...) + template.HTML($T, ...) - pattern: | - $DATA = request.$W[...] + $T, $ERR = fmt.$P("...", ...) ... - django.shortcuts.redirect(..., $STR + $DATA, ...) + template.HTML($T, ...) - pattern: | - $DATA = request.$W[...] + $T = $X + $Y ... - $INTERM = $STR + $DATA + template.HTML($T, ...) + - pattern: |- + $T = "..." ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: $A = django.shortcuts.redirect(..., request.$W[...], ...) - - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S % request.$W[...], ...) - - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) - - pattern: return django.shortcuts.redirect(..., request.$W[...], ...) - - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: return django.shortcuts.redirect(..., $S % request.$W[...], ...) - - pattern: return django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) - - pattern: django.shortcuts.redirect(..., request.$W, ...) - - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) - - pattern: django.shortcuts.redirect(..., $S % request.$W, ...) - - pattern: django.shortcuts.redirect(..., f"...{request.$W}...", ...) - - pattern: | - $DATA = request.$W + $OTHER, $ERR = fmt.$P(..., $T, ...) ... - django.shortcuts.redirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.shortcuts.redirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.shortcuts.redirect(..., f"...{$DATA}...", ...) + template.HTML($OTHER, ...) + severity: WARNING + - id: go.lang.security.audit.net.fs-directory-listing.fs-directory-listing + languages: + - go + message: 'Detected usage of ''http.FileServer'' as handler: this allows directory listing and an attacker could navigate through directories looking for sensitive files. Be sure to disable directory listing or restrict access to specific directories/files.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-548: Exposure of Information Through Directory Listing' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A06:2017 - Security Misconfiguration + - A01:2021 - Broken Access Control + references: + - https://github.com/OWASP/Go-SCP + - https://cwe.mitre.org/data/definitions/548.html + subcategory: + - vuln + technology: + - go + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $FS := http.FileServer(...) + ... + - pattern-either: + - pattern: | + http.ListenAndServe(..., $FS) + - pattern: | + http.ListenAndServeTLS(..., $FS) + - pattern: | + http.Handle(..., $FS) + - pattern: | + http.HandleFunc(..., $FS) + - patterns: + - pattern: | + http.$FN(..., http.FileServer(...)) + - metavariable-regex: + metavariable: $FN + regex: (ListenAndServe|ListenAndServeTLS|Handle|HandleFunc) + severity: WARNING + - id: go.lang.security.audit.net.pprof.pprof-debug-exposure + languages: + - go + message: The profiling 'pprof' endpoint is automatically exposed on /debug/pprof. This could leak information about the server. Instead, use `import "net/http/pprof"`. See https://www.farsightsecurity.com/blog/txt-record/go-remote-profiling-20161028/ for more information and mitigation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-489: Active Debug Code' + impact: LOW + likelihood: LOW + owasp: A06:2017 - Security Misconfiguration + references: + - https://www.farsightsecurity.com/blog/txt-record/go-remote-profiling-20161028/ + source-rule-url: https://github.com/securego/gosec#available-rules + subcategory: + - audit + technology: + - go + patterns: + - pattern-inside: | + import _ "net/http/pprof" + ... + - pattern-inside: | + func $ANY(...) { + ... + } + - pattern-not-inside: | + $MUX = http.NewServeMux(...) + ... + http.ListenAndServe($ADDR, $MUX) + - pattern-not: http.ListenAndServe("=~/^localhost.*/", ...) + - pattern-not: http.ListenAndServe("=~/^127[.]0[.]0[.]1.*/", ...) + - pattern: http.ListenAndServe(...) + severity: WARNING + - id: go.lang.security.audit.net.unescaped-data-in-htmlattr.unescaped-data-in-htmlattr + languages: + - go + message: Found a formatted template string passed to 'template. HTMLAttr()'. 'template.HTMLAttr()' does not escape contents. Be absolutely sure there is no user-controlled data in this template or validate and sanitize the data before passing it into the template. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://golang.org/pkg/html/template/#HTMLAttr + subcategory: + - audit + technology: + - go + pattern-either: + - pattern: template.HTMLAttr($T + $X, ...) + - pattern: template.HTMLAttr(fmt.$P("...", ...), ...) + - pattern: | + $T = "..." + ... + $T = $FXN(..., $T, ...) + ... + template.HTMLAttr($T, ...) + - pattern: | + $T = fmt.$P("...", ...) + ... + template.HTMLAttr($T, ...) + - pattern: | + $T, $ERR = fmt.$P("...", ...) + ... + template.HTMLAttr($T, ...) + - pattern: | + $T = $X + $Y + ... + template.HTMLAttr($T, ...) + - pattern: |- + $T = "..." + ... + $OTHER, $ERR = fmt.$P(..., $T, ...) + ... + template.HTMLAttr($OTHER, ...) + severity: WARNING + - id: go.lang.security.audit.net.unescaped-data-in-js.unescaped-data-in-js + languages: + - go + message: Found a formatted template string passed to 'template.JS()'. 'template.JS()' does not escape contents. Be absolutely sure there is no user-controlled data in this template. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://golang.org/pkg/html/template/#JS + subcategory: + - audit + technology: + - go + pattern-either: + - pattern: template.JS($T + $X, ...) + - pattern: template.JS(fmt.$P("...", ...), ...) + - pattern: | + $T = "..." + ... + $T = $FXN(..., $T, ...) + ... + template.JS($T, ...) + - pattern: | + $T = fmt.$P("...", ...) + ... + template.JS($T, ...) + - pattern: | + $T, $ERR = fmt.$P("...", ...) + ... + template.JS($T, ...) + - pattern: | + $T = $X + $Y + ... + template.JS($T, ...) + - pattern: | + $T = "..." + ... + $OTHER, $ERR = fmt.$P(..., $T, ...) + ... + template.JS($OTHER, ...) + severity: WARNING + - fix: http.ListenAndServeTLS($ADDR, certFile, keyFile, $HANDLER) + id: go.lang.security.audit.net.use-tls.use-tls + languages: + - go + message: Found an HTTP server without TLS. Use 'http.ListenAndServeTLS' instead. See https://golang.org/pkg/net/http/#ListenAndServeTLS for more information. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://golang.org/pkg/net/http/#ListenAndServeTLS + subcategory: + - audit + technology: + - go + pattern: http.ListenAndServe($ADDR, $HANDLER) + severity: WARNING + - id: go.lang.security.audit.net.wip-xss-using-responsewriter-and-printf.wip-xss-using-responsewriter-and-printf + languages: + - go + message: Found data going from url query parameters into formatted data written to ResponseWriter. This could be XSS and should not be done. If you must do this, ensure your data is sanitized or escaped. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - go + patterns: + - pattern-inside: | + func $FUNC(..., $W http.ResponseWriter, ...) { + ... + var $TEMPLATE = "..." + ... + $W.Write([]byte(fmt.$PRINTF($TEMPLATE, ...)), ...) + ... + } + - pattern-either: - pattern: | - $DATA = request.$W + $PARAMS = r.URL.Query() ... - $INTERM = f"...{$DATA}..." + $DATA, $ERR := $PARAMS[...] ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W + $INTERM = $ANYTHING(..., $DATA, ...) ... - django.shortcuts.redirect(..., $STR + $DATA, ...) + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - pattern: | - $DATA = request.$W + $PARAMS = r.URL.Query() ... - $INTERM = $STR + $DATA + $DATA, $ERR := $PARAMS[...] ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: $A = django.shortcuts.redirect(..., request.$W, ...) - - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S % request.$W, ...) - - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W}...", ...) - - pattern: return django.shortcuts.redirect(..., request.$W, ...) - - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) - - pattern: return django.shortcuts.redirect(..., $S % request.$W, ...) - - pattern: return django.shortcuts.redirect(..., f"...{request.$W}...", ...) - - pattern: django.http.HttpResponseRedirect(..., request.$W.get(...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) - - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: | - $DATA = request.$W.get(...) + $INTERM = $DATA[...] ... - django.http.HttpResponseRedirect(..., $DATA, ...) + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA + $DATA, $ERR := r.URL.Query()[...] ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) + $INTERM = $DATA[...] ... - django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - pattern: | - $DATA = request.$W.get(...) + $DATA, $ERR := r.URL.Query()[...] ... - $INTERM = $STR.format(..., $DATA, ...) + $INTERM = $ANYTHING(..., $DATA, ...) ... - django.http.HttpResponseRedirect(..., $INTERM, ...) + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - pattern: | - $DATA = request.$W.get(...) + $PARAMS = r.URL.Query() ... - django.http.HttpResponseRedirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) + $DATA, $ERR := $PARAMS[...] ... - $INTERM = $STR % $DATA + $W.Write([]byte(fmt.$PRINTF(..., $DATA, ...))) + severity: WARNING + - id: go.lang.security.audit.reflect-makefunc.reflect-makefunc + languages: + - go + message: '''reflect.MakeFunc'' detected. This will sidestep protections that are normally afforded by Go''s type system. Audit this call and be sure that user input cannot be used to affect the code generated by MakeFunc; otherwise, you will have a serious security vulnerability.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-913: Improper Control of Dynamically-Managed Code Resources' + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - go + pattern: reflect.MakeFunc(...) + severity: ERROR + - id: go.lang.security.audit.sqli.gosql-sqli.gosql-sqli + languages: + - go + message: Detected string concatenation with a non-literal variable in a "database/sql" Go SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use prepared statements with the 'Prepare' and 'PrepareContext' calls. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://golang.org/pkg/database/sql/ + subcategory: + - vuln + technology: + - go + patterns: + - pattern-either: + - patterns: + - pattern: $DB.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = fmt.Sprintf("...", $PARAM1, ...) + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern: $DB.$METHOD(..., $X + $Y, ...) + - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) + - pattern-either: + - pattern-inside: | + $DB, ... = sql.Open(...) ... - django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern-inside: | + func $FUNCNAME(..., $DB *sql.DB, ...) { + ... + } + - pattern-not: $DB.$METHOD(..., "..." + "...", ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Exec|ExecContent|Query|QueryContext|QueryRow|QueryRowContext)$ + severity: ERROR + - id: go.lang.security.audit.sqli.pg-orm-sqli.pg-orm-sqli + languages: + - go + message: Detected string concatenation with a non-literal variable in a go-pg ORM SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, do not use strings concatenated with user-controlled input. Instead, use parameterized statements. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://pg.uptrace.dev/queries/ + subcategory: + - vuln + technology: + - go-pg + patterns: + - pattern-inside: | + import ( + ... + "$IMPORT" + ) + ... + - metavariable-regex: + metavariable: $IMPORT + regex: .*go-pg + - pattern-either: + - patterns: + - pattern: $DB.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = fmt.Sprintf("...", $PARAM1, ...) + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) + $DB.$INTFUNC1(...).$METHOD(..., $X + $Y, ...).$INTFUNC2(...) - pattern: | - $DATA = request.$W.get(...) + $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) + - pattern-inside: | + $DB = pg.Connect(...) ... - $INTERM = f"...{$DATA}..." + - pattern-inside: | + func $FUNCNAME(..., $DB *pg.DB, ...) { + ... + } + - pattern-not-inside: | + $QUERY = fmt.Sprintf("...", ...,"...", ...) + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not: $DB.$METHOD(...,"...",...) + - pattern-not: | + $DB.$INTFUNC1(...).$METHOD(..., "...", ...).$INTFUNC2(...) + - pattern-not-inside: | + $QUERY = "..." + "..." + - pattern-not: | + "..." + - pattern-not: path.Join(...) + - pattern-not: filepath.Join(...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Where|WhereOr|Join|GroupExpr|OrderExpr|ColumnExpr)$ + severity: ERROR + - id: go.lang.security.audit.sqli.pg-sqli.pg-sqli + languages: + - go + message: 'Detected string concatenation with a non-literal variable in a go-pg SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries instead of string concatenation. You can use parameterized queries like so: ''(SELECT ? FROM table, data1)''' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://pg.uptrace.dev/ + - https://pkg.go.dev/github.com/go-pg/pg/v10 + subcategory: + - vuln + technology: + - go-pg + patterns: + - pattern-either: + - patterns: + - pattern: | + $DB.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = fmt.Sprintf("...", $PARAM1, ...) + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern: $DB.$METHOD(..., $X + $Y, ...) + - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) + - pattern-either: + - pattern-inside: | + $DB = pg.Connect(...) ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) + - pattern-inside: | + func $FUNCNAME(..., $DB *pg.DB, ...) { + ... + } + - pattern-not: $DB.$METHOD(..., "..." + "...", ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Exec|ExecContext|ExecOne|ExecOneContext|Query|QueryOne|QueryContext|QueryOneContext)$ + severity: ERROR + - id: go.lang.security.audit.sqli.pgx-sqli.pgx-sqli + languages: + - go + message: 'Detected string concatenation with a non-literal variable in a pgx Go SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries instead. You can use parameterized queries like so: (`SELECT $1 FROM table`, `data1)' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/jackc/pgx + - https://pkg.go.dev/github.com/jackc/pgx/v4#hdr-Connection_Pool + subcategory: + - vuln + technology: + - pgx + patterns: + - pattern-either: + - patterns: + - pattern: $DB.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = fmt.Sprintf("...", $PARAM1, ...) + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern: $DB.$METHOD(..., $X + $Y, ...) + - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) + - pattern-either: + - pattern-inside: | + $DB, ... = pgx.Connect(...) ... - django.http.HttpResponseRedirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) + - pattern-inside: | + $DB, ... = pgx.NewConnPool(...) ... - $INTERM = $STR + $DATA + - pattern-inside: | + $DB, ... = pgx.ConnectConfig(...) ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., request.$W.get(...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: return django.http.HttpResponseRedirect(..., request.$W.get(...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) - - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: django.http.HttpResponseRedirect(..., request.$W(...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) - - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) + - pattern-inside: | + func $FUNCNAME(..., $DB *pgx.Conn, ...) { + ... + } + - pattern-not: $DB.$METHOD(..., "..." + "...", ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Exec|ExecEx|Query|QueryEx|QueryRow|QueryRowEx)$ + severity: ERROR + - id: go.lang.security.audit.unsafe-reflect-by-name.unsafe-reflect-by-name + languages: + - go + message: If an attacker can supply values that the application then uses to determine which method or field to invoke, the potential exists for the attacker to create control flow paths through the application that were not intended by the application developers. This attack vector may allow the attacker to bypass authentication or access control checks or otherwise cause the application to behave in an unexpected manner. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-470: Use of Externally-Controlled Input to Select Classes or Code (''Unsafe Reflection'')' + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - go + patterns: + - pattern-either: - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseRedirect(..., $DATA, ...) + $SMTH.MethodByName($NAME,...) - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA + $SMTH.FieldByName($NAME,...) + - pattern-not: | + $SMTH.MethodByName("...",...) + - pattern-not: | + $SMTH.FieldByName("...",...) + - pattern-inside: | + import "reflect" + ... + severity: WARNING + - id: go.lang.security.audit.unsafe.use-of-unsafe-block + languages: + - go + message: Using the unsafe package in Go gives you low-level memory management and many of the strengths of the C language, but also steps around the type safety of Go and can lead to buffer overflows and possible arbitrary code execution by an attacker. Only use this package if you absolutely know what you're doing. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-242: Use of Inherently Dangerous Function' + impact: LOW + likelihood: LOW + references: + - https://cwe.mitre.org/data/definitions/242.html + source_rule_url: https://github.com/securego/gosec/blob/master/rules/unsafe.go + subcategory: + - audit + technology: + - go + pattern: unsafe.$FUNC(...) + severity: WARNING + - fix: | + html/template + id: go.lang.security.audit.xss.import-text-template.import-text-template + languages: + - go + message: When working with web applications that involve rendering user-generated content, it's important to properly escape any HTML content to prevent Cross-Site Scripting (XSS) attacks. In Go, the `text/template` package does not automatically escape HTML content, which can leave your application vulnerable to these types of attacks. To mitigate this risk, it's recommended to use the `html/template` package instead, which provides built-in functionality for HTML escaping. By using `html/template` to render your HTML content, you can help to ensure that your web application is more secure and less susceptible to XSS vulnerabilities. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://www.veracode.com/blog/secure-development/use-golang-these-mistakes-could-compromise-your-apps-security + subcategory: + - audit + technology: + - go + patterns: + - pattern: | + import "$IMPORT" + - metavariable-regex: + metavariable: $IMPORT + regex: ^(text/template)$ + - focus-metavariable: $IMPORT + severity: WARNING + - id: go.lang.security.audit.xss.no-direct-write-to-responsewriter.no-direct-write-to-responsewriter + languages: + - go + message: Detected directly writing or similar in 'http.ResponseWriter.write()'. This bypasses HTML escaping that prevents cross-site scripting vulnerabilities. Instead, use the 'html/template' package and render data using 'template.Execute()'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + subcategory: + - audit + technology: + - go + patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-inside: | + func $HANDLER(..., $WRITER *http.ResponseWriter, ...) { + ... + } + - pattern-inside: | + func(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-either: + - pattern: $WRITER.Write(...) + - pattern: (*$WRITER).Write(...) + - pattern-not: $WRITER.Write([]byte("...")) + severity: WARNING + - id: go.lang.security.audit.xss.no-fprintf-to-responsewriter.no-fprintf-to-responsewriter + languages: + - go + message: Detected 'Fprintf' or similar writing to 'http.ResponseWriter'. This bypasses HTML escaping that prevents cross-site scripting vulnerabilities. Instead, use the 'html/template' package to render data to users. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + subcategory: + - audit + technology: + - go + patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-inside: | + func(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-not: fmt.$PRINTF($WRITER, "...") + - pattern: fmt.$PRINTF($WRITER, ...) + severity: WARNING + - id: go.lang.security.audit.xss.no-interpolation-in-tag.no-interpolation-in-tag + languages: + - generic + message: Detected template variable interpolation in an HTML tag. This is potentially vulnerable to cross-site scripting (XSS) attacks because a malicious actor has control over HTML but without the need to use escaped characters. Use explicit tags instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://github.com/golang/go/issues/19669 + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + subcategory: + - audit + technology: + - generic + paths: + include: + - '*.html' + - '*.thtml' + - '*.gohtml' + - '*.tmpl' + - '*.tpl' + pattern: <{{ ... }} ... > + severity: WARNING + - id: go.lang.security.audit.xss.no-interpolation-js-template-string.no-interpolation-js-template-string + languages: + - generic + message: Detected template variable interpolation in a JavaScript template string. This is potentially vulnerable to cross-site scripting (XSS) attacks because a malicious actor has control over JavaScript but without the need to use escaped characters. Instead, obtain this variable outside of the template string and ensure your template is properly escaped. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://github.com/golang/go/issues/9200#issuecomment-66100328 + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + subcategory: + - audit + technology: + - generic + paths: + include: + - '*.html' + - '*.thtml' + - '*.gohtml' + - '*.tmpl' + - '*.tpl' + patterns: + - pattern-inside: + - pattern: '` ... {{ ... }} ...`' + severity: WARNING + - id: go.lang.security.audit.xss.no-io-writestring-to-responsewriter.no-io-writestring-to-responsewriter + languages: + - go + message: Detected 'io.WriteString()' writing directly to 'http.ResponseWriter'. This bypasses HTML escaping that prevents cross-site scripting vulnerabilities. Instead, use the 'html/template' package to render data to users. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + - https://golang.org/pkg/io/#WriteString + subcategory: + - audit + technology: + - go + patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-inside: | + func(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-not: io.WriteString($WRITER, "...") + - pattern: io.WriteString($WRITER, $STRING) + severity: WARNING + - id: go.lang.security.audit.xss.no-printf-in-responsewriter.no-printf-in-responsewriter + languages: + - go + message: Detected 'printf' or similar in 'http.ResponseWriter.write()'. This bypasses HTML escaping that prevents cross-site scripting vulnerabilities. Instead, use the 'html/template' package to render data to users. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + subcategory: + - audit + technology: + - go + patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-inside: | + func(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern: | + $WRITER.Write(<... fmt.$PRINTF(...) ...>, ...) + severity: WARNING + - id: go.lang.security.audit.xss.template-html-does-not-escape.unsafe-template-type + languages: + - go + message: Semgrep could not determine that the argument to 'template.HTML()' is a constant. 'template.HTML()' and similar does not escape contents. Be absolutely sure there is no user-controlled data in this template. If user data can reach this template, you may have a XSS vulnerability. Instead, do not use this function and use 'template.Execute()'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://golang.org/pkg/html/template/#HTML + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/vulnerability/xss/xss.go#L33 + subcategory: + - audit + technology: + - go + patterns: + - pattern-not: template.$ANY("..." + "...") + - pattern-not: template.$ANY("...") + - pattern-either: + - pattern: template.HTML(...) + - pattern: template.CSS(...) + - pattern: template.HTMLAttr(...) + - pattern: template.JS(...) + - pattern: template.JSStr(...) + - pattern: template.Srcset(...) + - pattern: template.URL(...) + severity: WARNING + - id: go.lang.security.audit.xxe.parsing-external-entities-enabled.parsing-external-entities-enabled + languages: + - go + message: Detected enabling of "XMLParseNoEnt", which allows parsing of external entities and can lead to XXE if user controlled data is parsed by the library. Instead, do not enable "XMLParseNoEnt" or be sure to adequately sanitize user-controlled data when it is being parsed by this library. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://knowledge-base.secureflag.com/vulnerabilities/xml_injection/xml_entity_expansion_go_lang.html + - https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing + subcategory: + - audit + technology: + - libxml2 + patterns: + - pattern-inside: | + import ("github.com/lestrrat-go/libxml2/parser") + ... + - pattern: $PARSER := parser.New(parser.XMLParseNoEnt) + severity: WARNING + - id: go.lang.security.bad_tmp.bad-tmp-file-creation + languages: + - go + message: File creation in shared tmp directory without using ioutil.Tempfile + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-377: Insecure Temporary File' + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://github.com/securego/gosec + subcategory: + - audit + technology: + - go + pattern-either: + - pattern: ioutil.WriteFile("=~//tmp/.*$/", ...) + - pattern: os.Create("=~//tmp/.*$/", ...) + severity: WARNING + - fix-regex: + regex: (.*)(Copy|CopyBuffer)\((.*?),(.*?)(\)|,.*\)) + replacement: \1CopyN(\3, \4, 1024*1024*256) + id: go.lang.security.decompression_bomb.potential-dos-via-decompression-bomb + languages: + - go + message: 'Detected a possible denial-of-service via a zip bomb attack. By limiting the max bytes read, you can mitigate this attack. `io.CopyN()` can specify a size. ' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-400: Uncontrolled Resource Consumption' + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + references: + - https://golang.org/pkg/io/#CopyN + - https://github.com/securego/gosec/blob/master/rules/decompression-bomb.go + source-rule-url: https://github.com/securego/gosec + subcategory: + - audit + technology: + - go + patterns: + - pattern-either: + - pattern: io.Copy(...) + - pattern: io.CopyBuffer(...) + - pattern-either: + - pattern-inside: | + gzip.NewReader(...) ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) + - pattern-inside: | + zlib.NewReader(...) ... - django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) + - pattern-inside: | + zlib.NewReaderDict(...) ... - $INTERM = $STR.format(..., $DATA, ...) + - pattern-inside: | + bzip2.NewReader(...) ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) + - pattern-inside: | + flate.NewReader(...) ... - django.http.HttpResponseRedirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) + - pattern-inside: | + flate.NewReaderDict(...) ... - $INTERM = $STR % $DATA + - pattern-inside: | + lzw.NewReader(...) ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) + - pattern-inside: | + tar.NewReader(...) ... - django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) + - pattern-inside: | + zip.NewReader(...) ... - $INTERM = f"...{$DATA}..." + - pattern-inside: | + zip.OpenReader(...) ... - django.http.HttpResponseRedirect(..., $INTERM, ...) + severity: WARNING + - fix: filepath.FromSlash(filepath.Clean("/"+strings.Trim($...INNER, "/"))) + id: go.lang.security.filepath-clean-misuse.filepath-clean-misuse + languages: + - go + message: '`Clean` is not intended to sanitize against path traversal attacks. This function is for finding the shortest path name equivalent to the given input. Using `Clean` to sanitize file reads may expose this application to path traversal attacks, where an attacker could access arbitrary files on the server. To fix this easily, write this: `filepath.FromSlash(path.Clean("/"+strings.Trim(req.URL.Path, "/")))` However, a better solution is using the `SecureJoin` function in the package `filepath-securejoin`. See https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://pkg.go.dev/path#Clean + - http://technosophos.com/2016/03/31/go-quickly-cleaning-filepaths.html + - https://labs.detectify.com/2021/12/15/zero-day-path-traversal-grafana/ + - https://dzx.cz/2021/04/02/go_path_traversal/ + - https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme + subcategory: + - vuln + technology: + - go + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern-either: - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseRedirect(..., $STR + $DATA, ...) + "/" + ... + pattern-sinks: + - patterns: + - pattern-either: + - pattern: filepath.Clean($...INNER) + - pattern: path.Clean($...INNER) + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + severity: ERROR + - id: go.lang.security.injection.open-redirect.open-redirect + languages: + - go + message: An HTTP redirect was found to be crafted from user-input `$REQUEST`. This can lead to open redirect vulnerabilities, potentially allowing attackers to redirect users to malicious web sites. It is recommend where possible to not allow user-input to craft the redirect URL. When user-input is necessary to craft the request, it is recommended to follow OWASP best practices to restrict the URL to domains in an allowlist. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + description: An HTTP redirect was found to be crafted from user-input leading to an open redirect vulnerability + impact: MEDIUM + interfile: true + likelihood: MEDIUM + references: + - https://knowledge-base.secureflag.com/vulnerabilities/unvalidated_redirects___forwards/open_redirect_go_lang.html + subcategory: + - vuln + technology: + - go + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern: http.Redirect($W, $REQ, $URL, ...) + - focus-metavariable: $URL + requires: INPUT and not CLEAN + pattern-sources: + - label: INPUT + patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + - label: CLEAN + patterns: + - pattern-either: + - pattern: | + "$URLSTR" + $INPUT + - patterns: + - pattern-either: + - pattern: fmt.Fprintf($F, "$URLSTR", $INPUT, ...) + - pattern: fmt.Sprintf("$URLSTR", $INPUT, ...) + - pattern: fmt.Printf("$URLSTR", $INPUT, ...) + - metavariable-regex: + metavariable: $URLSTR + regex: .*//[a-zA-Z0-10]+\..* + requires: INPUT + severity: WARNING + - id: go.lang.security.injection.raw-html-format.raw-html-format + languages: + - go + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. Use the `html/template` package which will safely render HTML instead, or inspect that the HTML is rendered safely. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + subcategory: + - vuln + technology: + - go + mode: taint + pattern-sanitizers: + - pattern: html.EscapeString(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: fmt.Printf("$HTMLSTR", ...) + - pattern: fmt.Sprintf("$HTMLSTR", ...) + - pattern: fmt.Fprintf($W, "$HTMLSTR", ...) + - pattern: '"$HTMLSTR" + ...' + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + severity: WARNING + - id: go.lang.security.injection.tainted-sql-string.tainted-sql-string + languages: + - go + message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`db.Query("SELECT * FROM t WHERE id = ?", id)`) or a safe library. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://golang.org/doc/database/sql-injection + - https://www.stackhawk.com/blog/golang-sql-injection-guide-examples-and-prevention/ + subcategory: + - vuln + technology: + - go + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern-either: + - pattern: strconv.Atoi(...) - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., request.$W(...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) - - pattern: return django.http.HttpResponseRedirect(..., request.$W(...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) - - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) - - pattern: django.http.HttpResponseRedirect(..., request.$W[...], ...) - - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) - - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) + ($X: bool) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - patterns: + - pattern-inside: | + $VAR = "$SQLSTR"; + ... + - pattern: $VAR += ... + - patterns: + - pattern-inside: | + var $SB strings.Builder + ... + - pattern-inside: | + $SB.WriteString("$SQLSTR") + ... + $SB.String(...) + - pattern: | + $SB.WriteString(...) + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop).* + - patterns: + - pattern-either: + - pattern: fmt.Fprintf($F, "$SQLSTR", ...) + - pattern: fmt.Sprintf("$SQLSTR", ...) + - pattern: fmt.Printf("$SQLSTR", ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).* + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + severity: ERROR + - id: go.lang.security.injection.tainted-url-host.tainted-url-host + languages: + - go + message: A request was found to be crafted from user-input `$REQUEST`. This can lead to Server-Side Request Forgery (SSRF) vulnerabilities, potentially exposing sensitive data. It is recommend where possible to not allow user-input to craft the base request, but to be treated as part of the path or query parameter. When user-input is necessary to craft the request, it is recommended to follow OWASP best practices to prevent abuse, including using an allowlist. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://goteleport.com/blog/ssrf-attacks/ + subcategory: + - vuln + technology: + - go + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $CLIENT := &http.Client{...} + ... + - pattern: $CLIENT.$METHOD($URL, ...) + - pattern: http.$METHOD($URL, ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Get|Head|Post|PostForm)$ + - patterns: + - pattern: | + http.NewRequest("$METHOD", $URL, ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(GET|HEAD|POST|POSTFORM)$ + - focus-metavariable: $URL + requires: INPUT and not CLEAN + pattern-sources: + - label: INPUT + patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + - label: CLEAN + patterns: + - pattern-either: + - pattern: | + "$URLSTR" + $INPUT + - patterns: + - pattern-either: + - pattern: fmt.Fprintf($F, "$URLSTR", $INPUT, ...) + - pattern: fmt.Sprintf("$URLSTR", $INPUT, ...) + - pattern: fmt.Printf("$URLSTR", $INPUT, ...) + - metavariable-regex: + metavariable: $URLSTR + regex: .*//[a-zA-Z0-10]+\..* + requires: INPUT + severity: WARNING + - id: go.lang.security.zip.path-traversal-inside-zip-extraction + languages: + - go + message: File traversal when extracting zip archive + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source_rule_url: https://github.com/securego/gosec/issues/205 + subcategory: + - audit + technology: + - go + pattern: | + reader, $ERR := zip.OpenReader($ARCHIVE) + ... + for _, $FILE := range reader.File { + ... + path := filepath.Join($TARGET, $FILE.Name) + ... + } + severity: WARNING + - id: go.otto.security.audit.dangerous-execution.dangerous-execution + languages: + - go + message: Detected non-static script inside otto VM. Audit the input to 'VM.Run'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - otto + - vm + patterns: + - pattern-inside: | + $VM = otto.New(...) + ... + - pattern-not: $VM.Run("...", ...) + - pattern: $VM.Run(...) + severity: ERROR + - id: go.template.security.insecure-types.go-insecure-templates + languages: + - go + message: usage of insecure template types. They are documented as a security risk. See https://golang.org/pkg/html/template/#HTML. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://golang.org/pkg/html/template/#HTML + - https://twitter.com/empijei/status/1275177219011350528 + subcategory: + - audit + technology: + - template + patterns: + - pattern-inside: | + import "html/template" + ... + - pattern-either: + - pattern: var $VAR template.HTML = $EXP + - pattern: var $VAR template.CSS = $EXP + - pattern: var $VAR template.HTMLAttr = $EXP + - pattern: var $VAR template.JS = $EXP + - pattern: var $VAR template.JSStr = $EXP + - pattern: var $VAR template.Srcset = $EXP + severity: WARNING + - id: go.template.security.ssti.go-ssti + languages: + - go + message: A server-side template injection occurs when an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side. When using "html/template" always check that user inputs are validated and sanitized before included within the template. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine' + impact: HIGH + likelihood: LOW + references: + - https://www.onsecurity.io/blog/go-ssti-method-research/ + - http://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html + subcategory: + - vuln + technology: + - go + patterns: + - pattern-inside: | + import ("html/template") + ... + - pattern: $TEMPLATE = fmt.Sprintf("...", $ARG, ...) + - patterns: + - pattern-either: + - pattern-inside: | + func $FN(..., $REQ *http.Request, ...){ + ... + } + - pattern-inside: | + func $FN(..., $REQ http.Request, ...){ + ... + } + - pattern-inside: | + func(..., $REQ *http.Request, ...){ + ... + } + - patterns: + - pattern-either: + - pattern-inside: | + $ARG := $REQ.URL.Query().Get(...) + ... + $T, $ERR := $TMPL.Parse($TEMPLATE) + - pattern-inside: | + $ARG := $REQ.Form.Get(...) + ... + $T, $ERR := $TMPL.Parse($TEMPLATE) + - pattern-inside: | + $ARG := $REQ.PostForm.Get(...) + ... + $T, $ERR := $TMPL.Parse($TEMPLATE) + severity: ERROR + - id: java.android.best-practice.manifest-security-features.manifest-usescleartexttraffic-true + languages: + - generic + message: The Android manifest is configured to allow non-encrypted connections. Evaluate if this is necessary for your app, and disable it if appropriate. This flag is ignored on Android 7 (API 24) and above if a Network Security Config is present. + metadata: + category: best-practice + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + references: + - https://developer.android.com/guide/topics/manifest/application-element#usesCleartextTraffic + - https://developer.android.com/training/articles/security-config + technology: + - android + paths: + include: + - '*.xml' + patterns: + - pattern: | + android:usesCleartextTraffic="true" + - pattern-not-inside: | + + severity: INFO + - id: java.android.best-practice.manifest-security-features.manifest-usescleartexttraffic-ignored-by-nsc + languages: + - generic + message: Manifest uses both `android:usesCleartextTraffic` and Network Security Config. The `usesCleartextTraffic` directive is ignored on Android 7 (API 24) and above if a Network Security Config is present. + metadata: + category: best-practice + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + references: + - https://developer.android.com/guide/topics/manifest/application-element#usesCleartextTraffic + - https://developer.android.com/training/articles/security-config + technology: + - android + paths: + include: + - '*.xml' + patterns: + - pattern-either: - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseRedirect(..., $DATA, ...) + android:usesCleartextTraffic ... android:networkSecurityConfig - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) + android:networkSecurityConfig ... android:usesCleartextTraffic + - pattern-not-inside: | + + severity: INFO + - id: java.android.best-practice.network-security-config.nsc-allows-plaintext-traffic + languages: + - generic + message: The Network Security Config is set to allow non-encrypted connections. Evaluate if this is necessary for your app, and disable it if appropriate. (To hide this warning, set `xmlns:tools="http://schemas.android.com/tools" tools:ignore="InsecureBaseConfiguration"` as parameters to your ``) + metadata: + category: best-practice + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + references: + - https://developer.android.com/training/articles/security-config + - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/ + technology: + - android + paths: + include: + - '*.xml' + patterns: + - pattern: | + + - pattern-not-inside: | + + - pattern-not-inside: | + ... ... ... ... ... ... ... ... ... ... + severity: INFO + - id: java.android.best-practice.network-security-config.nsc-pinning-without-backup + languages: + - generic + message: Your app uses TLS public key pinning without specifying a backup key. If you are forced to change TLS keys or CAs on short notice, not having a backup pin can lead to connectivity issues until you can push out an update. It is considered best practice to add at least one additional pin as a backup. + metadata: + category: best-practice + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + references: + - https://developer.android.com/training/articles/security-config#CertificatePinning + - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/ + technology: + - android + paths: + include: + - '*.xml' + patterns: + - pattern: | + ... + - pattern-not-inside: | + ......... + - pattern-inside: | + ... ... + - pattern-inside: | + ... ... ... ... ... + - pattern-not-inside: | + + severity: INFO + - id: java.android.best-practice.network-security-config.nsc-pinning-without-expiration + languages: + - generic + message: Your app uses TLS public key pinning without specifying an expiration date. If your users do not update the app to receive new pins in time, expired or replaced certificates can lead to connectivity issues until they install an update. It is considered best practice to set an expiration time, after which the system will default to trusting system CAs and disregard the pin. + metadata: + category: best-practice + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + references: + - https://developer.android.com/training/articles/security-config#CertificatePinning + - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/ + technology: + - android + paths: + include: + - '*.xml' + patterns: + - pattern: | + ... ... ... + - pattern-not-inside: | + ... ... ... + - pattern-inside: | + ... ... ... ... ... + - pattern-not-inside: | + + severity: INFO + - id: java.android.best-practice.network-security-config.nsc-allows-user-ca-certs + languages: + - generic + message: The Network Security Config is set to accept user-installed CAs. Evaluate if this is necessary for your app, and disable it if appropriate. (To hide this warning, set `xmlns:tools="http://schemas.android.com/tools" tools:ignore="AcceptsUserCertificates"` as parameters to your ``) + metadata: + category: best-practice + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + references: + - https://developer.android.com/training/articles/security-config + - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/ + technology: + - android + paths: + include: + - '*.xml' + patterns: + - pattern: | + + - pattern-inside: | + ... ... ... ... + - pattern-not-inside: | + + - pattern-not-inside: | + ... ... ... ... ... ... ... ... ... ... + severity: WARNING + - id: java.android.best-practice.network-security-config.nsc-allows-user-ca-certs-for-domain + languages: + - generic + message: The Network Security Config is set to accept user-installed CAs for the domain `$DOMAIN`. Evaluate if this is necessary for your app, and disable it if appropriate. (To hide this warning, set `xmlns:tools="http://schemas.android.com/tools" tools:ignore="AcceptsUserCertificates"` as parameters to your ``) + metadata: + category: best-practice + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + references: + - https://developer.android.com/training/articles/security-config + - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/ + technology: + - android + paths: + include: + - '*.xml' + patterns: + - pattern: | + + - pattern-inside: | + ... ... ... + - pattern-inside: | + ... $DOMAIN ... ... ... + - pattern-not-inside: | + + - pattern-not-inside: | + ... ... ... ... ... ... ... ... ... ... + severity: WARNING + - id: java.android.security.exported_activity.exported_activity + languages: + - generic + message: The application exports an activity. Any application on the device can launch the exported activity which may compromise the integrity of your application or its data. Ensure that any exported activities do not have privileged access to your application's control plane. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-926: Improper Export of Android Application Components' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A5:2021 Security Misconfiguration + references: + - https://cwe.mitre.org/data/definitions/926.html + subcategory: + - vuln + technology: + - Android + paths: + exclude: + - sources/ + - classes3.dex + - '*.so' + include: + - '*AndroidManifest.xml' + patterns: + - pattern-not-inside: + - pattern-inside: " \n" + - pattern-either: - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) + + - pattern: | + ... /> + severity: WARNING + - id: java.aws-lambda.security.tainted-sql-string.tainted-sql-string + languages: + - java + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + interfile: true + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/SQL_Injection + subcategory: + - vuln + technology: + - aws-lambda + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR".concat(...) + - patterns: + - pattern-inside: | + StringBuilder $SB = new StringBuilder("$SQLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$SQLSTR"; + ... + - pattern: $VAR += ... + - pattern: String.format("$SQLSTR", ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b + - pattern-not-inside: | + System.out.$PRINTLN(...) + pattern-sources: + - patterns: + - focus-metavariable: $EVENT + - pattern-either: + - pattern: | + $HANDLERTYPE $HANDLER($TYPE $EVENT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { + ... + } + - pattern: | + $HANDLERTYPE $HANDLER(InputStream $EVENT, OutputStream $OUT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { + ... + } + severity: ERROR + - id: java.aws-lambda.security.tainted-sqli.tainted-sqli + languages: + - java + message: Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use parameterized SQL queries or properly sanitize user input instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + interfile: true + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - sql + - java + - aws-lambda + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: "(java.sql.CallableStatement $STMT) = ...; \n" + - pattern: | + (java.sql.Statement $STMT) = ...; + - pattern: | + (java.sql.PreparedStatement $STMT) = ...; + - pattern: | + $VAR = $CONN.prepareStatement(...) + - pattern: | + $PATH.queryForObject(...); + - pattern: | + (java.util.Map $STMT) = $PATH.queryForMap(...); + - pattern: | + (org.springframework.jdbc.support.rowset.SqlRowSet $STMT) = ...; + - patterns: + - pattern-inside: | + (String $SQL) = "$SQLSTR" + ...; + ... + - pattern: $PATH.$SQLCMD(..., $SQL, ...); + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(^SELECT.* | ^INSERT.* | ^UPDATE.*) + - metavariable-regex: + metavariable: $SQLCMD + regex: (execute|query|executeUpdate|batchUpdate) + pattern-sources: + - patterns: + - focus-metavariable: $EVENT + - pattern-either: + - pattern: | + $HANDLERTYPE $HANDLER($TYPE $EVENT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { + ... + } + - pattern: | + $HANDLERTYPE $HANDLER(InputStream $EVENT, OutputStream $OUT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { + ... + } + severity: WARNING + - id: java.java-jwt.security.audit.jwt-decode-without-verify.java-jwt-decode-without-verify + languages: + - java + message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-345: Insufficient Verification of Data Authenticity' + impact: HIGH + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - vuln + technology: + - jwt + patterns: + - pattern: | + com.auth0.jwt.JWT.decode(...); + - pattern-not-inside: |- + class $CLASS { + ... + $RETURNTYPE $FUNC (...) { + ... + $VERIFIER.verify(...); + ... + } + } + severity: WARNING + - id: java.java-jwt.security.jwt-hardcode.java-jwt-hardcoded-secret + languages: + - java + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + subcategory: + - vuln + technology: + - java + - secrets + - jwt + patterns: + - pattern-either: + - pattern: | + (Algorithm $ALG) = $ALGO.$HMAC("$Y"); + - pattern: | + $SECRET = "$Y"; + ... + (Algorithm $ALG) = $ALGO.$HMAC($SECRET); + - pattern: | + class $CLASS { + ... + $TYPE $SECRET = "$Y"; + ... + $RETURNTYPE $FUNC (...) { + ... + (Algorithm $ALG) = $ALGO.$HMAC($SECRET); + ... + } + ... + } + - focus-metavariable: $Y + - metavariable-regex: + metavariable: $HMAC + regex: (HMAC384|HMAC256|HMAC512) + severity: WARNING + - id: java.java-jwt.security.jwt-none-alg.java-jwt-none-alg + languages: + - java + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - vuln + technology: + - jwt + pattern-either: + - pattern: | + $JWT.sign(com.auth0.jwt.algorithms.Algorithm.none()); + - pattern: | + $NONE = com.auth0.jwt.algorithms.Algorithm.none(); + ... + $JWT.sign($NONE); + - pattern: |- + class $CLASS { + ... + $TYPE $NONE = com.auth0.jwt.algorithms.Algorithm.none(); + ... + $RETURNTYPE $FUNC (...) { + ... + $JWT.sign($NONE); + ... + } + ... + } + severity: ERROR + - id: java.jax-rs.security.insecure-resteasy.insecure-resteasy-deserialization + languages: + - java + message: When a Restful webservice endpoint is configured to use wildcard mediaType {*/*} as a value for the @Consumes annotation, an attacker could abuse the SerializableProvider by sending a HTTP Request with a Content-Type of application/x-java-serialized-object. The body of that request would be processed by the SerializationProvider and could contain a malicious payload, which may lead to arbitrary code execution when calling the $Y.getObject method. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://access.redhat.com/blogs/766093/posts/3162112 + subcategory: + - audit + technology: + - jax-rs + pattern-either: + - pattern: | + @Consumes({"application/x-java-serialized-object"}) + - pattern: | + @Consumes({"*/*"}) + - pattern: | + @Consumes("*/*") + - pattern: | + @Consumes({MediaType.WILDCARD_TYPE}) + severity: WARNING + - id: java.jax-rs.security.insecure-resteasy.default-resteasy-provider-abuse + languages: + - java + message: When a Restful webservice endpoint isn't configured with a @Consumes annotation, an attacker could abuse the SerializableProvider by sending a HTTP Request with a Content-Type of application/x-java-serialized-object. The body of that request would be processed by the SerializationProvider and could contain a malicious payload, which may lead to arbitrary code execution. Instead, add a @Consumes annotation to the function or class. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://access.redhat.com/blogs/766093/posts/3162112 + subcategory: + - audit + technology: + - jax-rs + patterns: + - pattern: | + @Path("...") + public $RETURNTYPE $METHOD(...) { ...} + - pattern-not-inside: | + @GET + public $RETURNTYPE $METHOD(...) { ...} + - pattern-not-inside: | + @Path("...") + @Consumes(...) + public $RETURNTYPE $METHOD(...) { ...} + - pattern-not-inside: | + @Consumes(...) + public class $CLASSNAME { ... } + severity: WARNING + - id: java.jax-rs.security.jax-rs-path-traversal.jax-rs-path-traversal + languages: + - java + message: Detected a potential path traversal. A malicious actor could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://www.owasp.org/index.php/Path_Traversal + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN + subcategory: + - vuln + technology: + - jax-rs + pattern-either: + - pattern: | + $RETURNTYPE $FUNC (..., @PathParam(...) $TYPE $VAR, ...) { + ... + new File(..., $VAR, ...); + ... + } + - pattern: |- + $RETURNTYPE $FUNC (..., @javax.ws.rs.PathParam(...) $TYPE $VAR, ...) { + ... + new File(..., $VAR, ...); + ... + } + severity: WARNING + - id: java.jboss.security.session_sqli.find-sql-string-concatenation + languages: + - java + message: In $METHOD, $X is used to construct a SQL query via string concatenation. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - jboss + pattern-either: + - pattern: | + $RETURN $METHOD(...,String $X,...){ + ... + Session $SESSION = ...; + ... + String $QUERY = ... + $X + ...; + ... + PreparedStatement $PS = $SESSION.connection().prepareStatement($QUERY); + ... + ResultSet $RESULT = $PS.executeQuery(); + ... + } + - pattern: | + $RETURN $METHOD(...,String $X,...){ + ... + String $QUERY = ... + $X + ...; + ... + Session $SESSION = ...; + ... + PreparedStatement $PS = $SESSION.connection().prepareStatement($QUERY); + ... + ResultSet $RESULT = $PS.executeQuery(); + ... + } + severity: ERROR + - id: java.jjwt.security.jwt-none-alg.jjwt-none-alg + languages: + - java + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + metadata: + asvs: + control_id: 3.5.3 Insecue Stateless Session Tokens + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + patterns: + - pattern: | + io.jsonwebtoken.Jwts.builder(); + - pattern-not-inside: |- + $RETURNTYPE $FUNC(...) { + ... + $JWTS.signWith(...); + ... + } + severity: ERROR + - id: java.lang.correctness.assignment-comparison.assignment-comparison + languages: + - java + message: The value of `$X` is being ignored and will be used in the conditional test + metadata: + category: correctness + technology: + - java + pattern-either: + - pattern: if ($X=true) { ... } + - pattern: if ($X=false) { ... } + severity: ERROR + - id: java.lang.correctness.eqeq.eqeq + languages: + - java + message: '`$X == $X` or `$X != $X` is always true. (Unless the value compared is a float or double). To test if `$X` is not-a-number, use `Double.isNaN($X)`.' + metadata: + category: correctness + technology: + - java + patterns: + - pattern-not-inside: assert $X; + - pattern-not-inside: | + assert $X : $Y; + - pattern-either: + - pattern: $X == $X + - pattern: $X != $X + - pattern-not: 1 == 1 + severity: ERROR + - id: java.lang.correctness.hardcoded-conditional.hardcoded-conditional + languages: + - java + message: This if statement will always have the same behavior and is therefore unnecessary. + metadata: + category: correctness + technology: + - java + patterns: + - pattern-either: + - pattern: if (true) { ... } + - pattern: if (false) { ... } + - pattern: if ($VAR = true) { ... } + - pattern: if ($VAR = false) { ... } + - pattern: if ($EXPR && false) { ... } + - pattern: if (false && $EXPR) { ... } + - pattern: if ($EXPR || true) { ... } + - pattern: if (true || $EXPR) { ... } + severity: ERROR + - id: java.lang.correctness.no-string-eqeq.no-string-eqeq + languages: + - java + message: Strings should not be compared with '=='. This is a reference comparison operator. Use '.equals()' instead. + metadata: + category: correctness + technology: + - java + patterns: + - pattern-not: null == (String $Y) + - pattern: $X == (String $Y) + severity: WARNING + - id: java.lang.security.audit.anonymous-ldap-bind.anonymous-ldap-bind + languages: + - java + message: Detected anonymous LDAP bind. This permits anonymous users to execute LDAP statements. Consider enforcing authentication for LDAP. See https://docs.oracle.com/javase/tutorial/jndi/ldap/auth_mechs.html for more information. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-287: Improper Authentication' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#LDAP_ANONYMOUS + subcategory: + - audit + technology: + - java + pattern: | + $ENV.put($CTX.SECURITY_AUTHENTICATION, "none"); + ... + $DCTX = new InitialDirContext($ENV, ...); + severity: WARNING + - id: java.lang.security.audit.bad-hexa-conversion.bad-hexa-conversion + languages: + - java + message: '''Integer.toHexString()'' strips leading zeroes from each byte if read byte-by-byte. This mistake weakens the hash value computed since it introduces more collisions. Use ''String.format("%02X", ...)'' instead.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-704: Incorrect Type Conversion or Cast' + impact: LOW + likelihood: LOW + owasp: A03:2017 - Sensitive Data Exposure + references: + - https://cwe.mitre.org/data/definitions/704.html + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#BAD_HEXA_CONVERSION + subcategory: + - audit + technology: + - java + pattern: |- + $X $METHOD(...) { + ... + MessageDigest $MD = ...; + ... + $MD.digest(...); + ... + Integer.toHexString(...); + } + severity: WARNING + - id: java.lang.security.audit.blowfish-insufficient-key-size.blowfish-insufficient-key-size + languages: + - java + message: Using less than 128 bits for Blowfish is considered insecure. Use 128 bits or more, or switch to use AES instead. + metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#BLOWFISH_KEY_SIZE + subcategory: + - audit + technology: + - java + patterns: + - pattern: | + $KEYGEN = KeyGenerator.getInstance("Blowfish"); + ... + $KEYGEN.init($SIZE); + - metavariable-comparison: + comparison: $SIZE < 128 + metavariable: $SIZE + severity: WARNING + - fix: | + "AES/GCM/NoPadding" + id: java.lang.security.audit.cbc-padding-oracle.cbc-padding-oracle + languages: + - java + message: Using CBC with PKCS5Padding is susceptible to padding oracle attacks. A malicious actor could discern the difference between plaintext with valid or invalid padding. Further, CBC mode does not include any integrity checks. Use 'AES/GCM/NoPadding' instead. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://capec.mitre.org/data/definitions/463.html + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#cipher-modes + - https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PADDING_ORACLE + subcategory: + - audit + technology: + - java + patterns: + - pattern-inside: Cipher.getInstance("=~/.*\/CBC\/PKCS5Padding/") + - pattern: | + "=~/.*\/CBC\/PKCS5Padding/" + severity: WARNING + - id: java.lang.security.audit.command-injection-formatted-runtime-call.command-injection-formatted-runtime-call + languages: + - java + message: A formatted or concatenated string was detected as input to a java.lang.Runtime call. This is dangerous if a variable is controlled by user input and could result in a command injection. Ensure your variables are not controlled by users or sufficiently sanitized. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#COMMAND_INJECTION. + subcategory: + - audit + technology: + - java + patterns: + - metavariable-pattern: + metavariable: $RUNTIME + patterns: + - pattern-either: + - pattern: (java.lang.Runtime $R) + - pattern: java.lang.Runtime.getRuntime(...) + - pattern-either: + - pattern: $RUNTIME.exec($X + $Y); + - pattern: $RUNTIME.exec(String.format(...)); + - pattern: $RUNTIME.loadLibrary($X + $Y); + - pattern: $RUNTIME.loadLibrary(String.format(...)); + - patterns: + - pattern-either: + - pattern: | + $RUNTIME.exec("=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $ARG,...) + - pattern: | + $RUNTIME.exec(Arrays.asList("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...),...) + - pattern: | + $RUNTIME.exec(new String[]{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...},...) + - patterns: + - pattern-either: + - pattern: | + $RUNTIME.exec($CMD,"-c",$ARG,...) + - pattern: | + $RUNTIME.exec(Arrays.asList($CMD,"-c",$ARG,...),...) + - pattern: | + $RUNTIME.exec(new String[]{$CMD,"-c",$ARG,...},...) + - pattern-inside: | + $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/"; + ... + - patterns: + - pattern-either: + - pattern: | + $RUNTIME.exec($CMD, $EXECUTE, $ARG, ...) + - pattern-inside: | + $CMD = new String[]{"=~/(sh|bash|ksh|csh|tcsh|zsh)/", ...}; + ... + - patterns: + - pattern-either: + - pattern: | + $RUNTIME.exec("=~/(sh|bash|ksh|csh|tcsh|zsh)/", $BASH, $ARG,...) + - pattern: | + $RUNTIME.exec(Arrays.asList("=~/(sh|bash|ksh|csh|tcsh|zsh)/",$BASH,$ARG,...),...) + - pattern: | + $RUNTIME.exec(new String[]{"=~/(sh|bash|ksh|csh|tcsh|zsh)/",$BASH,$ARG,...},...) + - pattern-inside: | + $BASH = new String[]{"=~/(-c)/", ...}; + ... + - pattern-not-inside: | + $ARG = "..."; + ... + - pattern-not: | + $RUNTIME.exec("...","...","...",...) + - pattern-not: | + $RUNTIME.exec(new String[]{"...","...","...",...},...) + - pattern-not: | + $RUNTIME.exec(Arrays.asList("...","...","...",...),...) + severity: ERROR + - id: java.lang.security.audit.command-injection-process-builder.command-injection-process-builder + languages: + - java + message: A formatted or concatenated string was detected as input to a ProcessBuilder call. This is dangerous if a variable is controlled by user input and could result in a command injection. Ensure your variables are not controlled by users or sufficiently sanitized. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - java + pattern-either: + - patterns: + - pattern: | + new ProcessBuilder($CMD,...) + - pattern-not-inside: | + $CMD = "..."; + ... + - pattern-not-inside: | + $CMD = Arrays.asList("...",...); + ... + - pattern-not-inside: | + $CMD = new String[]{"...",...}; + ... + - pattern-not: | + new ProcessBuilder("...",...) + - pattern-not: | + new ProcessBuilder(new String[]{"...",...},...) + - pattern-not: | + new ProcessBuilder(Arrays.asList("...",...),...) + - patterns: + - pattern: | + $PB.command($CMD,...) + - pattern-inside: | + $TYPE $PB = new ProcessBuilder(...); + ... + - pattern-not-inside: | + $CMD = "..."; + ... + - pattern-not-inside: | + $CMD = Arrays.asList("...",...); + ... + - pattern-not-inside: | + $CMD = new String[]{"...",...}; + ... + - pattern-not: | + $PB.command("...",...) + - pattern-not: | + $PB.command(new String[]{"...",...},...) + - pattern-not: | + $PB.command(Arrays.asList("...",...),...) + - patterns: + - pattern-either: + - pattern: | + new ProcessBuilder("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...) + - pattern: | + new ProcessBuilder("cmd","/c",$ARG,...) + - pattern: | + new ProcessBuilder(Arrays.asList("cmd","/c",$ARG,...),...) + - pattern: | + new ProcessBuilder(new String[]{"cmd","/c",$ARG,...},...) + - patterns: + - pattern-either: + - pattern: | + new ProcessBuilder($CMD,"/c",$ARG,...) + - pattern: | + new ProcessBuilder(Arrays.asList($CMD,"/c",$ARG,...),...) + - pattern: | + new ProcessBuilder(new String[]{$CMD,"/c",$ARG,...},...) + - pattern-inside: | + $CMD = "cmd"; + ... + - pattern-not-inside: | + $ARG = "..."; + ... + - pattern-not: | + new ProcessBuilder("...","...","...",...) + - pattern-not: | + new ProcessBuilder(new String[]{"...","...","...",...},...) + - pattern-not: | + new ProcessBuilder(Arrays.asList("...","...","...",...),...) + - patterns: + - pattern-either: + - pattern: | + $PB.command("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...) + - pattern: | + $PB.command("cmd","/c",$ARG,...) + - pattern: | + $PB.command(Arrays.asList("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...),...) + - pattern: | + $PB.command(Arrays.asList("cmd","/c",$ARG,...),...) + - pattern: | + $PB.command(new String[]{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...},...) + - pattern: | + $PB.command(new String[]{"cmd","/c",$ARG,...},...) + - patterns: + - pattern-either: + - pattern: | + $PB.command($CMD,"-c",$ARG,...) + - pattern: | + $PB.command(Arrays.asList($CMD,"-c",$ARG,...),...) + - pattern: | + $PB.command(new String[]{$CMD,"-c",$ARG,...},...) + - pattern-inside: | + $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/"; + ... + - patterns: + - pattern-either: + - pattern: | + $PB.command($CMD,"/c",$ARG,...) + - pattern: | + $PB.command(Arrays.asList($CMD,"/c",$ARG,...),...) + - pattern: | + $PB.command(new String[]{$CMD,"/c",$ARG,...},...) + - pattern-inside: | + $CMD = "cmd"; + ... + - pattern-inside: | + $TYPE $PB = new ProcessBuilder(...); + ... + - pattern-not-inside: | + $ARG = "..."; + ... + - pattern-not: | + $PB.command("...","...","...",...) + - pattern-not: | + $PB.command(new String[]{"...","...","...",...},...) + - pattern-not: | + $PB.command(Arrays.asList("...","...","...",...),...) + severity: ERROR + - id: java.lang.security.audit.cookie-missing-httponly.cookie-missing-httponly + languages: + - java + message: A cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie. Set the 'HttpOnly' flag by calling 'cookie.setHttpOnly(true);' + metadata: + asvs: + control_id: 3.4.2 Missing Cookie Attribute + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v34-cookie-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#HTTPONLY_COOKIE + subcategory: + - audit + technology: + - java + patterns: + - pattern-not-inside: $COOKIE.setValue(""); ... + - pattern-either: + - pattern: $COOKIE.setHttpOnly(false); + - patterns: + - pattern-not-inside: $COOKIE.setHttpOnly(...); ... + - pattern-not-inside: $COOKIE = ResponseCookie.from(...). ...; ... + - pattern: $RESPONSE.addCookie($COOKIE); + severity: WARNING + - id: java.lang.security.audit.cookie-missing-secure-flag.cookie-missing-secure-flag + languages: + - java + message: A cookie was detected without setting the 'secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'secure' flag by calling '$COOKIE.setSecure(true);' + metadata: + asvs: + control_id: 3.4.1 Missing Cookie Attribute + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v34-cookie-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#INSECURE_COOKIE + subcategory: + - audit + technology: + - java + patterns: + - pattern-not-inside: $COOKIE.setValue(""); ... + - pattern-either: + - pattern: $COOKIE.setSecure(false); + - patterns: + - pattern-not-inside: $COOKIE.setSecure(...); ... + - pattern-not-inside: $COOKIE = ResponseCookie.from(...). ...; ... + - pattern: $RESPONSE.addCookie($COOKIE); + severity: WARNING + - id: java.lang.security.audit.crlf-injection-logs.crlf-injection-logs + languages: + - java + message: When data from an untrusted source is put into a logger and not neutralized correctly, an attacker could forge log entries or include malicious content. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-93: Improper Neutralization of CRLF Sequences (''CRLF Injection'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#CRLF_INJECTION_LOGS + subcategory: + - vuln + technology: + - java + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + class $CLASS { + ... + Logger $LOG = ...; + ... + } + - pattern-either: + - pattern-inside: | + $X $METHOD(...,HttpServletRequest $REQ,...) { + ... + } + - pattern-inside: | + $X $METHOD(...,ServletRequest $REQ,...) { + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + HttpServletRequest $REQ = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + ServletRequest $REQ = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + Logger $LOG = ...; + ... + HttpServletRequest $REQ = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + Logger $LOG = ...; + ... + ServletRequest $REQ = ...; + ... + } + - pattern-either: + - pattern: | + String $VAL = $REQ.getParameter(...); + ... + $LOG.$LEVEL(<... $VAL ...>); + - pattern: | + String $VAL = $REQ.getParameter(...); + ... + $LOG.log($LEVEL,<... $VAL ...>); + - pattern: | + $LOG.$LEVEL(<... $REQ.getParameter(...) ...>); + - pattern: | + $LOG.log($LEVEL,<... $REQ.getParameter(...) ...>); + severity: WARNING + - fix: | + "AES/GCM/NoPadding" + id: java.lang.security.audit.crypto.des-is-deprecated.des-is-deprecated + languages: + - java + - kt + message: DES is considered deprecated. AES is the recommended cipher. Upgrade to use AES. See https://www.nist.gov/news-events/news/2005/06/nist-withdraws-outdated-data-encryption-standard for more information. + metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::symmetric-algorithm::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.nist.gov/news-events/news/2005/06/nist-withdraws-outdated-data-encryption-standard + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#DES_USAGE + subcategory: + - vuln + technology: + - java + patterns: + - pattern-either: + - pattern-inside: $CIPHER.getInstance("=~/DES/.*/") + - pattern-inside: $CIPHER.getInstance("DES") + - pattern-either: + - pattern: | + "=~/DES/.*/" + - pattern: | + "DES" + severity: WARNING + - id: java.lang.security.audit.crypto.desede-is-deprecated.desede-is-deprecated + languages: + - java + - kt + message: Triple DES (3DES or DESede) is considered deprecated. AES is the recommended cipher. Upgrade to use AES. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::symmetric-algorithm::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#TDES_USAGE + subcategory: + - vuln + technology: + - java + patterns: + - pattern-either: + - pattern: | + $CIPHER.getInstance("=~/DESede.*/") + - pattern: | + $CRYPTO.KeyGenerator.getInstance("DES") + severity: WARNING + - id: java.lang.security.audit.crypto.ecb-cipher.ecb-cipher + languages: + - java + message: Cipher in ECB mode is detected. ECB mode produces the same output for the same input each time which allows an attacker to intercept and replay the data. Further, ECB mode does not provide any integrity checking. See https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::mode::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#ECB_MODE + subcategory: + - vuln + technology: + - java + patterns: + - pattern: | + Cipher $VAR = $CIPHER.getInstance($MODE); + - metavariable-regex: + metavariable: $MODE + regex: .*ECB.* + severity: WARNING + - id: java.lang.security.audit.crypto.gcm-detection.gcm-detection + languages: + - java + message: GCM detected, please check that IV/nonce is not reused, an Initialization Vector (IV) is a nonce used to randomize the encryption, so that even if multiple messages with identical plaintext are encrypted, the generated corresponding ciphertexts are different. Unlike the Key, the IV usually does not need to be secret, rather it is important that it is random and unique. Certain encryption schemes the IV is exchanged in public as part of the ciphertext. Reusing same Initialization Vector with the same Key to encrypt multiple plaintext blocks allows an attacker to compare the ciphertexts and then, with some assumptions on the content of the messages, to gain important information about the data being encrypted. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-323: Reusing a Nonce, Key Pair in Encryption' + functional-categories: + - crypto::search::randomness::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A02:2021 - Cryptographic Failures + references: + - https://cwe.mitre.org/data/definitions/323.html + subcategory: + - audit + technology: + - java + patterns: + - pattern-either: + - pattern: $METHOD.getInstance("AES/GCM/NoPadding",...); + - pattern: new GCMParameterSpec(...); + severity: INFO + - id: java.lang.security.audit.crypto.gcm-nonce-reuse.gcm-nonce-reuse + languages: + - java + message: 'GCM IV/nonce is reused: encryption can be totally useless' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-323: Reusing a Nonce, Key Pair in Encryption' + functional-categories: + - crypto::search::randomness::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://www.youtube.com/watch?v=r1awgAl90wM + subcategory: + - vuln + technology: + - java + patterns: + - pattern-either: + - pattern: new GCMParameterSpec(..., "...".getBytes(...), ...); + - pattern: byte[] $NONCE = "...".getBytes(...); ... new GCMParameterSpec(..., $NONCE, ...); + severity: ERROR + - id: java.lang.security.audit.crypto.no-null-cipher.no-null-cipher + languages: + - java + message: 'NullCipher was detected. This will not encrypt anything; the cipher text will be the same as the plain text. Use a valid, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#NULL_CIPHER + subcategory: + - vuln + technology: + - java + patterns: + - pattern-either: + - pattern: new NullCipher(...); + - pattern: new javax.crypto.NullCipher(...); + severity: WARNING + - id: java.lang.security.audit.crypto.no-static-initialization-vector.no-static-initialization-vector + languages: + - java + message: Initialization Vectors (IVs) for block ciphers should be randomly generated each time they are used. Using a static IV means the same plaintext encrypts to the same ciphertext every time, weakening the strength of the encryption. + metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-329: Generation of Predictable IV with CBC Mode' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A02:2021 - Cryptographic Failures + references: + - https://cwe.mitre.org/data/definitions/329.html + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#STATIC_IV + subcategory: + - vuln + technology: + - java + pattern-either: + - pattern: | + byte[] $IV = { + ... + }; + ... + new IvParameterSpec($IV, ...); + - pattern: | + class $CLASS { + byte[] $IV = { + ... + }; + ... + $METHOD(...) { + ... + new IvParameterSpec($IV, ...); + ... + } + } + severity: WARNING + - id: java.lang.security.audit.crypto.rsa-no-padding.rsa-no-padding + languages: + - java + - kt + message: Using RSA without OAEP mode weakens the encryption. + metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::mode::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://rdist.root.org/2009/10/06/why-rsa-encryption-padding-is-critical/ + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#RSA_NO_PADDING + subcategory: + - vuln + technology: + - java + - kotlin + pattern: $CIPHER.getInstance("=~/RSA/[Nn][Oo][Nn][Ee]/NoPadding/") + severity: WARNING + - id: java.lang.security.audit.crypto.ssl.avoid-implementing-custom-digests.avoid-implementing-custom-digests + languages: + - java + message: 'Cryptographic algorithms are notoriously difficult to get right. By implementing a custom message digest, you risk introducing security issues into your program. Use one of the many sound message digests already available to you: MessageDigest sha256Digest = MessageDigest.getInstance("SHA256");' + metadata: + asvs: + control_id: 6.2.2 Insecure Custom Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#custom-algorithms + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#CUSTOM_MESSAGE_DIGEST + subcategory: + - audit + technology: + - java + pattern: |- + class $CLASS extends MessageDigest { + ... + } + severity: WARNING + - fix-regex: + regex: DefaultHttpClient + replacement: HttpClientBuilder + id: java.lang.security.audit.crypto.ssl.defaulthttpclient-is-deprecated.defaulthttpclient-is-deprecated + languages: + - java + message: DefaultHttpClient is deprecated. Further, it does not support connections using TLS1.2, which makes using DefaultHttpClient a security hazard. Use HttpClientBuilder instead. + metadata: + asvs: + control_id: 9.1.3 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v91-client-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#DEFAULT_HTTP_CLIENT + subcategory: + - audit + technology: + - java + pattern: new DefaultHttpClient(...); + severity: WARNING + - id: java.lang.security.audit.crypto.ssl.insecure-hostname-verifier.insecure-hostname-verifier + languages: + - java + message: Insecure HostnameVerifier implementation detected. This will accept any SSL certificate with any hostname, which creates the possibility for man-in-the-middle attacks. + metadata: + asvs: + control_id: 9.2.1 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_HOSTNAME_VERIFIER + subcategory: + - audit + technology: + - java + pattern-either: + - pattern: | + class $CLASS implements HostnameVerifier { + ... + public boolean verify(...) { return true; } + } + - pattern: |- + new HostnameVerifier(...){ + public boolean verify(...) { + return true; + } + } + - pattern: import org.apache.http.conn.ssl.NoopHostnameVerifier; + severity: WARNING + - id: java.lang.security.audit.crypto.ssl.insecure-trust-manager.insecure-trust-manager + languages: + - java + message: Detected empty trust manager implementations. This is dangerous because it accepts any certificate, enabling man-in-the-middle attacks. Consider using a KeyStore and TrustManagerFactory instead. See https://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https for more information. + metadata: + asvs: + control_id: 9.2.1 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_TRUST_MANAGER + subcategory: + - audit + technology: + - java + patterns: + - pattern-either: + - pattern-inside: | + class $CLASS implements X509TrustManager { + ... + } + - pattern-inside: | + new X509TrustManager() { + ... + } + - pattern-inside: | + class $CLASS implements X509ExtendedTrustManager { + ... + } + - pattern-inside: | + new X509ExtendedTrustManager() { + ... + } + - pattern-not: public void checkClientTrusted(...) { $SOMETHING; } + - pattern-not: public void checkServerTrusted(...) { $SOMETHING; } + - pattern-either: + - pattern: public void checkClientTrusted(...) {} + - pattern: public void checkServerTrusted(...) {} + - pattern: public X509Certificate[] getAcceptedIssuers(...) { return null; } + severity: WARNING + - id: java.lang.security.audit.crypto.unencrypted-socket.unencrypted-socket + languages: + - java + message: Detected use of a Java socket that is not encrypted. As a result, the traffic could be read by an attacker intercepting the network traffic. Use an SSLSocket created by 'SSLSocketFactory' or 'SSLServerSocketFactory' instead. + metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + functional-categories: + - net::search::crypto-config::java.net + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNENCRYPTED_SOCKET + subcategory: + - vuln + technology: + - java + pattern-either: + - pattern: new ServerSocket(...) + - pattern: new Socket(...) + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-aes-ecb.use-of-aes-ecb + languages: + - java + message: 'Use of AES with ECB mode detected. ECB doesn''t provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::mode::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + subcategory: + - vuln + technology: + - java + pattern: $CIPHER.getInstance("=~/AES/ECB.*/") + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-blowfish.use-of-blowfish + languages: + - java + message: 'Use of Blowfish was detected. Blowfish uses a 64-bit block size that makes it vulnerable to birthday attacks, and is therefore considered non-compliant. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + subcategory: + - vuln + technology: + - java + pattern: $CIPHER.getInstance("Blowfish") + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-default-aes.use-of-default-aes + languages: + - java + message: 'Use of AES with no settings detected. By default, java.crypto.Cipher uses ECB mode. ECB doesn''t provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: java.crypto.Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::mode::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + subcategory: + - vuln + technology: + - java + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + import javax; + ... + - pattern-either: + - pattern: javax.crypto.Cipher.getInstance("AES") + - pattern: (javax.crypto.Cipher $CIPHER).getInstance("AES") + - patterns: + - pattern-either: + - pattern-inside: | + import javax.*; + ... + - pattern-inside: | + import javax.crypto; + ... + - pattern-either: + - pattern: crypto.Cipher.getInstance("AES") + - pattern: (crypto.Cipher $CIPHER).getInstance("AES") + - patterns: + - pattern-either: + - pattern-inside: | + import javax.crypto.*; + ... + - pattern-inside: | + import javax.crypto.Cipher; + ... + - pattern-either: + - pattern: Cipher.getInstance("AES") + - pattern: (Cipher $CIPHER).getInstance("AES") + severity: WARNING + - fix: | + getSha512Digest + id: java.lang.security.audit.crypto.use-of-md5-digest-utils.use-of-md5-digest-utils + languages: + - java + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use HMAC instead. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-328: Use of Weak Hash' + functional-categories: + - crypto::search::hash-algorithm::org.apache.commons + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_MD5 + subcategory: + - vuln + technology: + - java + patterns: + - pattern: | + $DU.$GET_ALGO().digest(...) + - metavariable-pattern: + metavariable: $GET_ALGO + pattern: getMd5Digest + - metavariable-pattern: + metavariable: $DU + pattern: DigestUtils + - focus-metavariable: $GET_ALGO + severity: WARNING + - fix: | + "SHA-512" + id: java.lang.security.audit.crypto.use-of-md5.use-of-md5 + languages: + - java + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use HMAC instead. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-328: Use of Weak Hash' + functional-categories: + - crypto::search::hash-algorithm::java.security + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_MD5 + subcategory: + - vuln + technology: + - java + patterns: + - pattern: | + java.security.MessageDigest.getInstance($ALGO, ...); + - metavariable-regex: + metavariable: $ALGO + regex: (.MD5.) + - focus-metavariable: $ALGO + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-rc2.use-of-rc2 + languages: + - java + message: 'Use of RC2 was detected. RC2 is vulnerable to related-key attacks, and is therefore considered non-compliant. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + subcategory: + - vuln + technology: + - java + pattern: $CIPHER.getInstance("RC2") + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-rc4.use-of-rc4 + languages: + - java + message: 'Use of RC4 was detected. RC4 is vulnerable to several attacks, including stream cipher attacks and bit flipping attacks. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + subcategory: + - vuln + technology: + - java + pattern: $CIPHER.getInstance("RC4") + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-sha1.use-of-sha1 + languages: + - java + message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Instead, use PBKDF2 for password hashing or SHA256 or SHA512 for other hash function applications. + metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-328: Use of Weak Hash' + functional-categories: + - crypto::search::hash-algorithm::javax.crypto + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_SHA1 + subcategory: + - vuln + technology: + - java + pattern-either: + - patterns: + - pattern: | + java.security.MessageDigest.getInstance("$ALGO", ...); + - metavariable-regex: + metavariable: $ALGO + regex: (SHA1|SHA-1) + - pattern: | + $DU.getSha1Digest().digest(...) + severity: WARNING + - id: java.lang.security.audit.crypto.weak-random.weak-random + languages: + - java + message: Detected use of the functions `Math.random()` or `java.util.Random()`. These are both not cryptographically strong random number generators (RNGs). If you are using these RNGs to create passwords or secret tokens, use `java.security.SecureRandom` instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-330: Use of Insufficiently Random Values' + functional-categories: + - crypto::search::randomness::java.security + impact: MEDIUM + likelihood: LOW + owasp: + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - java + pattern-either: + - pattern: | + new java.util.Random(...).$FUNC(...) + - pattern: | + java.lang.Math.random(...) + severity: WARNING + - id: java.lang.security.audit.crypto.weak-rsa.use-of-weak-rsa-key + languages: + - java + message: RSA keys should be at least 2048 bits based on NIST recommendation. + metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::key-length::java.security + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#RSA_KEY_SIZE + subcategory: + - vuln + technology: + - java + patterns: + - pattern: | + KeyPairGenerator $KEY = $G.getInstance("RSA"); + ... + $KEY.initialize($BITS); + - metavariable-comparison: + comparison: $BITS < 2048 + metavariable: $BITS + severity: WARNING + - id: java.lang.security.audit.dangerous-groovy-shell.dangerous-groovy-shell + languages: + - java + message: A expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#GROOVY_SHELL + subcategory: + - audit + technology: + - groovy + patterns: + - pattern-either: + - pattern: | + $SHELL.parse(...) + - pattern: | + $SHELL.evaluate(...) + - pattern: | + $SHELL.parseClass(...) + - pattern-either: + - pattern-inside: | + groovy.lang.GroovyShell $SHELL = ...; + ... + - pattern-inside: | + groovy.lang.GroovyClassLoader $SHELL = ...; + ... + - pattern-not: | + $SHELL.parse("...",...) + - pattern-not: | + $SHELL.evaluate("...",...) + - pattern-not: | + $SHELL.parseClass("...",...) + severity: WARNING + - id: java.lang.security.audit.el-injection.el-injection + languages: + - java + message: An expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#EL_INJECTION + subcategory: + - audit + technology: + - java + patterns: + - pattern-either: + - pattern: | + class $CLASS { + ... + ExpressionFactory $EF; + ... + $X $METHOD(...) { + ... + $EF.createValueExpression($CTX,$INPUT,...); + ... + } + ... + } + - pattern: | + class $CLASS { + ... + ExpressionFactory $EF = ...; + ... + $X $METHOD(...) { + ... + $EF.createValueExpression($CTX,$INPUT,...); + ... + } + ... + } + - pattern: | + $X $METHOD(...) { + ... + ExpressionFactory $EF = ...; + ... + $EF.createValueExpression($CTX,$INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ExpressionFactory $EF,...) { + ... + $EF.createValueExpression($CTX,$INPUT,...); + ... + } + - pattern: | + class $CLASS { + ... + ExpressionFactory $EF; + ... + $X $METHOD(...) { + ... + $EF.createMethodExpression($CTX,$INPUT,...); + ... + } + ... + } + - pattern: | + class $CLASS { + ... + ExpressionFactory $EF = ...; + ... + $X $METHOD(...) { + ... + $EF.createMethodExpression($CTX,$INPUT,...); + ... + } + ... + } + - pattern: | + $X $METHOD(...) { + ... + ExpressionFactory $EF = ...; + ... + $EF.createMethodExpression($CTX,$INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ExpressionFactory $EF,...) { + ... + $EF.createMethodExpression($CTX,$INPUT,...); + ... + } + - pattern: | + $X $METHOD(String $INPUT, ...) { + ... + $OBJECT.buildConstraintViolationWithTemplate($INPUT, ...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $EF.createValueExpression($CTX,"...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $EF.createValueExpression($CTX,$S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $EF.createMethodExpression($CTX,"...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $EF.createMethodExpression($CTX,$S,...); + ... + } + severity: WARNING + - id: java.lang.security.audit.formatted-sql-string.formatted-sql-string + languages: + - java + message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. + metadata: + asvs: + control_id: 5.3.5 Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + - https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html#create_ps + - https://software-security.sans.org/developer-how-to/fix-sql-injection-in-java-using-prepared-callable-statement + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SQL_INJECTION + subcategory: + - vuln + technology: + - java + mode: taint + options: + taint_assume_safe_booleans: true + taint_assume_safe_numbers: true + pattern-propagators: + - from: $X + pattern: (StringBuffer $S).append($X) + to: $S + - from: $X + pattern: (StringBuilder $S).append($X) + to: $S + pattern-sanitizers: + - patterns: + - pattern: (CriteriaBuilder $CB).$ANY(...) + pattern-sinks: + - patterns: + - pattern-not: $S.$SQLFUNC(<... "=~/.*TABLE *$/" ...>) + - pattern-not: $S.$SQLFUNC(<... "=~/.*TABLE %s$/" ...>) + - pattern-either: + - pattern: (Statement $S).$SQLFUNC(...) + - pattern: (PreparedStatement $P).$SQLFUNC(...) + - pattern: (Connection $C).createStatement(...).$SQLFUNC(...) + - pattern: (Connection $C).prepareStatement(...).$SQLFUNC(...) + - pattern: (EntityManager $EM).$SQLFUNC(...) + - metavariable-regex: + metavariable: $SQLFUNC + regex: execute|executeQuery|createQuery|query|addBatch|nativeSQL|create|prepare + requires: CONCAT + pattern-sources: + - label: INPUT + patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + $ANNOT $FUNC (..., $INPUT, ...) { + ... + } + - pattern: (String $INPUT) + - focus-metavariable: $INPUT + - label: CONCAT + patterns: + - pattern-either: + - pattern: $X + $INPUT + - pattern: $X += $INPUT + - pattern: $STRB.append($INPUT) + - pattern: String.format(..., $INPUT, ...) + - pattern: String.join(..., $INPUT, ...) + - pattern: (String $STR).concat($INPUT) + - pattern: $INPUT.concat(...) + - pattern: new $STRB(..., $INPUT, ...) + requires: INPUT + severity: ERROR + - id: java.lang.security.audit.http-response-splitting.http-response-splitting + languages: + - java + message: Older Java application servers are vulnerable to HTTP response splitting, which may occur if an HTTP request can be injected with CRLF characters. This finding is reported for completeness; it is recommended to ensure your environment is not affected by testing this yourself. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers (''HTTP Request/Response Splitting'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://www.owasp.org/index.php/HTTP_Response_Splitting + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#HTTP_RESPONSE_SPLITTING + subcategory: + - vuln + technology: + - java + pattern-either: + - pattern: | + $VAR = $REQ.getParameter(...); + ... + $COOKIE = new Cookie(..., $VAR, ...); + ... + $RESP.addCookie($COOKIE, ...); + - patterns: + - pattern-inside: | + $RETTYPE $FUNC(...,@PathVariable $TYPE $VAR, ...) { + ... + } + - pattern: | + $COOKIE = new Cookie(..., $VAR, ...); + ... + $RESP.addCookie($COOKIE, ...); + severity: INFO + - id: java.lang.security.audit.insecure-smtp-connection.insecure-smtp-connection + languages: + - java + message: Insecure SMTP connection detected. This connection will trust any SSL certificate. Enable certificate verification by setting 'email.setSSLCheckServerIdentity(true)'. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-297: Improper Validation of Certificate with Host Mismatch' + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#INSECURE_SMTP_SSL + subcategory: + - vuln + technology: + - java + patterns: + - pattern-not-inside: | + $EMAIL.setSSLCheckServerIdentity(true); + ... + - pattern-inside: | + $EMAIL = new SimpleEmail(...); + ... + - pattern: $EMAIL.send(...); + severity: WARNING + - id: java.lang.security.audit.java-reverse-shell.java-reverse-shell + languages: + - java + message: Semgrep found potential reverse shell behavior + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - java + patterns: + - pattern-either: + - pattern: | + Socket $S=new Socket(...); + ... + InputStream $SI = $S.getInputStream(); + ... + while(!$S.isClosed()) + { + ... + while($SI.available()>0)$PO.write($SI.read()); + ... + $SO.flush(); + ... + } + - pattern-inside: | + Process $P=new ProcessBuilder(...).redirectErrorStream(true).start(); + ... + $P.destroy(); + severity: WARNING + - id: java.lang.security.audit.jdbc-sql-formatted-string.jdbc-sql-formatted-string + languages: + - java + message: 'Possible JDBC injection detected. Use the parameterized query feature available in queryForObject instead of concatenating or formatting strings: ''jdbc.queryForObject("select * from table where name = ?", Integer.class, parameterName);''' + metadata: + asvs: + control_id: 5.3.5 Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SQL_INJECTION_SPRING_JDBC + subcategory: + - audit + technology: + - jdbc + patterns: + - pattern-inside: | + $JDBC = new JdbcTemplate(...); + ... + - pattern-either: + - pattern: $JDBC.queryForObject($STR + $VAR, ...); + - pattern: $JDBC.queryForObject(String.format(...), ...); + - pattern: | + String $Q = $STR + $VAR; + ... + $JDBC.queryForObject($Q, ...); + - pattern: | + String $Q = String.format(...); + ... + $JDBC.queryForObject($Q, ...); + - pattern: | + StringBuilder $Q = new StringBuilder(...); + ... + $Q.append($STR + $VAR); + ... + $JDBC.queryForObject($Q, ...); + - pattern: $JDBC.queryForList($STR + $VAR); + - pattern: $JDBC.queryForList(String.format(...)); + - pattern: | + String $Q = $STR + $VAR; + ... + $JDBC.queryForList($Q); + - pattern: | + String $Q = String.format(...); + ... + $JDBC.queryForList($Q); + - pattern: | + StringBuilder $Q = new StringBuilder(...); + ... + $Q.append($STR + $VAR); + ... + $JDBC.queryForList($Q, ...); + - pattern: $JDBC.update($STR + $VAR); + - pattern: $JDBC.update(String.format(...)); + - pattern: | + String $Q = $STR + $VAR; + ... + $JDBC.update($Q); + - pattern: | + String $Q = String.format(...); + ... + $JDBC.update($Q); + - pattern: | + StringBuilder $Q = new StringBuilder(...); + ... + $Q.append($STR + $VAR); + ... + $JDBC.update($Q, ...); + - pattern: $JDBC.execute($STR + $VAR); + - pattern: $JDBC.execute(String.format(...)); + - pattern: | + String $Q = $STR + $VAR; + ... + $JDBC.execute($Q); + - pattern: | + String $Q = String.format(...); + ... + $JDBC.execute($Q); + - pattern: | + StringBuilder $Q = new StringBuilder(...); + ... + $Q.append($STR + $VAR); + ... + $JDBC.execute($Q, ...); + - pattern: $JDBC.insert($STR + $VAR); + - pattern: $JDBC.insert(String.format(...)); + - pattern: | + String $Q = $STR + $VAR; + ... + $JDBC.insert($Q); + - pattern: | + String $Q = String.format(...); + ... + $JDBC.insert($Q); + - pattern: | + StringBuilder $Q = new StringBuilder(...); + ... + $Q.append($STR + $VAR); + ... + $JDBC.insert($Q, ...); + severity: WARNING + - id: java.lang.security.audit.ldap-entry-poisoning.ldap-entry-poisoning + languages: + - java + message: An object-returning LDAP search will allow attackers to control the LDAP response. This could lead to Remote Code Execution. + metadata: + asvs: + control_id: 5.3.7 Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf + - https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#LDAP_ENTRY_POISONING + subcategory: + - audit + technology: + - java + pattern-either: + - pattern: | + new SearchControls($S, $CL, $TL, $AT, true, $DEREF) + - pattern: | + SearchControls $VAR = new SearchControls(); + ... + $VAR.setReturningObjFlag(true); + severity: WARNING + - id: java.lang.security.audit.ldap-injection.ldap-injection + languages: + - java + message: Detected non-constant data passed into an LDAP query. If this data can be controlled by an external user, this is an LDAP injection. Ensure data passed to an LDAP query is not controllable; or properly sanitize the data. + metadata: + asvs: + control_id: 5.3.7 Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#LDAP_INJECTION + subcategory: + - audit + technology: + - java + patterns: + - pattern-either: + - pattern-inside: | + $X $METHOD(...) { + ... + InitialDirContext $CTX = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + DirContext $CTX = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + InitialLdapContext $CTX = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + LdapContext $CTX = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + LdapCtx $CTX = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + EventDirContext $CTX = ...; + ... + } + - pattern: | + $X $METHOD(...) { + ... + $CTX.search($Y,$INPUT,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $CTX.search($Y,"...",...); + ... + } + severity: WARNING + - id: java.lang.security.audit.md5-used-as-password.md5-used-as-password + languages: + - java + message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as PBKDF2 or bcrypt. You can use `javax.crypto.SecretKeyFactory` with `SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")` or, if using Spring, `org.springframework.security.crypto.bcrypt`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html + - https://github.com/returntocorp/semgrep-rules/issues/1609 + - https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory + - https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html + subcategory: + - vuln + technology: + - java + - md5 + mode: taint + pattern-sinks: + - patterns: + - pattern: $MODEL.$METHOD(...); + - metavariable-regex: + metavariable: $METHOD + regex: (?i)(.*password.*) + pattern-sources: + - patterns: + - pattern-inside: | + $TYPE $MD = MessageDigest.getInstance("MD5"); + ... + - pattern: $MD.digest(...); + severity: WARNING + - id: java.lang.security.audit.object-deserialization.object-deserialization + languages: + - java + message: Found object deserialization using ObjectInputStream. Deserializing entire Java objects is dangerous because malicious actors can create Java object streams with unintended consequences. Ensure that the objects being deserialized are not user-controlled. If this must be done, consider using HMACs to sign the data stream to make sure it is not tampered with, or consider only transmitting object fields and populating a new object. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://www.owasp.org/index.php/Deserialization_of_untrusted_data + - https://www.oracle.com/java/technologies/javase/seccodeguide.html#8 + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#OBJECT_DESERIALIZATION + subcategory: + - audit + technology: + - java + pattern: new ObjectInputStream(...); + severity: WARNING + - id: java.lang.security.audit.ognl-injection.ognl-injection + languages: + - java + message: A expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#OGNL_INJECTION + subcategory: + - audit + technology: + - ognl + patterns: + - pattern-either: + - pattern: | + $X $METHOD(...,OgnlReflectionProvider $P,...) { + ... + $P.getGetMethod($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlReflectionProvider $P,...) { + ... + $P.getSetMethod($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlReflectionProvider $P,...) { + ... + $P.getField($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlReflectionProvider $P,...) { + ... + $P.setProperties($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlReflectionProvider $P,...) { + ... + $P.setProperty($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlReflectionProvider $P,...) { + ... + $P.getValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlReflectionProvider $P,...) { + ... + $P.setValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ReflectionProvider $P,...) { + ... + $P.getGetMethod($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ReflectionProvider $P,...) { + ... + $P.getSetMethod($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ReflectionProvider $P,...) { + ... + $P.getField($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ReflectionProvider $P,...) { + ... + $P.setProperties($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ReflectionProvider $P,...) { + ... + $P.setProperty($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ReflectionProvider $P,...) { + ... + $P.getValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ReflectionProvider $P,...) { + ... + $P.setValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,TextParseUtil $P,...) { + ... + $P.translateVariables($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,TextParseUtil $P,...) { + ... + $P.translateVariablesCollection($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,TextParseUtil $P,...) { + ... + $P.shallBeIncluded($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,TextParseUtil $P,...) { + ... + $P.commaDelimitedStringToSet($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,TextParser $P,...) { + ... + $P.evaluate($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlTextParser $P,...) { + ... + $P.evaluate($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlUtil $P,...) { + ... + $P.setProperties($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlUtil $P,...) { + ... + $P.setProperty($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlUtil $P,...) { + ... + $P.getValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlUtil $P,...) { + ... + $P.setValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlUtil $P,...) { + ... + $P.callMethod($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlUtil $P,...) { + ... + $P.compile($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,VelocityStrutsUtil $P,...) { + ... + $P.evaluate($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,StrutsUtil $P,...) { + ... + $P.isTrue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,StrutsUtil $P,...) { + ... + $P.findString($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,StrutsUtil $P,...) { + ... + $P.findValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,StrutsUtil $P,...) { + ... + $P.getText($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,StrutsUtil $P,...) { + ... + $P.translateVariables($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,StrutsUtil $P,...) { + ... + $P.makeSelectList($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,OgnlTool $P,...) { + ... + $P.findValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ValueStack $P,...) { + ... + $P.findString($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ValueStack $P,...) { + ... + $P.findValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ValueStack $P,...) { + ... + $P.setValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...,ValueStack $P,...) { + ... + $P.setParameter($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlReflectionProvider $P = ...; + ... + $P.getGetMethod($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlReflectionProvider $P = ...; + ... + $P.getSetMethod($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlReflectionProvider $P = ...; + ... + $P.getField($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlReflectionProvider $P = ...; + ... + $P.setProperties($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlReflectionProvider $P = ...; + ... + $P.setProperty($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlReflectionProvider $P = ...; + ... + $P.getValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlReflectionProvider $P = ...; + ... + $P.setValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ReflectionProvider $P = ...; + ... + $P.getGetMethod($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ReflectionProvider $P = ...; + ... + $P.getSetMethod($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ReflectionProvider $P = ...; + ... + $P.getField($T, $INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ReflectionProvider $P = ...; + ... + $P.setProperties($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ReflectionProvider $P = ...; + ... + $P.setProperty($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ReflectionProvider $P = ...; + ... + $P.getValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ReflectionProvider $P = ...; + ... + $P.setValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + TextParseUtil $P = ...; + ... + $P.translateVariables($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + TextParseUtil $P = ...; + ... + $P.translateVariablesCollection($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + TextParseUtil $P = ...; + ... + $P.shallBeIncluded($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + TextParseUtil $P = ...; + ... + $P.commaDelimitedStringToSet($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + TextParser $P = ...; + ... + $P.evaluate($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlTextParser $P = ...; + ... + $P.evaluate($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlUtil $P = ...; + ... + $P.setProperties($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlUtil $P = ...; + ... + $P.setProperty($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlUtil $P = ...; + ... + $P.getValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlUtil $P = ...; + ... + $P.setValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlUtil $P = ...; + ... + $P.callMethod($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlUtil $P = ...; + ... + $P.compile($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + VelocityStrutsUtil $P = ...; + ... + $P.evaluate($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + StrutsUtil $P = ...; + ... + $P.isTrue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + StrutsUtil $P = ...; + ... + $P.findString($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + StrutsUtil $P = ...; + ... + $P.findValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + StrutsUtil $P = ...; + ... + $P.getText($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + StrutsUtil $P = ...; + ... + $P.translateVariables($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + StrutsUtil $P = ...; + ... + $P.makeSelectList($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + OgnlTool $P = ...; + ... + $P.findValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ValueStack $P = ...; + ... + $P.findString($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ValueStack $P = ...; + ... + $P.findValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ValueStack $P = ...; + ... + $P.setValue($INPUT,...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + ValueStack $P = ...; + ... + $P.setParameter($INPUT,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.getGetMethod($T,"...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.getSetMethod($T,"...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.getField($T,"...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.setProperties("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.setProperty("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.getValue("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.setValue("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.translateVariables("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.translateVariablesCollection("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.shallBeIncluded("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.commaDelimitedStringToSet("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.evaluate("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.callMethod("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.compile("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.isTrue("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.findString("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.findValue("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.getText("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.makeSelectList("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $P.setParameter("...",...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.getGetMethod($T,$S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.getSetMethod($T,$S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.getField($T,$S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.setProperties($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.setProperty($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.getValue($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.setValue($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.translateVariables($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.translateVariablesCollection($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.shallBeIncluded($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.commaDelimitedStringToSet($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.evaluate($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.callMethod($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.compile($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.isTrue($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.findString($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.findValue($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.getText($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.makeSelectList($S,...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $P.setParameter($S,...); + ... + } + severity: WARNING + - id: java.lang.security.audit.overly-permissive-file-permission.overly-permissive-file-permission + languages: + - java + message: Detected file permissions that are overly permissive (read, write, and execute). It is generally a bad practices to set overly permissive file permission such as read+write+exec for all users. If the file affected is a configuration, a binary, a script or sensitive data, it can lead to privilege escalation or information leakage. Instead, follow the principle of least privilege and give users only the permissions they need. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-276: Incorrect Default Permissions' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#OVERLY_PERMISSIVE_FILE_PERMISSION + subcategory: + - audit + technology: + - java + pattern-either: + - pattern: java.nio.file.Files.setPosixFilePermissions($FILE, java.nio.file.attribute.PosixFilePermissions.fromString("=~/(^......r..$)|(^.......w.$)|(^........x$)/")); + - pattern: | + $TYPE $P = java.nio.file.attribute.PosixFilePermissions.fromString("=~/(^......r..$)|(^.......w.$)|(^........x$)/"); + ... + java.nio.file.Files.setPosixFilePermissions($FILE, $P); + - pattern: | + $P.add(java.nio.file.attribute.PosixFilePermission.OTHERS_READ); + ... + java.nio.file.Files.setPosixFilePermissions($FILE, $P); + - pattern: | + $P.add(java.nio.file.attribute.PosixFilePermission.OTHERS_WRITE); + ... + java.nio.file.Files.setPosixFilePermissions($FILE, $P); + - pattern: |- + $P.add(java.nio.file.attribute.PosixFilePermission.OTHERS_EXECUTE); + ... + java.nio.file.Files.setPosixFilePermissions($FILE, $P); + severity: WARNING + - id: java.lang.security.audit.permissive-cors.permissive-cors + languages: + - java + message: https://find-sec-bugs.github.io/bugs.htm#PERMISSIVE_CORS Permissive CORS policy will allow a malicious application to communicate with the victim application in an inappropriate way, leading to spoofing, data theft, relay and other attacks. + metadata: + asvs: + control_id: 14.4.8 Permissive CORS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x22-V14-Config.md#v144-http-security-headers-requirements + section: 'V14: Configuration Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-183: Permissive List of Allowed Inputs' + impact: LOW + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit + technology: + - java + pattern-either: + - pattern: | + HttpServletResponse $RES = ...; + ... + $RES.addHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); + - pattern: | + HttpServletResponse $RES = ...; + ... + $RES.setHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); + - pattern: | + ServerHttpResponse $RES = ...; + ... + $RES.getHeaders().add("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); + - pattern: | + HttpHeaders $HEADERS = ...; + ... + $HEADERS.set("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); + - pattern: | + ServerWebExchange $SWE = ...; + ... + $SWE.getResponse().getHeaders().add("Access-Control-Allow-Origin", "*"); + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...) { + ... + $RES.addHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...) { + ... + $RES.setHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); + ... + } + - pattern: | + $X $METHOD(...,ServerHttpResponse $RES,...) { + ... + $RES.getHeaders().add("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); + ... + } + - pattern: | + $X $METHOD(...,ServerWebExchange $SWE,...) { + ... + $SWE.getResponse().getHeaders().add("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); + ... + } + - pattern: ResponseEntity.$RES().header("=~/access-control-allow-origin/i", "=~/^\*|null$/i") + - pattern: ServerResponse.$RES().header("=~/access-control-allow-origin/i", "=~/^\*|null$/i") + severity: WARNING + - id: java.lang.security.audit.script-engine-injection.script-engine-injection + languages: + - java + message: Detected potential code injection using ScriptEngine. Ensure user-controlled data cannot enter '.eval()', otherwise, this is a code injection vulnerability. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SCRIPT_ENGINE_INJECTION + subcategory: + - audit + technology: + - java + patterns: + - pattern-either: + - pattern-inside: | + class $CLASS { + ... + ScriptEngine $SE; + ... + } + - pattern-inside: | + class $CLASS { + ... + ScriptEngine $SE = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + ScriptEngine $SE = ...; + ... + } + - pattern: | + $X $METHOD(...) { + ... + $SE.eval(...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $SE.eval("..."); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $SE.eval($S); + ... + } + severity: WARNING + - id: java.lang.security.audit.sqli.hibernate-sqli.hibernate-sqli + languages: + - java + message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. + metadata: + asvs: + control_id: 5.3.5 Insecure Custom Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: V5 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SQL_INJECTION_HIBERNATE + subcategory: + - audit + technology: + - hibernate + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + String $SQL = $X + $Y; + ... + - pattern-inside: | + String $SQL = String.format(...); + ... + - pattern-inside: | + $VAL $FUNC(...,String $SQL,...) { + ... + } + - pattern-not-inside: | + String $SQL = "..." + "..."; + ... + - pattern: org.hibernate.criterion.Restrictions.sqlRestriction($SQL,...) + - pattern: org.hibernate.criterion.Restrictions.sqlRestriction(String.format(...),...) + - patterns: + - pattern: org.hibernate.criterion.Restrictions.sqlRestriction($X + $Y,...) + - pattern-not: org.hibernate.criterion.Restrictions.sqlRestriction("..." + "...",...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + String $SQL = $X + $Y; + ... + - pattern-inside: | + String $SQL = String.format(...); + ... + - pattern-inside: | + $TYPE $FUNC(...,String $SQL,...) { + ... + } + - pattern-not-inside: | + String $SQL = "..." + "..."; + ... + - pattern: $SESSION.$METHOD($SQL,...) + - pattern: | + $SESSION.$METHOD(String.format(...),...); + - pattern: | + $SESSION.$METHOD($X + $Y,...); + - pattern-either: + - pattern-inside: | + org.hibernate.Session $SESSION = ...; + ... + - pattern-inside: | + $TYPE $FUNC(...,org.hibernate.Session $SESSION,...) { + ... + } + - pattern-not: | + $SESSION.$METHOD("..." + "...",...); + - metavariable-regex: + metavariable: $METHOD + regex: ^(createQuery|createSQLQuery)$ + severity: WARNING + - id: java.lang.security.audit.sqli.jdbc-sqli.jdbc-sqli + languages: + - java + message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - jdbc + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + String $SQL = $X + $Y; + ... + - pattern-inside: | + String $SQL = String.format(...); + ... + - pattern-inside: | + $VAL $FUNC(...,String $SQL,...) { + ... + } + - pattern-not-inside: | + String $SQL = "..." + "..."; + ... + - pattern: $S.$METHOD($SQL,...) + - pattern: | + $S.$METHOD(String.format(...),...); + - pattern: | + $S.$METHOD($X + $Y,...); + - pattern-either: + - pattern-inside: | + java.sql.Statement $S = ...; + ... + - pattern-inside: | + $TYPE $FUNC(...,java.sql.Statement $S,...) { + ... + } + - pattern-not: | + $S.$METHOD("..." + "...",...); + - metavariable-regex: + metavariable: $METHOD + regex: ^(executeQuery|execute|executeUpdate|executeLargeUpdate|addBatch|nativeSQL)$ + severity: WARNING + - id: java.lang.security.audit.sqli.jdo-sqli.jdo-sqli + languages: + - java + message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - java + pattern-either: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + String $SQL = $X + $Y; + ... + - pattern-inside: | + String $SQL = String.format(...); + ... + - pattern-inside: | + $TYPE $FUNC(...,String $SQL,...) { + ... + } + - pattern-not-inside: | + String $SQL = "..." + "..."; + ... + - pattern: $Q.$METHOD($SQL,...) + - pattern: | + $Q.$METHOD(String.format(...),...); + - pattern: | + $Q.$METHOD($X + $Y,...); + - pattern-either: + - pattern-inside: | + javax.jdo.Query $Q = ...; + ... + - pattern-inside: | + $TYPE $FUNC(...,javax.jdo.Query $Q,...) { + ... + } + - pattern-not: | + $Q.$METHOD("..." + "...",...); + - metavariable-regex: + metavariable: $METHOD + regex: ^(setFilter|setGrouping)$ + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + String $SQL = $X + $Y; + ... + - pattern-inside: | + String $SQL = String.format(...); + ... + - pattern-inside: | + $VAL $FUNC(...,String $SQL,...) { + ... + } + - pattern-not-inside: | + String $SQL = "..." + "..."; + ... + - pattern: $PM.newQuery(...,$SQL,...) + - pattern: | + $PM.newQuery(...,String.format(...),...); + - pattern: | + $PM.newQuery(...,$X + $Y,...); + - pattern-either: + - pattern-inside: | + javax.jdo.PersistenceManager $PM = ...; + ... + - pattern-inside: | + $TYPE $FUNC(...,javax.jdo.PersistenceManager $PM,...) { + ... + } + - pattern-not: | + $PM.newQuery(...,"..." + "...",...); + severity: WARNING + - id: java.lang.security.audit.sqli.jpa-sqli.jpa-sqli + languages: + - java + message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - jpa + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + String $SQL = $X + $Y; + ... + - pattern-inside: | + String $SQL = String.format(...); + ... + - pattern-inside: | + $TYPE $FUNC(...,String $SQL,...) { + ... + } + - pattern-not-inside: | + String $SQL = "..." + "..."; + ... + - pattern: $EM.$METHOD($SQL,...) + - pattern: | + $EM.$METHOD(String.format(...),...); + - pattern: | + $EM.$METHOD($X + $Y,...); + - pattern-either: + - pattern-inside: | + EntityManager $EM = ...; + ... + - pattern-inside: | + $TYPE $FUNC(...,EntityManager $EM,...) { + ... + } + - pattern-not: | + $EM.$METHOD("..." + "...",...); + - metavariable-regex: + metavariable: $METHOD + regex: ^(createQuery|createNativeQuery)$ + severity: WARNING + - id: java.lang.security.audit.sqli.tainted-sql-from-http-request.tainted-sql-from-http-request + languages: + - java + message: Detected input from a HTTPServletRequest going into a SQL sink or statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use parameterized SQL queries or properly sanitize user input instead. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + - https://owasp.org/www-community/attacks/SQL_Injection + subcategory: + - vuln + technology: + - sql + - java + - servlets + - spring + mode: taint + options: + taint_assume_safe_booleans: true + taint_assume_safe_numbers: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: "(java.sql.CallableStatement $STMT) = ...; \n" + - pattern: | + (java.sql.Statement $STMT) = ...; + ... + $OUTPUT = $STMT.$FUNC(...); + - pattern: | + (java.sql.PreparedStatement $STMT) = ...; + - pattern: | + $VAR = $CONN.prepareStatement(...) + - pattern: | + $PATH.queryForObject(...); + - pattern: | + (java.util.Map $STMT) = $PATH.queryForMap(...); + - pattern: | + (org.springframework.jdbc.support.rowset.SqlRowSet $STMT) = ...; + - pattern: | + (org.springframework.jdbc.core.JdbcTemplate $TEMPL).batchUpdate(...) + - patterns: + - pattern-inside: | + (String $SQL) = "$SQLSTR" + ...; + ... + - pattern: $PATH.$SQLCMD(..., $SQL, ...); + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(^SELECT.* | ^INSERT.* | ^UPDATE.*) + - metavariable-regex: + metavariable: $SQLCMD + regex: (execute|query|executeUpdate|batchUpdate) + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ).$REQFUNC(...) + - pattern: "(ServletRequest $REQ).$REQFUNC(...) \n" + - metavariable-regex: + metavariable: $REQFUNC + regex: (getInputStream|getParameter|getParameterMap|getParameterValues|getReader|getCookies|getHeader|getHeaderNames|getHeaders|getPart|getParts|getQueryString) + severity: WARNING + - id: java.lang.security.audit.sqli.turbine-sqli.turbine-sqli + languages: + - java + message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - turbine + pattern-either: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + String $SQL = $X + $Y; + ... + - pattern-inside: | + String $SQL = String.format(...); + ... + - pattern-inside: | + $VAL $FUNC(...,String $SQL,...) { + ... + } + - pattern-not-inside: | + String $SQL = "..." + "..."; + ... + - pattern: $PEER.executeQuery($SQL,...) + - pattern: | + $PEER.executeQuery(String.format(...),...) + - pattern: | + $PEER.executeQuery($X + $Y,...) + - pattern-not: | + $PEER.executeQuery("..." + "...",...) + - metavariable-regex: + metavariable: $PEER + regex: (BasePeer|GroupPeer) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + String $SQL = $X + $Y; + ... + - pattern-inside: | + String $SQL = String.format(...); + ... + - pattern-inside: | + $VAL $FUNC(...,String $SQL,...) { + ... + } + - pattern-not-inside: | + String $SQL = "..." + "..."; + ... + - pattern: $P.executeQuery($SQL,...) + - pattern: | + $P.executeQuery(String.format(...),...) + - pattern: | + $P.executeQuery($X + $Y,...) + - pattern-either: + - pattern-inside: | + BasePeer $P = ...; + ... + - pattern-inside: | + GroupPeer $P = ...; + ... + - pattern-inside: | + $VAL $FUNC(...,GroupPeer $P,...) { + ... + } + - pattern-inside: | + $VAL $FUNC(...,BasePeer $P,...) { + ... + } + - pattern-not: | + $P.executeQuery("..." + "...",...) + severity: WARNING + - id: java.lang.security.audit.sqli.vertx-sqli.vertx-sqli + languages: + - java + message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - vertx + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + String $SQL = $X + $Y; + ... + - pattern-inside: | + String $SQL = String.format(...); + ... + - pattern-inside: | + $TYPE $FUNC(...,String $SQL,...) { + ... + } + - pattern-not-inside: | + String $SQL = "..." + "..."; + ... + - pattern: $SC.$METHOD($SQL,...) + - pattern: | + $SC.$METHOD(String.format(...),...); + - pattern: | + $SC.$METHOD($X + $Y,...); + - pattern-either: + - pattern-inside: | + SqlClient $SC = ...; + ... + - pattern-inside: | + SqlConnection $SC = ...; + ... + - pattern-inside: | + $TYPE $FUNC(...,SqlClient $SC,...) { + ... + } + - pattern-inside: | + $TYPE $FUNC(...,SqlConnection $SC,...) { + ... + } + - pattern-not: | + $SC.$METHOD("..." + "...",...); + - metavariable-regex: + metavariable: $METHOD + regex: ^(query|preparedQuery|prepare)$ + severity: WARNING + - id: java.lang.security.audit.tainted-cmd-from-http-request.tainted-cmd-from-http-request + languages: + - java + message: Detected input from a HTTPServletRequest going into a 'ProcessBuilder' or 'exec' command. This could lead to command injection if variables passed into the exec commands are not properly sanitized. Instead, avoid using these OS commands with user-supplied input, or, if you must use these commands, use a whitelist of specific values. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - java + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (ProcessBuilder $PB) = ...; + - patterns: + - pattern: | + (Process $P) = ...; + - pattern-not: | + (Process $P) = (java.lang.Runtime $R).exec(...); + - patterns: + - pattern: (java.lang.Runtime $R).exec($CMD, ...); + - focus-metavariable: $CMD + - patterns: + - pattern-either: + - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(ProcessBuilder $PB) = ...;\n...\n$PB.command($ARGLIST);\n" + - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(ProcessBuilder $PB) = ...;\n" + - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(Process $P) = ...;\n" + - pattern: | + $ARGLIST.add(...); + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); + ... + for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { + ... + } + - pattern: | + $COOKIE.getValue(...) + severity: ERROR + - id: java.lang.security.audit.tainted-env-from-http-request.tainted-env-from-http-request + languages: + - java + message: Detected input from a HTTPServletRequest going into the environment variables of an 'exec' command. Instead, call the command with user-supplied arguments by using the overloaded method with one String array as the argument. `exec({"command", "arg1", "arg2"})`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-454: External Initialization of Trusted Variables or Data Stores' + cwe2021-top25: false + cwe2022-top25: false + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - java + mode: taint + pattern-sinks: + - patterns: + - pattern: (java.lang.Runtime $R).exec($CMD, $ENV_ARGS, ...); + - focus-metavariable: $ENV_ARGS + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); + ... + for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { + ... + } + - pattern: | + $COOKIE.getValue(...) + severity: ERROR + - id: java.lang.security.audit.tainted-ldapi-from-http-request.tainted-ldapi-from-http-request + languages: + - java + message: Detected input from a HTTPServletRequest going into an LDAP query. This could lead to LDAP injection if the input is not properly sanitized, which could result in attackers modifying objects in the LDAP tree structure. Ensure data passed to an LDAP query is not controllable or properly sanitize the data. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://sensei.securecodewarrior.com/recipes/scw%3Ajava%3ALDAP-injection + subcategory: + - vuln + technology: + - java + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (javax.naming.directory.InitialDirContext $IDC).search(...) + - pattern: | + (javax.naming.directory.DirContext $CTX).search(...) + - pattern-not: | + (javax.naming.directory.InitialDirContext $IDC).search($Y, "...", ...) + - pattern-not: | + (javax.naming.directory.DirContext $CTX).search($Y, "...", ...) + pattern-sources: + - patterns: + - pattern: (HttpServletRequest $REQ) + severity: WARNING + - id: java.lang.security.audit.tainted-session-from-http-request.tainted-session-from-http-request + languages: + - java + message: Detected input from a HTTPServletRequest going into a session command, like `setAttribute`. User input into such a command could lead to an attacker inputting malicious code into your session parameters, blurring the line between what's trusted and untrusted, and therefore leading to a trust boundary violation. This could lead to programmers trusting unvalidated data. Instead, thoroughly sanitize user input before passing it into such function calls. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-501: Trust Boundary Violation' + impact: MEDIUM + interfile: true + likelihood: MEDIUM + owasp: + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - vuln + technology: + - java + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern: (HttpServletRequest $REQ).getSession().$FUNC($NAME, $VALUE); + - metavariable-regex: + metavariable: $FUNC + regex: ^(putValue|setAttribute)$ + - focus-metavariable: $VALUE + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern: | + (HttpServletRequest $REQ).$FUNC(...) + - pattern-not: | + (HttpServletRequest $REQ).getSession() + - patterns: + - pattern-inside: | + (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); + ... + for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { + ... + } + - pattern: | + $COOKIE.getValue(...) + - patterns: + - pattern-inside: | + $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(... ); + ... + - pattern: | + $PARAM = $VALS[$INDEX]; + - patterns: + - pattern-inside: | + $HEADERS = (HttpServletRequest $REQ).getHeaders(...); + ... + $PARAM = $HEADERS.$FUNC(...); + ... + - pattern: | + java.net.URLDecoder.decode($PARAM, ...) + severity: WARNING + - id: java.lang.security.audit.tainted-xpath-from-http-request.tainted-xpath-from-http-request + languages: + - java + message: Detected input from a HTTPServletRequest going into a XPath evaluate or compile command. This could lead to xpath injection if variables passed into the evaluate or compile commands are not properly sanitized. Xpath injection could lead to unauthorized access to sensitive information in XML documents. Instead, thoroughly sanitize user input or use parameterized xpath queries if you can. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-643: Improper Neutralization of Data within XPath Expressions (''XPath Injection'')' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - java + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (javax.xml.xpath.XPath $XP).evaluate(...) + - pattern: | + (javax.xml.xpath.XPath $XP).compile(...).evaluate(...) + pattern-sources: + - patterns: + - pattern: | + (HttpServletRequest $REQ).$FUNC(...) + severity: WARNING + - id: java.lang.security.audit.unsafe-reflection.unsafe-reflection + languages: + - java + message: If an attacker can supply values that the application then uses to determine which class to instantiate or which method to invoke, the potential exists for the attacker to create control flow paths through the application that were not intended by the application developers. This attack vector may allow the attacker to bypass authentication or access control checks or otherwise cause the application to behave in an unexpected manner. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-470: Use of Externally-Controlled Input to Select Classes or Code (''Unsafe Reflection'')' + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://owasp.org/www-community/vulnerabilities/Unsafe_use_of_Reflection + subcategory: + - audit + technology: + - java + patterns: + - pattern: | + Class.forName($CLASS,...) + - pattern-not: | + Class.forName("...",...) + - pattern-not-inside: | + $CLASS = "..."; + ... + severity: WARNING + - id: java.lang.security.audit.unvalidated-redirect.unvalidated-redirect + languages: + - java + message: Application redirects to a destination URL specified by a user-supplied parameter that is not validated. This could direct users to malicious locations. Consider using an allowlist to validate URLs. + metadata: + asvs: + control_id: 5.1.5 Open Redirect + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: LOW + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNVALIDATED_REDIRECT + subcategory: + - vuln + technology: + - java + pattern-either: + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...,String $URL,...) { + ... + $RES.sendRedirect($URL); + ... + } + - pattern: | + $X $METHOD(...,String $URL,...,HttpServletResponse $RES,...) { + ... + $RES.sendRedirect($URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { + ... + String $URL = $REQ.getParameter(...); + ... + $RES.sendRedirect($URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { + ... + String $URL = $REQ.getParameter(...); + ... + $RES.sendRedirect($URL); + ... + } + - pattern: | + $X $METHOD(...,String $URL,...) { + ... + HttpServletResponse $RES = ...; + ... + $RES.sendRedirect($URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { + ... + $RES.sendRedirect($REQ.getParameter(...)); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { + ... + $RES.sendRedirect($REQ.getParameter(...)); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...,String $URL,...) { + ... + $RES.addHeader("Location",$URL); + ... + } + - pattern: | + $X $METHOD(...,String $URL,...,HttpServletResponse $RES,...) { + ... + $RES.addHeader("Location",$URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { + ... + String $URL = $REQ.getParameter(...); + ... + $RES.addHeader("Location",$URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { + ... + String $URL = $REQ.getParameter(...); + ... + $RES.addHeader("Location",$URL); + ... + } + - pattern: | + $X $METHOD(...,String $URL,...) { + ... + HttpServletResponse $RES = ...; + ... + $RES.addHeader("Location",$URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { + ... + $RES.addHeader("Location",$REQ.getParameter(...)); + ... + } + - pattern: |- + $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { + ... + $RES.addHeader("Location",$REQ.getParameter(...)); + ... + } + severity: WARNING + - id: java.lang.security.audit.url-rewriting.url-rewriting + languages: + - java + message: URL rewriting has significant security risks. Since session ID appears in the URL, it may be easily seen by third parties. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#URL_REWRITING + subcategory: + - vuln + technology: + - java + pattern-either: + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...) { + ... + $RES.encodeURL(...); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...) { + ... + $RES.encodeUrl(...); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...) { + ... + $RES.encodeRedirectURL(...); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...) { + ... + $RES.encodeRedirectUrl(...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + HttpServletResponse $RES = ...; + ... + $RES.encodeURL(...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + HttpServletResponse $RES = ...; + ... + $RES.encodeUrl(...); + ... + } + - pattern: | + $X $METHOD(...) { + ... + HttpServletResponse $RES = ...; + ... + $RES.encodeRedirectURL(...); + ... + } + - pattern: |- + $X $METHOD(...) { + ... + HttpServletResponse $RES = ...; + ... + $RES.encodeRedirectUrl(...); + ... + } + severity: WARNING + - fix-regex: + regex: (.*?)\.getInstance\(.*?\) + replacement: \1.getInstance("TLSv1.2") + id: java.lang.security.audit.weak-ssl-context.weak-ssl-context + languages: + - java + message: An insecure SSL context was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use SSLContext.getInstance("TLSv1.2") for the best security. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://tools.ietf.org/html/rfc7568 + - https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html + source_rule_url: https://find-sec-bugs.github.io/bugs.htm#SSL_CONTEXT + subcategory: + - audit + technology: + - java + patterns: + - pattern-not: SSLContext.getInstance("TLSv1.3") + - pattern-not: SSLContext.getInstance("TLSv1.2") + - pattern: SSLContext.getInstance("...") + severity: WARNING + - id: java.lang.security.audit.xml-decoder.xml-decoder + languages: + - java + message: XMLDecoder should not be used to parse untrusted data. Deserializing user input can lead to arbitrary code execution. Use an alternative and explicitly disable external entities. See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html for alternatives and vulnerability prevention. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#XML_DECODER + subcategory: + - audit + technology: + - java + patterns: + - pattern: | + $X $METHOD(...) { + ... + new XMLDecoder(...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + new XMLDecoder("..."); + ... + } + - pattern-not: |- + $X $METHOD(...) { + ... + String $STR = "..."; + ... + new XMLDecoder($STR); + ... + } + severity: WARNING + - id: java.lang.security.audit.xss.jsf.autoescape-disabled.autoescape-disabled + languages: + - regex + message: Detected an element with disabled HTML escaping. If external data can reach this, this is a cross-site scripting (XSS) vulnerability. Ensure no external data can reach here, or remove 'escape=false' from this element. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-150: Improper Neutralization of Escape, Meta, or Control Sequences' + impact: MEDIUM + likelihood: LOW + owasp: A07:2017 - Cross-Site Scripting (XSS) + references: + - https://stackoverflow.com/a/7442668 + subcategory: + - audit + technology: + - jsf + paths: + include: + - '*.html' + - '*.xhtml' + pattern-regex: .*escape.*?=.*?false.* + severity: WARNING + - id: java.lang.security.audit.xss.jsp.no-scriptlets.no-scriptlets + languages: + - regex + message: JSP scriptlet detected. Scriptlets are difficult to use securely and are considered bad practice. See https://stackoverflow.com/a/3180202. Instead, consider migrating to JSF or using the Expression Language '${...}' with the escapeXml function in your JSP files. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-116: Improper Encoding or Escaping of Output' + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://stackoverflow.com/a/3180202 + - https://stackoverflow.com/a/4948856 + subcategory: + - audit + technology: + - jsp + paths: + include: + - '*.jsp' + pattern-regex: \<\%[^\@].* + severity: WARNING + - id: java.lang.security.audit.xss.jsp.use-escapexml.use-escapexml + languages: + - regex + message: Detected an Expression Language segment that does not escape output. This is dangerous because if any data in this expression can be controlled externally, it is a cross-site scripting vulnerability. Instead, use the 'escapeXml' function from the JSTL taglib. See https://www.tutorialspoint.com/jsp/jstl_function_escapexml.htm for more information. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-116: Improper Encoding or Escaping of Output' + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://www.tutorialspoint.com/jsp/jstl_function_escapexml.htm + - https://stackoverflow.com/a/4948856 + - https://stackoverflow.com/a/3180202 + subcategory: + - audit + technology: + - jsp + paths: + include: + - '*.jsp' + pattern-regex: \$\{(?!.*escapeXml).*\} + severity: WARNING + - id: java.lang.security.audit.xss.jsp.use-jstl-escaping.use-jstl-escaping + languages: + - regex + message: Detected an Expression Language segment in a tag that does not escape output. This is dangerous because if any data in this expression can be controlled externally, it is a cross-site scripting vulnerability. Instead, use the 'out' tag from the JSTL taglib to escape this expression. See https://www.tutorialspoint.com/jsp/jstl_core_out_tag.htm for more information. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-116: Improper Encoding or Escaping of Output' + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://www.tutorialspoint.com/jsp/jstl_core_out_tag.htm + - https://stackoverflow.com/a/4948856 + - https://stackoverflow.com/a/3180202 + subcategory: + - audit + technology: + - jsp + paths: + include: + - '*.jsp' + pattern-regex: <(?![A-Za-z0-9]+:out).*?\$\{.*?\}.*> + severity: WARNING + - id: java.lang.security.audit.xss.no-direct-response-writer.no-direct-response-writer + languages: + - java + message: Detected a request with potential user-input going into a OutputStream or Writer object. This bypasses any view or template environments, including HTML escaping, which may expose this application to cross-site scripting (XSS) vulnerabilities. Consider using a view technology such as JavaServer Faces (JSFs) which automatically escapes HTML views. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + license: proprietary license - copyright © Semgrep, Inc. + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaServerFaces.html + subcategory: + - vuln + technology: + - java + - servlets + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern-either: + - pattern: Encode.forHtml(...) + - pattern: (PolicyFactory $POLICY).sanitize(...) + - pattern: (AntiSamy $AS).scan(...) + - pattern: JSoup.clean(...) + - pattern: org.apache.commons.lang.StringEscapeUtils.escapeHtml(...) + - pattern: org.springframework.web.util.HtmlUtils.htmlEscape(...) + - pattern: org.owasp.esapi.ESAPI.encoder().encodeForHTML(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (HttpServletResponse $RESPONSE).getWriter(...).$WRITE(...) + - pattern: | + (HttpServletResponse $RESPONSE).getOutputStream(...).$WRITE(...) + - pattern: | + (java.io.PrintWriter $WRITER).$WRITE(...) + - pattern: | + (PrintWriter $WRITER).$WRITE(...) + - pattern: | + (javax.servlet.ServletOutputStream $WRITER).$WRITE(...) + - pattern: | + (ServletOutputStream $WRITER).$WRITE(...) + - pattern: | + (java.io.OutputStream $WRITER).$WRITE(...) + - pattern: | + (OutputStream $WRITER).$WRITE(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ).$REQFUNC(...) + - pattern: "(ServletRequest $REQ).$REQFUNC(...) \n" + - metavariable-regex: + metavariable: $REQFUNC + regex: (getInputStream|getParameter|getParameterMap|getParameterValues|getReader|getCookies|getHeader|getHeaderNames|getHeaders|getPart|getParts|getQueryString) + severity: WARNING + - id: java.lang.security.audit.xssrequestwrapper-is-insecure.xssrequestwrapper-is-insecure + languages: + - java + message: It looks like you're using an implementation of XSSRequestWrapper from dzone. (https://www.javacodegeeks.com/2012/07/anti-cross-site-scripting-xss-filter.html) The XSS filtering in this code is not secure and can be bypassed by malicious actors. It is recommended to use a stack that automatically escapes in your view or templates instead of filtering yourself. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#XSS_REQUEST_WRAPPER + subcategory: + - audit + technology: + - java + pattern-either: + - pattern: | + class XSSRequestWrapper extends HttpServletRequestWrapper { + ... + } + - pattern: |- + $P = $X.compile("", $X.CASE_INSENSITIVE); + $V = $P.matcher(...).replaceAll(""); + severity: WARNING + - id: java.lang.security.audit.xxe.documentbuilderfactory-disallow-doctype-decl-false.documentbuilderfactory-disallow-doctype-decl-false + languages: + - java + message: DOCTYPE declarations are enabled for $DBFACTORY. Without prohibiting external entity declarations, this is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false. + metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html + subcategory: + - vuln + technology: + - java + - xml + patterns: + - pattern: $DBFACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false); + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + } + severity: ERROR + - fix: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + $FACTORY.newDocumentBuilder(); + id: java.lang.security.audit.xxe.documentbuilderfactory-disallow-doctype-decl-missing.documentbuilderfactory-disallow-doctype-decl-missing + languages: + - java + message: DOCTYPE declarations are enabled for this DocumentBuilderFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false. + metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html + subcategory: + - vuln + technology: + - java + - xml + mode: taint + pattern-sanitizers: + - by-side-effect: true + pattern-either: + - patterns: + - pattern-either: + - pattern: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + - focus-metavariable: $FACTORY + - patterns: + - pattern-either: + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", + true); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); + ... + } + ... + } + - pattern: $M($X) + - focus-metavariable: $X + pattern-sinks: + - patterns: + - pattern: $FACTORY.newDocumentBuilder(); + pattern-sources: + - by-side-effect: true + patterns: + - pattern-either: + - pattern: | + $FACTORY = DocumentBuilderFactory.newInstance(); + - patterns: + - pattern: $FACTORY + - pattern-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + severity: ERROR + - fix: $DBFACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + id: java.lang.security.audit.xxe.documentbuilderfactory-external-general-entities-true.documentbuilderfactory-external-general-entities-true + languages: + - java + message: External entities are allowed for $DBFACTORY. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://xml.org/sax/features/external-general-entities" to false. + metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + subcategory: + - vuln + technology: + - java + - xml + pattern: $DBFACTORY.setFeature("http://xml.org/sax/features/external-general-entities", true); + severity: ERROR + - fix: $DBFACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + id: java.lang.security.audit.xxe.documentbuilderfactory-external-parameter-entities-true.documentbuilderfactory-external-parameter-entities-true + languages: + - java + message: External entities are allowed for $DBFACTORY. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://xml.org/sax/features/external-parameter-entities" to false. + metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + subcategory: + - vuln + technology: + - java + - xml + pattern: $DBFACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", true); + severity: ERROR + - fix: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + $FACTORY.newSAXParser(); + id: java.lang.security.audit.xxe.saxparserfactory-disallow-doctype-decl-missing.saxparserfactory-disallow-doctype-decl-missing + languages: + - java + message: DOCTYPE declarations are enabled for this SAXParserFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature `http://apache.org/xml/features/disallow-doctype-decl` to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features `http://xml.org/sax/features/external-general-entities` and `http://xml.org/sax/features/external-parameter-entities` to false. NOTE - The previous links are not meant to be clicked. They are the literal config key values that are supposed to be used to disable these features. For more information, see https://semgrep.dev/docs/cheat-sheets/java-xxe/#3a-documentbuilderfactory. + metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html + subcategory: + - vuln + technology: + - java + - xml + mode: taint + pattern-sanitizers: + - by-side-effect: true + pattern-either: + - patterns: + - pattern-either: + - pattern: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + - focus-metavariable: $FACTORY + - patterns: + - pattern-either: + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", + true); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); + ... + } + ... + } + - pattern: $M($X) + - focus-metavariable: $X + pattern-sinks: + - patterns: + - pattern: $FACTORY.newSAXParser(); + pattern-sources: + - by-side-effect: true + patterns: + - pattern-either: + - pattern: | + $FACTORY = SAXParserFactory.newInstance(); + - patterns: + - pattern: $FACTORY + - pattern-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + severity: ERROR + - fix: | + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + $FACTORY.newTransformer(...); + id: java.lang.security.audit.xxe.transformerfactory-dtds-not-disabled.transformerfactory-dtds-not-disabled + languages: + - java + message: DOCTYPE declarations are enabled for this TransformerFactory. This is vulnerable to XML external entity attacks. Disable this by setting the attributes "accessExternalDTD" and "accessExternalStylesheet" to "". + metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html + subcategory: + - vuln + technology: + - java + - xml + mode: taint + pattern-sanitizers: + - by-side-effect: true + pattern-either: + - patterns: + - pattern-either: + - pattern: | + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + - pattern: | + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + - pattern: | + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + - pattern: | + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + - focus-metavariable: $FACTORY + - patterns: + - pattern-either: + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + } + ... + } + - pattern: $M($X) + - focus-metavariable: $X + pattern-sinks: + - patterns: + - pattern: $FACTORY.newTransformer(...); + pattern-sources: + - by-side-effect: true + patterns: + - pattern-either: + - pattern: | + $FACTORY = TransformerFactory.newInstance(); + - patterns: + - pattern: $FACTORY + - pattern-inside: | + class $C { + ... + $V $FACTORY = TransformerFactory.newInstance(); + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + } + ... + } + severity: ERROR + - id: java.lang.security.do-privileged-use.do-privileged-use + languages: + - java + message: Marking code as privileged enables a piece of trusted code to temporarily enable access to more resources than are available directly to the code that called it. Be very careful in your use of the privileged construct, and always remember to make the privileged code section as small as possible. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-269: Improper Privilege Management' + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://docs.oracle.com/javase/8/docs/technotes/guides/security/doprivileged.html + - https://wiki.sei.cmu.edu/confluence/display/java/Privilege+Escalation + - http://phrack.org/papers/escaping_the_java_sandbox.html + subcategory: + - audit + technology: + - java + patterns: + - pattern-inside: | + import java.security.*; + ... + - pattern-either: + - pattern: AccessController.doPrivileged(...); + - pattern: class $ACTION implements PrivilegedAction { ... } + severity: WARNING + - id: java.lang.security.httpservlet-path-traversal.httpservlet-path-traversal + languages: + - java + message: Detected a potential path traversal. A malicious actor could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://www.owasp.org/index.php/Path_Traversal + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN + subcategory: + - vuln + technology: + - java + mode: taint + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (java.io.File $FILE) = ... + - pattern: | + (java.io.FileOutputStream $FOS) = ... + - pattern: | + new java.io.FileInputStream(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); + ... + for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { + ... + } + - pattern: | + $COOKIE.getValue(...) + - patterns: + - pattern-inside: | + $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(...); + ... + - pattern: | + $PARAM = $VALS[$INDEX]; + severity: ERROR + - id: java.lang.security.insecure-jms-deserialization.insecure-jms-deserialization + languages: + - java + message: JMS Object messages depend on Java Serialization for marshalling/unmarshalling of the message payload when ObjectMessage.getObject() is called. Deserialization of untrusted data can lead to security flaws; a remote attacker could via a crafted JMS ObjectMessage to execute arbitrary code with the permissions of the application listening/consuming JMS Messages. In this case, the JMS MessageListener consume an ObjectMessage type received inside the onMessage method, which may lead to arbitrary code execution when calling the $Y.getObject method. + metadata: + asvs: + control_id: 5.5.3 Insecue Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities-wp.pdf + subcategory: + - vuln + technology: + - java + patterns: + - pattern-inside: | + public class $JMS_LISTENER implements MessageListener { + ... + public void onMessage(Message $JMS_MSG) { + ... + } + } + - pattern-either: + - pattern-inside: $X = $Y.getObject(...); + - pattern-inside: $X = ($Z) $Y.getObject(...); + severity: WARNING + - id: java.lang.security.jackson-unsafe-deserialization.jackson-unsafe-deserialization + languages: + - java + message: When using Jackson to marshall/unmarshall JSON to Java objects, enabling default typing is dangerous and can lead to RCE. If an attacker can control `$JSON` it might be possible to provide a malicious JSON which can be used to exploit unsecure deserialization. In order to prevent this issue, avoid to enable default typing (globally or by using "Per-class" annotations) and avoid using `Object` and other dangerous types for member variable declaration which creating classes for Jackson based deserialization. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + impact: HIGH + likelihood: LOW + owasp: + - A8:2017 Insecure Deserialization + - A8:2021 Software and Data Integrity Failures + references: + - https://swapneildash.medium.com/understanding-insecure-implementation-of-jackson-deserialization-7b3d409d2038 + - https://cowtowncoder.medium.com/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062 + - https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/ + subcategory: + - audit + technology: + - jackson + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + ObjectMapper $OM = new ObjectMapper(...); + ... + - pattern-inside: | + $OM.enableDefaultTyping(); + ... + - pattern: $OM.readValue($JSON, ...); + - patterns: + - pattern-inside: | + class $CLASS { + ... + @JsonTypeInfo(use = Id.CLASS,...) + $TYPE $VAR; + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: (Object|Serializable|Comparable) + - pattern: $OM.readValue($JSON, $CLASS.class); + - patterns: + - pattern-inside: | + class $CLASS { + ... + ObjectMapper $OM; + ... + $INITMETHODTYPE $INITMETHOD(...) { + ... + $OM = new ObjectMapper(); + ... + $OM.enableDefaultTyping(); + ... + } + ... + } + - pattern-inside: "$METHODTYPE $METHOD(...) {\n ... \n}\n" + - pattern: $OM.readValue($JSON, ...); + severity: WARNING + - id: java.lang.security.servletresponse-writer-xss.servletresponse-writer-xss + languages: + - java + message: 'Cross-site scripting detected in HttpServletResponse writer with variable ''$VAR''. User input was detected going directly from the HttpServletRequest into output. Ensure your data is properly encoded using org.owasp.encoder.Encode.forHtml: ''Encode.forHtml($VAR)''.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#XSS_SERVLET + subcategory: + - vuln + technology: + - java + patterns: + - pattern-inside: $TYPE $FUNC(..., HttpServletResponse $RESP, ...) { ... } + - pattern-inside: $VAR = $REQ.getParameter(...); ... + - pattern-either: + - pattern: $RESP.getWriter(...).write(..., $VAR, ...); + - pattern: | + $WRITER = $RESP.getWriter(...); + ... + $WRITER.write(..., $VAR, ...); + severity: ERROR + - id: java.lang.security.use-snakeyaml-constructor.use-snakeyaml-constructor + languages: + - java + message: Used SnakeYAML org.yaml.snakeyaml.Yaml() constructor with no arguments, which is vulnerable to deserialization attacks. Use the one-argument Yaml(...) constructor instead, with SafeConstructor or a custom Constructor as the argument. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://securitylab.github.com/research/swagger-yaml-parser-vulnerability/#snakeyaml-deserialization-vulnerability + subcategory: + - audit + technology: + - snakeyaml + patterns: + - pattern: | + $Y = new org.yaml.snakeyaml.Yaml(); + ... + $Y.load(...); + severity: WARNING + - id: java.lang.security.xmlinputfactory-external-entities-enabled.xmlinputfactory-external-entities-enabled + languages: + - java + message: XML external entities are enabled for this XMLInputFactory. This is vulnerable to XML external entity attacks. Disable external entities by setting "javax.xml.stream.isSupportingExternalEntities" to false. + metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf + subcategory: + - audit + technology: + - java + patterns: + - pattern-either: + - pattern: (javax.xml.stream.XMLInputFactory $XMLFACTORY).setProperty("javax.xml.stream.isSupportingExternalEntities", true); + - pattern: (javax.xml.stream.XMLInputFactory $XMLFACTORY).setProperty(javax.xml.stream.XMLInputFactory.SUPPORT_DTD, true); + - pattern: (javax.xml.stream.XMLInputFactory $XMLFACTORY).setProperty("javax.xml.stream.isSupportingExternalEntities", Boolean.TRUE); + - pattern: (javax.xml.stream.XMLInputFactory $XMLFACTORY).setProperty(javax.xml.stream.XMLInputFactory.SUPPORT_DTD, Boolean.TRUE); + severity: ERROR + - id: java.lang.security.xmlinputfactory-possible-xxe.xmlinputfactory-possible-xxe + languages: + - java + message: XML external entities are not explicitly disabled for this XMLInputFactory. This could be vulnerable to XML external entity vulnerabilities. Explicitly disable external entities by setting "javax.xml.stream.isSupportingExternalEntities" to false. + metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#xmlinputfactory-a-stax-parser + subcategory: + - vuln + technology: + - java + patterns: + - pattern-not-inside: | + $METHOD(...) { + ... + $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", false); + ... + } + - pattern-not-inside: | + $METHOD(...) { + ... + $XMLFACTORY.setProperty(javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); + ... + } + - pattern-not-inside: | + $METHOD(...) { + ... + $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", Boolean.FALSE); + ... + } + - pattern-not-inside: | + $METHOD(...) { + ... + $XMLFACTORY.setProperty(javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); + ... + } + - pattern-either: + - pattern: javax.xml.stream.XMLInputFactory.newFactory(...) + - pattern: new XMLInputFactory(...) + severity: WARNING + - id: java.mongodb.security.injection.audit.mongodb-nosqli.mongodb-nosqli + languages: + - java + message: Detected non-constant data passed into a NoSQL query using the 'where' evaluation operator. If this data can be controlled by an external user, this is a NoSQL injection. Ensure data passed to the NoSQL query is not user controllable, or properly sanitize the data. Ideally, avoid using the 'where' operator at all and instead use the helper methods provided by com.mongodb.client.model.Filters with comparative operators such as eq, ne, lt, gt, etc. + metadata: + asvs: + control_id: 5.3.4 Injection Prevention + control_url: https://github.com/OWASP/ASVS/blob/master/5.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "5" + category: security + confidence: LOW + cwe: + - 'CWE-943: Improper Neutralization of Special Elements in Data Query Logic' + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + - https://www.mongodb.com/docs/manual/tutorial/query-documents/ + - https://www.mongodb.com/docs/manual/reference/operator/query/where/ + subcategory: + - audit + technology: + - nosql + - mongodb + patterns: + - pattern-either: + - pattern: (com.mongodb.BasicDBObject $QUERY).put("$where", $INPUT); + - pattern: | + (HashMap $MAP).put("$where", $INPUT); + ... + (com.mongodb.BasicDBObject $QUERY).putAll($MAP); + - pattern: (com.mongodb.BasicDBObject $QUERY).append("$where", $INPUT); + - pattern: new com.mongodb.BasicDBObject("$where", $INPUT); + - pattern: | + (HashMap $MAP).put("$where", $INPUT); + ... + new com.mongodb.BasicDBObject($MAP); + - pattern: | + (HashMap $MAP).put("$where", $INPUT); + ... + String json = new JSONObject($MAP).toString(); + ... + (com.mongodb.BasicDBObject $QUERY).parse((String $JSON)); + - pattern: com.mongodb.BasicDBObjectBuilder.start().add("$where", $INPUT); + - pattern: com.mongodb.BasicDBObjectBuilder.start().append("$where", $INPUT); + - pattern: com.mongodb.BasicDBObjectBuilder.start("$where", $INPUT); + - pattern: | + (HashMap $MAP).put("$where", $INPUT); + ... + com.mongodb.BasicDBObjectBuilder.start($MAP); + - metavariable-pattern: + metavariable: $INPUT + patterns: + - pattern: | + ... + - pattern-not: | + "..." + severity: WARNING + - id: java.rmi.security.server-dangerous-class-deserialization.server-dangerous-class-deserialization + languages: + - java + message: Using a non-primitive class with Java RMI may be an insecure deserialization vulnerability. Depending on the underlying implementation. This object could be manipulated by a malicious actor allowing them to execute code on your system. Instead, use an integer ID to look up your object, or consider alternative serialization schemes such as JSON. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://mogwailabs.de/blog/2019/03/attacking-java-rmi-services-after-jep-290/ + subcategory: + - audit + technology: + - rmi + patterns: + - pattern: | + interface $INTERFACE extends Remote { + $RETURNTYPE $METHOD($CLASS $PARAM) throws RemoteException; + } + - metavariable-regex: + metavariable: $CLASS + regex: (?!int|boolean|short|long|byte|char|float|double) + severity: WARNING + - id: java.rmi.security.server-dangerous-object-deserialization.server-dangerous-object-deserialization + languages: + - java + message: Using an arbitrary object ('$PARAMTYPE $PARAM') with Java RMI is an insecure deserialization vulnerability. This object can be manipulated by a malicious actor allowing them to execute code on your system. Instead, use an integer ID to look up your object, or consider alternative serialization schemes such as JSON. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://frohoff.github.io/appseccali-marshalling-pickles/ + - https://book.hacktricks.xyz/network-services-pentesting/1099-pentesting-java-rmi + - https://youtu.be/t_aw1mDNhzI + - https://github.com/qtc-de/remote-method-guesser + - https://github.com/openjdk/jdk/blob/master/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java#L303C4-L331 + subcategory: + - audit + technology: + - rmi + patterns: + - pattern: | + interface $INTERFACE extends Remote { + $RETURNTYPE $METHOD($PARAMTYPE $PARAM) throws RemoteException; + } + - metavariable-pattern: + language: generic + metavariable: $PARAMTYPE + patterns: + - pattern-not: String + - pattern-not: java.lang.String + - pattern-not: boolean + - pattern-not: Boolean + - pattern-not: java.lang.Boolean + - pattern-not: byte + - pattern-not: Byte + - pattern-not: java.lang.Byte + - pattern-not: char + - pattern-not: Character + - pattern-not: java.lang.Character + - pattern-not: double + - pattern-not: Double + - pattern-not: java.lang.Double + - pattern-not: float + - pattern-not: Float + - pattern-not: java.lang.Float + - pattern-not: int + - pattern-not: Integer + - pattern-not: java.lang.Integer + - pattern-not: long + - pattern-not: Long + - pattern-not: java.lang.Long + - pattern-not: short + - pattern-not: Short + - pattern-not: java.lang.Short + severity: ERROR + - fix: | + $COOKIE = new Cookie($...ARGS); + $COOKIE.setSecure(true); + id: java.servlets.security.cookie-issecure-false.cookie-issecure-false + languages: + - java + message: 'Default session middleware settings: `setSecure` not set to true. This ensures that the cookie is sent only over HTTPS to prevent cross-site scripting attacks.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.oracle.com/javaee/6/api/javax/servlet/http/Cookie.html#setSecure(boolean) + - https://owasp.org/www-community/controls/SecureCookieAttribute + subcategory: + - audit + technology: + - java + - cookie + vulnerability: Insecure Transport + patterns: + - pattern: $COOKIE = new Cookie($...ARGS); + - pattern-not-inside: | + $COOKIE = new Cookie(...); + ... + $COOKIE.setSecure(...); + severity: WARNING + - fix-regex: + regex: setSecure\(false\) + replacement: setSecure(true) + id: java.servlets.security.cookie-setsecure.cookie-setsecure + languages: + - java + message: 'Default session middleware settings: `setSecure` not set to true. This ensures that the cookie is sent only over HTTPS to prevent cross-site scripting attacks.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.oracle.com/javaee/6/api/javax/servlet/http/Cookie.html#setSecure(boolean) + - https://owasp.org/www-community/controls/SecureCookieAttribute + subcategory: + - audit + technology: + - java + - cookie + vulnerability: Insecure Transport + patterns: + - patterns: + - pattern-inside: | + $COOKIE = new Cookie(...); + ... + - pattern: | + $COOKIE.setSecure(false); + - pattern-not-inside: | + $COOKIE = new Cookie(...); + ... + $COOKIE.setSecure(true); + severity: WARNING + - id: java.spring.security.audit.spel-injection.spel-injection + languages: + - java + message: A Spring expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SPEL_INJECTION + subcategory: + - audit + technology: + - spring + patterns: + - pattern-either: + - pattern-inside: | + class $CLASS { + ... + ExpressionParser $PARSER; + ... + } + - pattern-inside: | + class $CLASS { + ... + ExpressionParser $PARSER = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + ExpressionParser $PARSER = ...; + ... + } + - pattern-inside: | + class $CLASS { + ... + SpelExpressionParser $PARSER; + ... + } + - pattern-inside: | + class $CLASS { + ... + SpelExpressionParser $PARSER = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + SpelExpressionParser $PARSER = ...; + ... + } + - pattern-inside: | + class $CLASS { + ... + TemplateAwareExpressionParser $PARSER; + ... + } + - pattern-inside: | + class $CLASS { + ... + TemplateAwareExpressionParser $PARSER = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + TemplateAwareExpressionParser $PARSER = ...; + ... + } + - pattern: | + $X $METHOD(...) { + ... + $PARSER.parseExpression(...); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + $PARSER.parseExpression("..."); + ... + } + - pattern-not: | + $X $METHOD(...) { + ... + String $S = "..."; + ... + $PARSER.parseExpression($S); + ... + } + severity: WARNING + - id: java.spring.security.audit.spring-actuator-fully-enabled-yaml.spring-actuator-fully-enabled-yaml + languages: + - yaml + message: Spring Boot Actuator is fully enabled. This exposes sensitive endpoints such as /actuator/env, /actuator/logfile, /actuator/heapdump and others. Unless you have Spring Security enabled or another means to protect these endpoints, this functionality is available without authentication, causing a severe security risk. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints + - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 + - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators + subcategory: + - vuln + technology: + - spring + patterns: + - pattern-inside: | + management: + ... + endpoints: + ... + web: + ... + exposure: + ... + - pattern: | + include: "*" + severity: WARNING + - id: java.spring.security.audit.spring-actuator-fully-enabled.spring-actuator-fully-enabled + languages: + - generic + message: Spring Boot Actuator is fully enabled. This exposes sensitive endpoints such as /actuator/env, /actuator/logfile, /actuator/heapdump and others. Unless you have Spring Security enabled or another means to protect these endpoints, this functionality is available without authentication, causing a significant security risk. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints + - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 + - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators + subcategory: + - vuln + technology: + - spring + paths: + include: + - '*properties' + pattern: management.endpoints.web.exposure.include=* + severity: ERROR + - id: java.spring.security.audit.spring-actuator-non-health-enabled-yaml.spring-actuator-dangerous-endpoints-enabled-yaml + languages: + - yaml + message: Spring Boot Actuator "$ACTUATOR" is enabled. Depending on the actuator, this can pose a significant security risk. Please double-check if the actuator is needed and properly secured. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints + - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 + - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators + subcategory: + - vuln + technology: + - spring + patterns: + - pattern-inside: | + management: + ... + endpoints: + ... + web: + ... + exposure: + ... + include: + ... + - pattern: | + include: [..., $ACTUATOR, ...] + - metavariable-comparison: + comparison: not str($ACTUATOR) in ["health","*"] + metavariable: $ACTUATOR + severity: WARNING + - id: java.spring.security.audit.spring-actuator-non-health-enabled.spring-actuator-dangerous-endpoints-enabled + languages: + - generic + message: Spring Boot Actuators "$...ACTUATORS" are enabled. Depending on the actuators, this can pose a significant security risk. Please double-check if the actuators are needed and properly secured. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints + - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 + - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators + subcategory: + - vuln + technology: + - spring + options: + generic_ellipsis_max_span: 0 + patterns: + - pattern: management.endpoints.web.exposure.include=$...ACTUATORS + - metavariable-comparison: + comparison: not str($...ACTUATORS) in ["health","*"] + metavariable: $...ACTUATORS + severity: WARNING + - id: java.spring.security.audit.spring-csrf-disabled.spring-csrf-disabled + languages: + - java + message: CSRF protection is disabled for this configuration. This is a security risk. + metadata: + asvs: + control_id: 4.2.2 CSRF + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V4-Access-Control.md#v42-operation-level-access-control + section: V4 Access Control + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_PROTECTION_DISABLED + subcategory: + - audit + technology: + - spring + pattern: $OBJ.csrf(...).disable(...) + severity: WARNING + - id: java.spring.security.audit.spring-jsp-eval.spring-jsp-eval + languages: + - generic + message: A Spring expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#JSP_SPRING_EVAL + subcategory: + - audit + technology: + - spring + paths: + include: + - '*.jsp' + pattern: | + + severity: WARNING + - id: java.spring.security.audit.spring-sqli.spring-sqli + languages: + - java + message: Detected a string argument from a public method contract in a raw SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - spring + mode: taint + options: + taint_assume_safe_booleans: true + taint_assume_safe_numbers: true + pattern-sanitizers: + - not_conflicting: true + pattern-either: + - patterns: + - focus-metavariable: $A + - pattern-inside: | + new $TYPE(...,$A,...); + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - focus-metavariable: $A + - pattern: | + new PreparedStatementCreatorFactory($A,...); + - patterns: + - focus-metavariable: $A + - pattern: | + (JdbcTemplate $T).$M($A,...) + - patterns: + - pattern: (String $A) + - pattern-inside: | + (JdbcTemplate $T).batchUpdate(...) + - patterns: + - focus-metavariable: $A + - pattern: | + NamedParameterBatchUpdateUtils.$M($A,...) + - patterns: + - focus-metavariable: $A + - pattern: | + BatchUpdateUtils.$M($A,...) + pattern-sources: + - patterns: + - pattern: $ARG + - pattern-inside: | + public $T $M (..., String $ARG,...){...} + severity: WARNING + - id: java.spring.security.audit.spring-unvalidated-redirect.spring-unvalidated-redirect + languages: + - java + message: Application redirects a user to a destination URL specified by a user supplied parameter that is not validated. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNVALIDATED_REDIRECT + subcategory: + - vuln + technology: + - spring + pattern-either: + - pattern: | + $X $METHOD(...,String $URL,...) { + return "redirect:" + $URL; + } + - pattern: | + $X $METHOD(...,String $URL,...) { + ... + String $REDIR = "redirect:" + $URL; + ... + return $REDIR; + ... + } + - pattern: | + $X $METHOD(...,String $URL,...) { + ... + new ModelAndView("redirect:" + $URL); + ... + } + - pattern: |- + $X $METHOD(...,String $URL,...) { + ... + String $REDIR = "redirect:" + $URL; + ... + new ModelAndView($REDIR); + ... + } + severity: WARNING + - id: java.spring.security.injection.tainted-file-path.tainted-file-path + languages: + - java + message: Detected user input controlling a file path. An attacker could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-23: Relative Path Traversal' + impact: HIGH + interfile: true + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + subcategory: + - vuln + technology: + - java + - spring + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: new File(...) + - pattern: new java.io.File(...) + - pattern: new FileReader(...) + - pattern: new java.io.FileReader(...) + - pattern: new FileInputStream(...) + - pattern: new java.io.FileInputStream(...) + - pattern: (Paths $PATHS).get(...) + - patterns: + - pattern: | + $CLASS.$FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: ^(getResourceAsStream|getResource)$ + - patterns: + - pattern-either: + - pattern: new ClassPathResource($FILE, ...) + - pattern: ResourceUtils.getFile($FILE, ...) + - pattern: new FileOutputStream($FILE, ...) + - pattern: new java.io.FileOutputStream($FILE, ...) + - pattern: new StreamSource($FILE, ...) + - pattern: new javax.xml.transform.StreamSource($FILE, ...) + - pattern: FileUtils.openOutputStream($FILE, ...) + - focus-metavariable: $FILE + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + severity: ERROR + - id: java.spring.security.injection.tainted-html-string.tainted-html-string + languages: + - java + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. You can use the OWASP ESAPI encoder if you must render user data. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - java + - spring + mode: taint + pattern-propagators: + - from: $...TAINTED + pattern: (StringBuilder $SB).append($...TAINTED) + to: $SB + - from: $...TAINTED + pattern: $VAR += $...TAINTED + to: $VAR + pattern-sanitizers: + - pattern-either: + - pattern: Encode.forHtml(...) + - pattern: (PolicyFactory $POLICY).sanitize(...) + - pattern: (AntiSamy $AS).scan(...) + - pattern: JSoup.clean(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: new ResponseEntity<>($PAYLOAD, ...) + - pattern: new ResponseEntity<$ERROR>($PAYLOAD, ...) + - pattern: ResponseEntity. ... .body($PAYLOAD) + - patterns: + - pattern: | + ResponseEntity.$RESPFUNC($PAYLOAD). ... + - metavariable-regex: + metavariable: $RESPFUNC + regex: ^(ok|of)$ + - focus-metavariable: $PAYLOAD + requires: CONCAT + pattern-sources: + - label: INPUT + patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + - by-side-effect: true + label: CONCAT + patterns: + - pattern-either: + - pattern: | + "$HTMLSTR" + ... + - pattern: | + "$HTMLSTR".concat(...) + - patterns: + - pattern-inside: | + StringBuilder $SB = new StringBuilder("$HTMLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$HTMLSTR"; + ... + - pattern: $VAR += ... + - pattern: String.format("$HTMLSTR", ...) + - patterns: + - pattern-inside: | + String $VAR = "$HTMLSTR"; + ... + - pattern: String.format($VAR, ...) + - metavariable-regex: + metavariable: $HTMLSTR + regex: ^<\w+ + requires: INPUT + severity: ERROR + - id: java.spring.security.injection.tainted-sql-string.tainted-sql-string + languages: + - java + message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html + subcategory: + - vuln + technology: + - spring + mode: taint + options: + interfile: true + taint_assume_safe_booleans: true + taint_assume_safe_numbers: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR".concat(...) + - patterns: + - pattern-inside: | + StringBuilder $SB = new StringBuilder("$SQLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$SQLSTR"; + ... + - pattern: $VAR += ... + - pattern: String.format("$SQLSTR", ...) + - patterns: + - pattern-inside: | + String $VAR = "$SQLSTR"; + ... + - pattern: String.format($VAR, ...) + - pattern-not-inside: System.out.println(...) + - pattern-not-inside: $LOG.info(...) + - pattern-not-inside: $LOG.warn(...) + - pattern-not-inside: $LOG.warning(...) + - pattern-not-inside: $LOG.debug(...) + - pattern-not-inside: $LOG.debugging(...) + - pattern-not-inside: $LOG.error(...) + - pattern-not-inside: new Exception(...) + - pattern-not-inside: throw ...; + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue) + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - focus-metavariable: $SOURCE + severity: ERROR + - id: java.spring.security.injection.tainted-system-command.tainted-system-command + languages: + - java + message: 'Detected user input entering a method which executes a system command. This could result in a command injection vulnerability, which allows an attacker to inject an arbitrary system command onto the server. The attacker could download malware onto or steal data from the server. Instead, use ProcessBuilder, separating the command into individual arguments, like this: `new ProcessBuilder("ls", "-al", targetDirectory)`. Further, make sure you hardcode or allowlist the actual command so that attackers can''t run arbitrary commands.' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://www.stackhawk.com/blog/command-injection-java/ + - https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html + - https://github.com/github/codeql/blob/main/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.java + subcategory: + - vuln + technology: + - java + - spring + mode: taint + pattern-propagators: + - from: $INPUT + label: CONCAT + pattern: (StringBuilder $STRB).append($INPUT) + requires: INPUT + to: $STRB + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (Process $P) = new Process(...); + - pattern: | + (ProcessBuilder $PB).command(...); + - patterns: + - pattern-either: + - pattern: | + (Runtime $R).$EXEC(...); + - pattern: | + Runtime.getRuntime(...).$EXEC(...); + - metavariable-regex: + metavariable: $EXEC + regex: (exec|loadLibrary|load) + - patterns: + - pattern: | + (ProcessBuilder $PB).command(...).$ADD(...); + - metavariable-regex: + metavariable: $ADD + regex: (add|addAll) + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $BUILDER = new ProcessBuilder(...); + ... + - pattern: $BUILDER.start(...) + - pattern: | + new ProcessBuilder(...). ... .start(...); + requires: CONCAT + pattern-sources: + - label: INPUT + patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + - label: CONCAT + patterns: + - pattern-either: + - pattern: $X + $SOURCE + - pattern: $SOURCE + $Y + - pattern: String.format("...", ..., $SOURCE, ...) + - pattern: String.join("...", ..., $SOURCE, ...) + - pattern: (String $STR).concat($SOURCE) + - pattern: $SOURCE.concat(...) + - pattern: $X += $SOURCE + - pattern: $SOURCE += $X + requires: INPUT + severity: ERROR + - id: java.spring.security.injection.tainted-url-host.tainted-url-host + languages: + - java + message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, hardcode the correct host, or ensure that the user data can only affect the path or parameters. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - java + - spring + mode: taint + options: + interfile: true + pattern-sinks: + - pattern-either: + - pattern: new URL($ONEARG) + - patterns: + - pattern-either: + - pattern: | + "$URLSTR" + ... + - pattern: | + "$URLSTR".concat(...) + - patterns: + - pattern-inside: | + StringBuilder $SB = new StringBuilder("$URLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$URLSTR"; + ... + - pattern: $VAR += ... + - patterns: + - pattern: String.format("$URLSTR", ...) + - pattern-not: String.format("$URLSTR", "...", ...) + - patterns: + - pattern-inside: | + String $VAR = "$URLSTR"; + ... + - pattern: String.format($VAR, ...) + - metavariable-regex: + metavariable: $URLSTR + regex: http(s?)://%(v|s|q).* + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + severity: ERROR + - id: java.spring.security.unrestricted-request-mapping.unrestricted-request-mapping + languages: + - java + message: Detected a method annotated with 'RequestMapping' that does not specify the HTTP method. CSRF protections are not enabled for GET, HEAD, TRACE, or OPTIONS, and by default all HTTP methods are allowed when the HTTP method is not explicitly specified. This means that a method that performs state changes could be vulnerable to CSRF attacks. To mitigate, add the 'method' field and specify the HTTP method (such as 'RequestMethod.POST'). + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING + subcategory: + - audit + technology: + - spring + patterns: + - pattern-inside: | + @RequestMapping(...) + $RETURNTYPE $METHOD(...) { ... } + - pattern-not-inside: | + @RequestMapping(..., method = $X, ...) + $RETURNTYPE $METHOD(...) { ... } + - pattern: | + RequestMapping + severity: WARNING + - id: javascript.ajv.security.audit.ajv-allerrors-true.ajv-allerrors-true + languages: + - javascript + - typescript + message: 'By setting `allErrors: true` in `Ajv` library, all error objects will be allocated without limit. This allows the attacker to produce a huge number of errors which can lead to denial of service. Do not use `allErrors: true` in production.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-400: Uncontrolled Resource Consumption' + cwe2022-top25: true + impact: LOW + likelihood: LOW + references: + - https://ajv.js.org/options.html#allerrors + subcategory: + - audit + technology: + - ajv + pattern-either: + - pattern: | + new Ajv({...,allErrors: true,...},...) + - patterns: + - pattern: | + new Ajv($SETTINGS,...) + - pattern-inside: | + $SETTINGS = {...,allErrors: true,...} + ... + severity: WARNING + - id: javascript.angular.security.detect-angular-element-methods.detect-angular-element-methods + languages: + - javascript + - typescript + message: Use of angular.element can lead to XSS if user-input is treated as part of the HTML element within `$SINK`. It is recommended to contextually output encode user-input, before inserting into `$SINK`. If the HTML needs to be preserved it is recommended to sanitize the input using $sce.getTrustedHTML or $sanitize. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/function/angular.element + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - vuln + technology: + - angularjs + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: $sce.getTrustedHtml(...) + - pattern: $sanitize(...) + - pattern: DOMPurify.sanitize(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + angular.element(...). ... .$SINK($QUERY) + - pattern-inside: | + $ANGULAR = angular.element(...) + ... + $ANGULAR. ... .$SINK($QUERY) + - metavariable-regex: + metavariable: $SINK + regex: ^(after|append|html|prepend|replaceWith|wrap)$ + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + function(..., $SCOPE, ...) { ... } + - focus-metavariable: $SCOPE + - metavariable-regex: + metavariable: $SCOPE + regex: ^\$scope$ + - pattern: $rootScope + - pattern: $injector.get('$rootScope') + - pattern: $injector.get('$scope') + severity: INFO + - id: javascript.angular.security.detect-angular-element-taint.detect-angular-element-taint + languages: + - javascript + - typescript + message: Use of angular.element can lead to XSS if user-input is treated as part of the HTML element within `$SINK`. It is recommended to contextually output encode user-input, before inserting into `$SINK`. If the HTML needs to be preserved it is recommended to sanitize the input using $sce.getTrustedHTML or $sanitize. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/function/angular.element + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - vuln + technology: + - angularjs + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: $sce.getTrustedHtml(...) + - pattern: $sanitize(...) + - pattern: DOMPurify.sanitize(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + angular.element(...). ... .$SINK($QUERY) + - pattern-inside: | + $ANGULAR = angular.element(...) + ... + $ANGULAR. ... .$SINK($QUERY) + - metavariable-regex: + metavariable: $SINK + regex: ^(after|append|html|prepend|replaceWith|wrap)$ + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-either: + - pattern: window.location.search + - pattern: window.document.location.search + - pattern: document.location.search + - pattern: location.search + - pattern: $location.search(...) + - patterns: + - pattern-either: + - pattern: $DECODE(<... location.hash ...>) + - pattern: $DECODE(<... window.location.hash ...>) + - pattern: $DECODE(<... document.location.hash ...>) + - pattern: $DECODE(<... location.href ...>) + - pattern: $DECODE(<... window.location.href ...>) + - pattern: $DECODE(<... document.location.href ...>) + - pattern: $DECODE(<... document.URL ...>) + - pattern: $DECODE(<... window.document.URL ...>) + - pattern: $DECODE(<... document.location.href ...>) + - pattern: $DECODE(<... document.location.href ...>) + - pattern: $DECODE(<... $location.absUrl() ...>) + - pattern: $DECODE(<... $location.url() ...>) + - pattern: $DECODE(<... $location.hash() ...>) + - metavariable-regex: + metavariable: $DECODE + regex: ^(unescape|decodeURI|decodeURIComponent)$ + - patterns: + - pattern-inside: $http.$METHOD(...).$CONTINUE(function $FUNC($RES) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|delete|head|jsonp|post|put|patch) + - pattern: $RES.data + severity: WARNING + - id: javascript.angular.security.detect-angular-open-redirect.detect-angular-open-redirect + languages: + - javascript + - typescript + message: Use of $window.location.href can lead to open-redirect if user input is used for redirection. + metadata: + asvs: + control_id: 5.5.1 Insecue Redirect + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/service/$sce#trustAsJs + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - audit + technology: + - angular + patterns: + - pattern: | + $window.location.href = ... + - pattern-not: | + $window.location.href = "..." + severity: ERROR + - id: javascript.angular.security.detect-angular-resource-loading.detect-angular-resource-loading + languages: + - javascript + - typescript + message: $sceDelegateProvider allowlisting can introduce security issues if wildcards are used. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/service/$sce#trustAsJs + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - audit + technology: + - angular + pattern-either: + - pattern: | + $sceDelegateProvider.resourceUrlWhitelist([...,'**',...]); + - patterns: + - pattern: | + $sceDelegateProvider.resourceUrlWhitelist([...,$DOM,...]); + - metavariable-regex: + metavariable: $DOM + regex: ^'.*\*\*.+'$ + severity: WARNING + - id: javascript.angular.security.detect-angular-sce-disabled.detect-angular-sce-disabled + languages: + - javascript + - typescript + message: $sceProvider is set to false. Disabling Strict Contextual escaping (SCE) in an AngularJS application could provide additional attack surface for XSS vulnerabilities. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/service/$sce + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - vuln + technology: + - angular + pattern: | + $sceProvider.enabled(false); + severity: ERROR + - id: javascript.angular.security.detect-angular-trust-as-css.detect-angular-trust-as-css-method + languages: + - javascript + - typescript + message: The use of $sce.trustAsCss can be dangerous if unsanitized user input flows through this API. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/service/$sce#trustAsCss + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - audit + technology: + - angular + patterns: + - pattern-either: + - pattern: | + $SOURCE = $scope.$INPUT; + $sce.trustAsCss($SOURCE); + - pattern: | + $sce.trustAsCss($scope.$INPUT); + - pattern-inside: | + app.controller(..., function($scope,$sce){ + ... + }); + severity: WARNING + - id: javascript.angular.security.detect-angular-trust-as-html-method.detect-angular-trust-as-html-method + languages: + - javascript + - typescript + message: The use of $sce.trustAsHtml can be dangerous if unsanitized user input flows through this API. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/service/$sce#trustAsHtml + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - audit + technology: + - angular + patterns: + - pattern-either: + - pattern: | + $SOURCE = $scope.$INPUT; + $sce.trustAsHtml($SOURCE); + - pattern: | + $sce.trustAsHtml($scope.$INPUT); + - pattern-inside: | + app.controller(..., function($scope,$sce){ + ... + }); + severity: WARNING + - id: javascript.angular.security.detect-angular-trust-as-js-method.detect-angular-trust-as-js-method + languages: + - javascript + - typescript + message: The use of $sce.trustAsJs can be dangerous if unsanitized user input flows through this API. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/service/$sce#trustAsJs + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - audit + technology: + - angular + patterns: + - pattern-either: + - pattern: | + $SOURCE = $scope.$INPUT; + $sce.trustAsJs($SOURCE); + - pattern: | + $sce.trustAsJs($scope.$INPUT); + - pattern-inside: | + app.controller(..., function($scope,$sce){ + ... + }); + severity: WARNING + - id: javascript.angular.security.detect-angular-trust-as-method.detect-angular-trust-as-method + languages: + - javascript + - typescript + message: The use of $sce.trustAs can be dangerous if unsanitized user input flows through this API. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/service/$sce + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - vuln + technology: + - angular + mode: taint + pattern-sinks: + - pattern: $sce.trustAs(...) + - pattern: $sce.trustAsHtml(...) + pattern-sources: + - patterns: + - pattern-inside: | + app.controller(..., function($scope,$sce) { + ... + }); + - pattern: $scope.$X + severity: WARNING + - id: javascript.angular.security.detect-angular-trust-as-resourceurl-method.detect-angular-trust-as-resourceurl-method + languages: + - javascript + - typescript + message: The use of $sce.trustAsResourceUrl can be dangerous if unsanitized user input flows through this API. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/service/$sce#trustAsResourceUrl + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - audit + technology: + - angular + patterns: + - pattern-either: + - pattern: | + $SOURCE = $scope.$INPUT; + $sce.trustAsResourceUrl($SOURCE); + - pattern: | + $sce.trustAsResourceUrl($scope.$INPUT); + - pattern-inside: | + app.controller(..., function($scope,$sce){ + ... + }); + severity: WARNING + - id: javascript.angular.security.detect-angular-trust-as-url-method.detect-angular-trust-as-url-method + languages: + - javascript + - typescript + message: The use of $sce.trustAsUrl can be dangerous if unsanitized user input flows through this API. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/service/$sce#trustAsUrl + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - audit + technology: + - angular + patterns: + - pattern-either: + - pattern: | + $SOURCE = $scope.$INPUT; + $sce.trustAsUrl($SOURCE); + - pattern: | + $sce.trustAsUrl($scope.$INPUT); + - pattern-inside: | + app.controller(..., function($scope,$sce){ + ... + }); + severity: WARNING + - id: javascript.angular.security.detect-third-party-angular-translate.detect-angular-translateprovider-translations-method + languages: + - javascript + message: The use of $translateProvider.translations method can be dangerous if user input is provided to this API. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.angularjs.org/api/ng/service/$sce#trustAsUrl + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf + subcategory: + - audit + technology: + - angular + - typescript + patterns: + - pattern: | + $translateProvider.translations(...,$SOURCE); + - pattern-inside: | + app.controller(..., function($scope,$sce){ + ... + }); + severity: WARNING + - id: javascript.apollo.security.apollo-axios-ssrf.apollo-axios-ssrf + languages: + - javascript + message: User-controllable argument $DATAVAL to $METHOD passed to Axios via internal handler $INNERFUNC. This could be a server-side request forgery. A user could call a restricted API or leak internal headers to an unauthorized party. Validate your user arguments against an allowlist of known URLs, or consider refactoring so that user-controlled data is not necessary. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://www.cvedetails.com/cve/CVE-2020-28168/ + - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery + subcategory: + - audit + technology: + - apollo + - axios + patterns: + - pattern: const $RESPONSE = await axios.request($INNERARG,...) + - pattern-inside: | + Query: { + $METHOD(parent, args, context, info) { + ... + $DATA = args.$DATAVAL + ... + async function $INNERFUNC(...,$INNERARG,...){ + ... + } + ... + return $INNERFUNC(...,$DATA,...) + } + } + severity: WARNING + - id: javascript.argon2.security.unsafe-argon2-config.unsafe-argon2-config + languages: + - javascript + - typescript + message: Prefer Argon2id where possible. Per RFC9016, section 4 IETF recommends selecting Argon2id unless you can guarantee an adversary has no direct access to the computing environment. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-916: Use of Password Hash With Insufficient Computational Effort' + impact: LOW + likelihood: HIGH + owasp: + - A02:2021 - Cryptographic Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + - https://eprint.iacr.org/2016/759.pdf + - https://www.cs.tau.ac.il/~tromer/papers/cache-joc-20090619.pdf + - https://datatracker.ietf.org/doc/html/rfc9106#section-4 + subcategory: + - vuln + technology: + - argon2 + - cryptography + mode: taint + pattern-sanitizers: + - patterns: + - pattern: | + {type: $ARGON.argon2id} + ... + pattern-sinks: + - patterns: + - pattern: | + $Y + - pattern-inside: | + $ARGON.hash(...,$Y) + pattern-sources: + - patterns: + - pattern-inside: | + $ARGON = require('argon2'); + ... + - pattern: | + {type: ...} + severity: WARNING + - id: javascript.audit.detect-replaceall-sanitization.detect-replaceall-sanitization + languages: + - javascript + - typescript + message: Detected a call to `$FUNC()` in an attempt to HTML escape the string `$STR`. Manually sanitizing input through a manually built list can be circumvented in many situations, and it's better to use a well known sanitization library such as `sanitize-html` or `DOMPurify`. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://www.npmjs.com/package/dompurify + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - javascript + - typescript + patterns: + - pattern-either: + - pattern: $STR.$FUNC('<', '<') + - pattern: $STR.$FUNC('>', '>') + - pattern: $STR.$FUNC('"', '"') + - pattern: $STR.$FUNC("'", ''') + - pattern: $STR.$FUNC('&', '&') + - metavariable-regex: + metavariable: $FUNC + regex: (replace|replaceAll) + severity: INFO + - id: javascript.aws-lambda.security.detect-child-process.detect-child-process + languages: + - javascript + - typescript + message: Allowing spawning arbitrary programs or running shell processes with arbitrary arguments may end up in a command injection vulnerability. Try to avoid non-literal values for the command string. If it is not possible, then do not let running arbitrary commands, use a white list for inputs. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - javascript + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $CMD + - pattern-either: + - pattern: exec($CMD,...) + - pattern: execSync($CMD,...) + - pattern: spawn($CMD,...) + - pattern: spawnSync($CMD,...) + - pattern: $CP.exec($CMD,...) + - pattern: $CP.execSync($CMD,...) + - pattern: $CP.spawn($CMD,...) + - pattern: $CP.spawnSync($CMD,...) + - pattern-either: + - pattern-inside: | + require('child_process') + ... + - pattern-inside: | + import 'child_process' + ... + pattern-sources: + - patterns: + - pattern: $EVENT + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + severity: ERROR + - id: javascript.aws-lambda.security.dynamodb-request-object.dynamodb-request-object + languages: + - javascript + - typescript + message: Detected DynamoDB query params that are tainted by `$EVENT` object. This could lead to NoSQL injection if the variable is user-controlled and not properly sanitized. Explicitly assign query params instead of passing data from `$EVENT` directly to DynamoDB client. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-943: Improper Neutralization of Special Elements in Data Query Logic' + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - javascript + - aws-lambda + - dynamodb + mode: taint + pattern-sanitizers: + - patterns: + - pattern: | + {...} + pattern-sinks: + - patterns: + - focus-metavariable: $SINK + - pattern: | + $DC.$METHOD($SINK, ...) + - metavariable-regex: + metavariable: $METHOD + regex: (query|send|scan|delete|put|transactWrite|update|batchExecuteStatement|executeStatement|executeTransaction|transactWriteItems) + - pattern-either: + - pattern-inside: | + $DC = new $AWS.DocumentClient(...); + ... + - pattern-inside: | + $DC = new $AWS.DynamoDB(...); + ... + - pattern-inside: | + $DC = new DynamoDBClient(...); + ... + - pattern-inside: | + $DC = DynamoDBDocumentClient.from(...); + ... + pattern-sources: + - patterns: + - pattern: $EVENT + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + severity: ERROR + - id: javascript.aws-lambda.security.knex-sqli.knex-sqli + languages: + - javascript + - typescript + message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `knex.raw(''SELECT $1 from table'', [userinput])`' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://knexjs.org/#Builder-fromRaw + - https://knexjs.org/#Builder-whereRaw + subcategory: + - vuln + technology: + - aws-lambda + - knex + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern: $KNEX.fromRaw($QUERY, ...) + - pattern: $KNEX.whereRaw($QUERY, ...) + - pattern: $KNEX.raw($QUERY, ...) + - pattern-either: + - pattern-inside: | + require('knex') + ... + - pattern-inside: | + import 'knex' + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.pg-sqli.pg-sqli + languages: + - javascript + - typescript + message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `connection.query(''SELECT $1 from table'', [userinput])`' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://node-postgres.com/features/queries + subcategory: + - vuln + technology: + - aws-lambda + - postgres + - pg + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern: $DB.query($QUERY, ...) + - pattern-either: + - pattern-inside: | + require('pg') + ... + - pattern-inside: | + import 'pg' + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.sequelize-sqli.sequelize-sqli + languages: + - javascript + - typescript + message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `sequelize.query(''SELECT * FROM projects WHERE status = ?'', { replacements: [''active''], type: QueryTypes.SELECT });`' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://sequelize.org/master/manual/raw-queries.html + subcategory: + - vuln + technology: + - aws-lambda + - sequelize + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern: $DB.query($QUERY, ...) + - pattern-either: + - pattern-inside: | + require('sequelize') + ... + - pattern-inside: | + import 'sequelize' + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.tainted-eval.tainted-eval + languages: + - javascript + - typescript + message: The `eval()` function evaluates JavaScript code represented as a string. Executing JavaScript from a string is an enormous security risk. It is far too easy for a bad actor to run arbitrary code when you use `eval()`. Ensure evaluated content is not definable by external sources. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - javascript + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $CODE + - pattern-either: + - pattern: eval($CODE) + - pattern: Function(...,$CODE) + - pattern: new Function(...,$CODE) + pattern-sources: + - patterns: + - pattern: $EVENT + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + severity: WARNING + - id: javascript.aws-lambda.security.tainted-html-response.tainted-html-response + languages: + - javascript + - typescript + message: Detected user input flowing into an HTML response. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $BODY + - pattern-inside: | + {..., headers: {..., 'Content-Type': 'text/html', ...}, body: $BODY, ... } + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.tainted-html-string.tainted-html-string + languages: + - javascript + - typescript + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates which will safely render HTML instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + "$HTMLSTR" + $EXPR + - pattern: | + "$HTMLSTR".concat(...) + - pattern: $UTIL.format($HTMLSTR, ...) + - pattern: format($HTMLSTR, ...) + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... + - patterns: + - pattern: | + `...${...}...` + - pattern-regex: | + .*<\w+.* + - pattern-not-inside: | + console.$LOG(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.tainted-sql-string.tainted-sql-string + languages: + - javascript + - typescript + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/SQL_Injection + subcategory: + - vuln + technology: + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + $EXPR + - pattern: | + "$SQLSTR".concat(...) + - pattern: util.format($SQLSTR, ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - patterns: + - pattern: | + `...${...}...` + - pattern-regex: | + .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - pattern-not-inside: | + console.$LOG(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: ERROR + - id: javascript.aws-lambda.security.vm-runincontext-injection.vm-runincontext-injection + languages: + - javascript + - typescript + message: The `vm` module enables compiling and running code within V8 Virtual Machine contexts. The `vm` module is not a security mechanism. Do not use it to run untrusted code. If code passed to `vm` functions is controlled by user input it could result in command injection. Do not let user input in `vm` functions. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - javascript + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('vm'); + ... + - pattern-inside: | + import 'vm' + ... + - pattern-either: + - pattern: $VM.runInContext($X,...) + - pattern: $VM.runInNewContext($X,...) + - pattern: $VM.runInThisContext($X,...) + - pattern: $VM.compileFunction($X,...) + - pattern: new $VM.Script($X,...) + - pattern: new $VM.SourceTextModule($X,...) + - pattern: runInContext($X,...) + - pattern: runInNewContext($X,...) + - pattern: runInThisContext($X,...) + - pattern: compileFunction($X,...) + - pattern: new Script($X,...) + - pattern: new SourceTextModule($X,...) + pattern-sources: + - patterns: + - pattern: $EVENT + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + severity: ERROR + - id: javascript.bluebird.security.audit.tofastproperties-code-execution.tofastproperties-code-execution + languages: + - javascript + - typescript + message: Potential arbitrary code execution, whatever is provided to `toFastProperties` is sent straight to eval() + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - http://bluebirdjs.com/docs/getting-started.html + subcategory: + - vuln + technology: + - bluebird + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $UTIL.toFastProperties($SINK,...) + - pattern: toFastProperties($SINK,...) + - pattern-either: + - pattern-inside: | + $BB = require('bluebird'); + ... + - pattern-inside: | + import 'bluebird'; + ... + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-inside: function ... (..., $ARG,...) {...} + - focus-metavariable: $ARG + severity: WARNING + - id: javascript.browser.security.dom-based-xss.dom-based-xss + languages: + - javascript + - typescript + message: 'Detected possible DOM-based XSS. This occurs because a portion of the URL is being used to construct an element added directly to the page. For example, a malicious actor could send someone a link like this: http://www.some.site/page.html?default= which would add the script to the page. Consider allowlisting appropriate values or using an approach which does not involve the URL.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/DOM_Based_XSS + subcategory: + - audit + technology: + - browser + pattern-either: + - pattern: document.write(<... document.location.$W ...>) + - pattern: document.write(<... location.$W ...>) + severity: ERROR + - id: javascript.browser.security.eval-detected.eval-detected + languages: + - javascript + - typescript + message: Detected the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources. + metadata: + asvs: + control_id: 5.2.4 Dynamic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - browser + patterns: + - pattern-not: eval("...") + - pattern: eval(...) + severity: WARNING + - id: javascript.browser.security.insecure-document-method.insecure-document-method + languages: + - javascript + - typescript + message: User controlled data in methods like `innerHTML`, `outerHTML` or `document.write` is an anti-pattern that can lead to XSS vulnerabilities + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - browser + patterns: + - pattern-either: + - pattern: | + $EL.innerHTML = $HTML; + - pattern: | + $EL.outerHTML = $HTML; + - pattern: document.write(...) + - pattern-not: | + $EL.innerHTML = "..."; + - pattern-not: | + $EL.outerHTML = "..."; + - pattern-not: document.write("...") + severity: ERROR + - id: javascript.browser.security.insecure-innerhtml.insecure-innerhtml + languages: + - javascript + - typescript + message: User controlled data in a `$EL.innerHTML` is an anti-pattern that can lead to XSS vulnerabilities + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - browser + patterns: + - pattern: | + $EL.innerHTML = $HTML; + - pattern-not: | + $EL.innerHTML = "..."; + severity: ERROR + - id: javascript.browser.security.insufficient-postmessage-origin-validation.insufficient-postmessage-origin-validation + languages: + - javascript + - typescript + message: No validation of origin is done by the addEventListener API. It may be possible to exploit this flaw to perform Cross Origin attacks such as Cross-Site Scripting(XSS). + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-345: Insufficient Verification of Data Authenticity' + impact: LOW + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + subcategory: + - audit + technology: + - browser + pattern-either: + - patterns: + - pattern: | + window.addEventListener('message', $FUNC, ...) + - metavariable-pattern: + metavariable: $FUNC + patterns: + - pattern: | + function($OBJ) { ... } + - pattern-not: | + function($OBJ) { ... if (<... $OBJ.origin ...>) { ... } ... } + - patterns: + - pattern-either: + - pattern-inside: | + function $FNAME($OBJ) { $CONTEXT } + ... + - pattern-inside: | + $FNAME = (...) => { $CONTEXT } + ... + - pattern: | + window.addEventListener('message', $FNAME,...) + - metavariable-pattern: + metavariable: $CONTEXT + patterns: + - pattern-not: | + ... if (<... $OBJ.origin ...>) { ... } ... + severity: WARNING + - id: javascript.browser.security.open-redirect-from-function.js-open-redirect-from-function + languages: + - javascript + - typescript + message: The application accepts potentially user-controlled input `$PROP` which can control the location of the current window context. This can lead two types of vulnerabilities open-redirection and Cross-Site-Scripting (XSS) with JavaScript URIs. It is recommended to validate user-controllable input before allowing it to control the redirection. + metadata: + asvs: + control_id: 5.5.1 Insecue Redirect + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html + subcategory: + - vuln + technology: + - browser + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: location.href = $SINK + - pattern: window.location.href = $SINK + - pattern: this.window.location.href = $SINK + - pattern: this.location.href = $SINK + - pattern: location.replace($SINK) + - pattern: window.location.replace($SINK) + - pattern: this.window.location.replace($SINK) + - pattern: this.location.replace($SINK) + - focus-metavariable: $SINK + - metavariable-pattern: + metavariable: $SINK + patterns: + - pattern-not: | + "..." + $VALUE + - pattern-not: | + `...${$VALUE}` + pattern-sources: + - patterns: + - pattern-inside: | + function ... (..., $PROP, ...) { ... } + - focus-metavariable: $PROP + severity: INFO + - id: javascript.browser.security.open-redirect.js-open-redirect + languages: + - javascript + - typescript + message: The application accepts potentially user-controlled input `$PROP` which can control the location of the current window context. This can lead two types of vulnerabilities open-redirection and Cross-Site-Scripting (XSS) with JavaScript URIs. It is recommended to validate user-controllable input before allowing it to control the redirection. + metadata: + asvs: + control_id: 5.5.1 Insecue Redirect + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A01:2021 - Broken Access Control + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html + subcategory: + - vuln + technology: + - browser + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: location.href = $SINK + - pattern: $THIS. ... .location.href = $SINK + - pattern: location.replace($SINK) + - pattern: $THIS. ... .location.replace($SINK) + - pattern: location = $SINK + - pattern: $WINDOW. ... .location = $SINK + - focus-metavariable: $SINK + - metavariable-pattern: + metavariable: $SINK + patterns: + - pattern-not: | + "..." + $VALUE + - pattern-not: | + `...${$VALUE}` + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $PROP = new URLSearchParams($WINDOW. ... .location.search).get('...') + ... + - pattern-inside: | + $PROP = new URLSearchParams(location.search).get('...') + ... + - pattern-inside: | + $PROP = new URLSearchParams($WINDOW. ... .location.hash.substring(1)).get('...') + ... + - pattern-inside: | + $PROP = new URLSearchParams(location.hash.substring(1)).get('...') + ... + - pattern: $PROP + - patterns: + - pattern-either: + - pattern-inside: | + $PROPS = new URLSearchParams($WINDOW. ... .location.search) + ... + - pattern-inside: | + $PROPS = new URLSearchParams(location.search) + ... + - pattern-inside: | + $PROPS = new URLSearchParams($WINDOW. ... .location.hash.substring(1)) + ... + - pattern-inside: | + $PROPS = new URLSearchParams(location.hash.substring(1)) + ... + - pattern: $PROPS.get('...') + - patterns: + - pattern-either: + - pattern-inside: | + $PROPS = new URL($WINDOW. ... .location.href) + ... + - pattern-inside: | + $PROPS = new URL(location.href) + ... + - pattern: $PROPS.searchParams.get('...') + - patterns: + - pattern-either: + - pattern-inside: | + $PROPS = new URL($WINDOW. ... .location.href).searchParams.get('...') + ... + - pattern-inside: | + $PROPS = new URL(location.href).searchParams.get('...') + ... + - pattern: $PROPS + severity: WARNING + - id: javascript.browser.security.raw-html-concat.raw-html-concat + languages: + - javascript + - typescript + message: User controlled data in a HTML string may result in XSS + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/xss/ + subcategory: + - vuln + technology: + - browser + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + $S = new Remarkable() + ... + - pattern: $S.render(...) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: $STRING + $EXPR + - pattern-not: $STRING + "..." + - metavariable-pattern: + language: generic + metavariable: $STRING + patterns: + - pattern: <$TAG ... + - pattern-not: <$TAG ...>...... + - patterns: + - pattern: $EXPR + $STRING + - pattern-not: '"..." + $STRING' + - metavariable-pattern: + language: generic + metavariable: $STRING + patterns: + - pattern: '... ,...) + - pattern-not-inside: | + $OPTS = <... {name:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.name = ...; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-secure + languages: + - javascript + - typescript + message: 'Default session middleware settings: `secure` not set. It ensures the browser only sends the cookie over HTTPS.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: HIGH + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + subcategory: + - vuln + technology: + - express + patterns: + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{secure:true}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{secure:true}} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {secure:true} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {secure:true} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.secure = true; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.secure = true; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-httponly + languages: + - javascript + - typescript + message: 'Default session middleware settings: `httpOnly` not set. It ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: HIGH + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + subcategory: + - vuln + technology: + - express + patterns: + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{httpOnly:true}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{httpOnly:true}} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {httpOnly:true} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {httpOnly:true} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.httpOnly = true; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.httpOnly = true; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-domain + languages: + - javascript + - typescript + message: 'Default session middleware settings: `domain` not set. It indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: HIGH + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + subcategory: + - vuln + technology: + - express + patterns: + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{domain:...}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{domain:...}} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {domain:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {domain:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.domain = ...; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.domain = ...; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-path + languages: + - javascript + - typescript + message: 'Default session middleware settings: `path` not set. It indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: HIGH + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + subcategory: + - vuln + technology: + - express + patterns: + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{path:...}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{path:...}} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {path:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {path:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.path = ...; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.path = ...; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-expires + languages: + - javascript + - typescript + message: 'Default session middleware settings: `expires` not set. Use it to set expiration date for persistent cookies.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: HIGH + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html + subcategory: + - vuln + technology: + - express + patterns: + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{expires:...}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{expires:...}} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {expires:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {expires:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.expires = ...; + ... + $SESSION($OPTS,...); + - pattern-not-inside: |- + $OPTS = ...; + ... + $OPTS.cookie.expires = ...; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-detect-notevil-usage.express-detect-notevil-usage + languages: + - javascript + - typescript + message: Detected usage of the `notevil` package, which is unmaintained and has vulnerabilities. Using any sort of `eval()` functionality can be very dangerous, but if you must, the `eval` package is an up to date alternative. Be sure that only trusted input reaches an `eval()` function. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-1104: Use of Unmaintained Third Party Components' + impact: HIGH + likelihood: LOW + owasp: + - A06:2021 - Vulnerable and Outdated Components + references: + - https://github.com/mmckegg/notevil + subcategory: + - audit + technology: + - javascript + - typescript + patterns: + - pattern-either: + - pattern-inside: | + import $EVAL from 'notevil' + ... + - pattern-inside: | + import {$EVAL} from 'notevil' + ... + - pattern-inside: | + $EVAL = require('notevil') + ... + - pattern-either: + - patterns: + - pattern: $EVAL(...) + - pattern-not: $EVAL('...') + - patterns: + - pattern-either: + - pattern: $VM.runInContext("$CMD", ...) + - pattern: $VM.runInNewContext("$CMD", ...) + - pattern: $VM.runInThisContext("$CMD", ...) + - pattern: $VM.compileFunction("$CMD", ...) + - metavariable-pattern: + language: typescript + metavariable: $CMD + patterns: + - pattern: $EVAL(...) + - pattern-not: $EVAL('...') + severity: WARNING + - id: javascript.express.security.audit.express-jwt-not-revoked.express-jwt-not-revoked + languages: + - javascript + - typescript + message: No token revoking configured for `express-jwt`. A leaked token could still be used and unable to be revoked. Consider using function as the `isRevoked` option. + metadata: + asvs: + control_id: 3.5.3 Insecue Stateless Session Tokens + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://github.com/goldbergyoni/nodebestpractices/blob/master/sections/security/expirejwt.md + subcategory: + - vuln + technology: + - express + patterns: + - pattern-inside: | + $JWT = require('express-jwt'); + ... + - pattern: $JWT(...) + - pattern-not-inside: $JWT(<... {isRevoked:...} ...>,...) + - pattern-not-inside: |- + $OPTS = <... {isRevoked:...} ...>; + ... + $JWT($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-libxml-noent.express-libxml-noent + languages: + - javascript + - typescript + message: The libxml library processes user-input with the `noent` attribute is set to `true` which can lead to being vulnerable to XML External Entities (XXE) type attacks. It is recommended to set `noent` to `false` when using this feature to ensure you are protected. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + interfile: true + likelihood: HIGH + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + mode: taint + options: + interfile: true + pattern-sinks: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $XML = require('$IMPORT') + ... + - pattern-inside: | + import $XML from '$IMPORT' + ... + - pattern-inside: | + import * as $XML from '$IMPORT' + ... + - metavariable-regex: + metavariable: $IMPORT + regex: ^(libxmljs|libxmljs2)$ + - pattern-inside: $XML.$FUNC($QUERY, {...,noent:true,...}) + - metavariable-regex: + metavariable: $FUNC + regex: ^(parseXmlString|parseXml)$ + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - pattern: $REQ.files.$ANYTHING.data.toString('utf8') + - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - pattern: files.$ANYTHING.data.toString('utf8') + - pattern: files.$ANYTHING['data'].toString('utf8') + severity: ERROR + - id: javascript.express.security.audit.express-libxml-vm-noent.express-libxml-vm-noent + languages: + - javascript + - typescript + message: Detected use of parseXml() function with the `noent` field set to `true`. This can lead to an XML External Entities (XXE) attack if untrusted data is passed into it. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - express + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: $VM.runInContext("$CMD", ...) + - pattern: $VM.runInNewContext("$CMD", ...) + - pattern: $VM.runInThisContext("$CMD", ...) + - pattern: $VM.compileFunction("$CMD", ...) + - metavariable-pattern: + language: typescript + metavariable: $CMD + pattern-either: + - pattern: | + $LIBXML.parseXml($DATA, {..., noent: true, ...}, ...) + - patterns: + - pattern-inside: | + $OPTS = {..., noent: true, ...} + ... + - pattern: $LIBXML.parseXml( $DATA, $OPTS ) + - pattern: | + $LIBXML.parseXml($DATA, {..., noent: true, ...}, ...) + - patterns: + - pattern-inside: | + $OPTS = {..., noent: true, ...} + ... + - pattern: $LIBXML.parseXml( $DATA, $OPTS ) + severity: WARNING + - id: javascript.express.security.audit.express-open-redirect.express-open-redirect + languages: + - javascript + - typescript + message: The application redirects to a URL specified by user-supplied input `$REQ` that is not validated. This could redirect users to malicious locations. Consider using an allow-list approach to validate URLs, or warn users they are being redirected to a third-party website. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A01:2021 - Broken Access Control + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + mode: taint + options: + symbolic_propagation: true + taint_unify_mvars: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.redirect("$HTTP"+$REQ. ... .$VALUE) + - pattern: $RES.redirect("$HTTP"+$REQ. ... .$VALUE + $...A) + - pattern: $RES.redirect(`$HTTP${$REQ. ... .$VALUE}...`) + - pattern: $RES.redirect("$HTTP"+$REQ.$VALUE[...]) + - pattern: $RES.redirect("$HTTP"+$REQ.$VALUE[...] + $...A) + - pattern: $RES.redirect(`$HTTP${$REQ.$VALUE[...]}...`) + - metavariable-regex: + metavariable: $HTTP + regex: ^https?:\/\/$ + - pattern-either: + - pattern: $REQ. ... .$VALUE + - patterns: + - pattern-either: + - pattern: $RES.redirect($REQ. ... .$VALUE) + - pattern: $RES.redirect($REQ. ... .$VALUE + $...A) + - pattern: $RES.redirect(`${$REQ. ... .$VALUE}...`) + - pattern: $REQ. ... .$VALUE + - patterns: + - pattern-either: + - pattern: $RES.redirect($REQ.$VALUE['...']) + - pattern: $RES.redirect($REQ.$VALUE['...'] + $...A) + - pattern: $RES.redirect(`${$REQ.$VALUE['...']}...`) + - pattern: $REQ.$VALUE + - patterns: + - pattern-either: + - pattern-inside: | + $ASSIGN = $REQ. ... .$VALUE + ... + - pattern-inside: | + $ASSIGN = $REQ.$VALUE['...'] + ... + - pattern-inside: | + $ASSIGN = $REQ. ... .$VALUE + $...A + ... + - pattern-inside: "$ASSIGN = $REQ.$VALUE['...'] + $...A\n... \n" + - pattern-inside: | + $ASSIGN = `${$REQ. ... .$VALUE}...` + ... + - pattern-inside: "$ASSIGN = `${$REQ.$VALUE['...']}...`\n... \n" + - pattern-either: + - pattern: $RES.redirect($ASSIGN) + - pattern: $RES.redirect($ASSIGN + $...FOO) + - pattern: $RES.redirect(`${$ASSIGN}...`) + - focus-metavariable: $ASSIGN + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.audit.express-path-join-resolve-traversal.express-path-join-resolve-traversal + languages: + - javascript + - typescript + message: Possible writing outside of the destination, make sure that the target path is nested in the intended destination + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + subcategory: + - vuln + technology: + - express + - node.js + mode: taint + pattern-sanitizers: + - pattern: $Y.replace(...) + - pattern: $Y.indexOf(...) + - pattern: | + function ... (...) { + ... + <... $Y.indexOf(...) ...> + ... + } + - patterns: + - pattern: $FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: sanitize + pattern-sinks: + - patterns: + - focus-metavariable: $SINK + - pattern-either: + - pattern-inside: | + $PATH = require('path'); + ... + - pattern-inside: | + import $PATH from 'path'; + ... + - pattern-either: + - pattern: $PATH.join(...,$SINK,...) + - pattern: $PATH.resolve(...,$SINK,...) + - patterns: + - focus-metavariable: $SINK + - pattern-inside: | + import 'path'; + ... + - pattern-either: + - pattern: path.join(...,$SINK,...) + - pattern: path.resolve(...,$SINK,...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.audit.express-res-sendfile.express-res-sendfile + languages: + - javascript + - typescript + message: The application processes user-input, this is passed to res.sendFile which can allow an attacker to arbitrarily read files on the system through path traversal. It is recommended to perform input validation in addition to canonicalizing the path. This allows you to validate the path against the intended directory it should be accessing. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-73: External Control of File Name or Path' + impact: MEDIUM + likelihood: HIGH + owasp: + - A04:2021 - Insecure Design + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.$METH($QUERY,...) + - pattern-not-inside: $RES.$METH($QUERY,$OPTIONS) + - metavariable-regex: + metavariable: $METH + regex: ^(sendfile|sendFile)$ + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + function ... (...,$REQ: $TYPE, ...) {...} + - metavariable-regex: + metavariable: $TYPE + regex: ^(string|String) + severity: WARNING + - id: javascript.express.security.audit.express-session-hardcoded-secret.express-session-hardcoded-secret + languages: + - javascript + - typescript + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + interfile: true + likelihood: HIGH + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + - secrets + options: + interfile: true + patterns: + - pattern-either: + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern-inside: | + import $SESSION from 'express-session' + ... + - pattern-inside: | + import {..., $SESSION, ...} from 'express-session' + ... + - pattern-inside: | + import * as $SESSION from 'express-session' + ... + - patterns: + - pattern-either: + - pattern-inside: $APP.use($SESSION({...})) + - pattern: | + $SECRET = $VALUE + ... + $APP.use($SESSION($SECRET)) + - pattern: | + secret: '$Y' + severity: WARNING + - id: javascript.express.security.audit.express-ssrf.express-ssrf + languages: + - javascript + - typescript + message: 'The following request $REQUEST.$METHOD() was found to be crafted from user-input `$REQ` which can lead to Server-Side Request Forgery (SSRF) vulnerabilities. It is recommended where possible to not allow user-input to craft the base request, but to be treated as part of the path or query parameter. When user-input is necessary to craft the request, it is recommeneded to follow OWASP best practices to prevent abuse. ' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + mode: taint + options: + taint_unify_mvars: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $REQUEST = require('request') + ... + - pattern-inside: | + import * as $REQUEST from 'request' + ... + - pattern-inside: | + import $REQUEST from 'request' + ... + - pattern-either: + - pattern: $REQUEST.$METHOD("$HTTP"+$REQ. ... .$VALUE) + - pattern: $REQUEST.$METHOD("$HTTP"+$REQ. ... .$VALUE + $...A) + - pattern: $REQUEST.$METHOD(`$HTTP${$REQ. ... .$VALUE}...`) + - pattern: $REQUEST.$METHOD("$HTTP"+$REQ.$VALUE[...]) + - pattern: $REQUEST.$METHOD("$HTTP"+$REQ.$VALUE[...] + $...A) + - pattern: $REQUEST.$METHOD(`$HTTP${$REQ.$VALUE[...]}...`) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|patch|del|head|delete)$ + - metavariable-regex: + metavariable: $HTTP + regex: ^(https?:\/\/|//)$ + - pattern-either: + - pattern: $REQ. ... .$VALUE + - patterns: + - pattern-either: + - pattern-inside: | + $REQUEST = require('request') + ... + - pattern-inside: | + import * as $REQUEST from 'request' + ... + - pattern-inside: | + import $REQUEST from 'request' + ... + - pattern-either: + - pattern: $REQUEST.$METHOD($REQ. ... .$VALUE,...) + - pattern: $REQUEST.$METHOD($REQ. ... .$VALUE + $...A,...) + - pattern: $REQUEST.$METHOD(`${$REQ. ... .$VALUE}...`,...) + - pattern: $REQ. ... .$VALUE + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|patch|del|head|delete)$ + - patterns: + - pattern-either: + - pattern-inside: | + $REQUEST = require('request') + ... + - pattern-inside: | + import * as $REQUEST from 'request' + ... + - pattern-inside: | + import $REQUEST from 'request' + ... + - pattern-either: + - pattern: $REQUEST.$METHOD($REQ.$VALUE['...'],...) + - pattern: $REQUEST.$METHOD($REQ.$VALUE['...'] + $...A,...) + - pattern: $REQUEST.$METHOD(`${$REQ.$VALUE['...']}...`,...) + - pattern: $REQ.$VALUE + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|patch|del|head|delete)$ + - patterns: + - pattern-either: + - pattern-inside: | + $REQUEST = require('request') + ... + - pattern-inside: | + import * as $REQUEST from 'request' + ... + - pattern-inside: | + import $REQUEST from 'request' + ... + - pattern-either: + - pattern-inside: | + $ASSIGN = $REQ. ... .$VALUE + ... + - pattern-inside: | + $ASSIGN = $REQ. ... .$VALUE['...'] + ... + - pattern-inside: | + $ASSIGN = $REQ. ... .$VALUE + $...A + ... + - pattern-inside: "$ASSIGN = $REQ. ... .$VALUE['...'] + $...A\n... \n" + - pattern-inside: | + $ASSIGN = `${$REQ. ... .$VALUE}...` + ... + - pattern-inside: "$ASSIGN = `${$REQ. ... .$VALUE['...']}...`\n... \n" + - patterns: + - pattern-either: + - pattern-inside: | + $ASSIGN = "$HTTP"+ $REQ. ... .$VALUE + ... + - pattern-inside: | + $ASSIGN = "$HTTP"+$REQ. ... .$VALUE + $...A + ... + - pattern-inside: | + $ASSIGN = "$HTTP"+$REQ.$VALUE[...] + ... + - pattern-inside: | + $ASSIGN = "$HTTP"+$REQ.$VALUE[...] + $...A + ... + - pattern-inside: | + $ASSIGN = `$HTTP${$REQ.$VALUE[...]}...` + ... + - metavariable-regex: + metavariable: $HTTP + regex: ^(https?:\/\/|//)$ + - pattern-either: + - pattern: $REQUEST.$METHOD($ASSIGN,...) + - pattern: $REQUEST.$METHOD($ASSIGN + $...FOO,...) + - pattern: $REQUEST.$METHOD(`${$ASSIGN}...`,...) + - patterns: + - pattern-either: + - pattern: $REQUEST.$METHOD("$HTTP"+$ASSIGN,...) + - pattern: $REQUEST.$METHOD("$HTTP"+$ASSIGN + $...A,...) + - pattern: $REQUEST.$METHOD(`$HTTP${$ASSIGN}...`,...) + - metavariable-regex: + metavariable: $HTTP + regex: ^(https?:\/\/|//)$ + - pattern: $ASSIGN + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|patch|del|head|delete)$ + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, ...) {...} + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,...) => + {...} + - pattern-inside: | + ({ $REQ }: $EXPRESS.Request,...) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.audit.express-third-party-object-deserialization.express-third-party-object-deserialization + languages: + - javascript + - typescript + message: The following function call $SER.$FUNC accepts user controlled data which can result in Remote Code Execution (RCE) through Object Deserialization. It is recommended to use secure data processing alternatives such as JSON.parse() and Buffer.from(). + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + interfile: true + likelihood: HIGH + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + source_rule_url: + - https://github.com/ajinabraham/njsscan/blob/75bfbeb9c8d72999e4d527dfa2548f7f0f3cc48a/njsscan/rules/semantic_grep/eval/eval_deserialize.yaml + subcategory: + - vuln + technology: + - express + mode: taint + options: + interfile: true + pattern-sinks: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $SER = require('$IMPORT') + ... + - pattern-inside: | + import $SER from '$IMPORT' + ... + - pattern-inside: | + import * as $SER from '$IMPORT' + ... + - metavariable-regex: + metavariable: $IMPORT + regex: ^(node-serialize|serialize-to-js)$ + - pattern: $SER.$FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: ^(unserialize|deserialize)$ + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - pattern: $REQ.files.$ANYTHING.data.toString('utf8') + - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - pattern: files.$ANYTHING.data.toString('utf8') + - pattern: files.$ANYTHING['data'].toString('utf8') + severity: WARNING + - id: javascript.express.security.audit.express-xml2json-xxe-event.express-xml2json-xxe-event + languages: + - javascript + - typescript + message: Xml Parser is used inside Request Event. Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://www.npmjs.com/package/xml2json + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('xml2json'); + ... + - pattern-inside: | + import 'xml2json'; + ... + - pattern: $REQ.on('...', function(...) { ... $EXPAT.toJson($INPUT,...); ... }) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.audit.possible-user-input-redirect.unknown-value-in-redirect + languages: + - javascript + - typescript + message: It looks like '$UNK' is read from user input and it is used to as a redirect. Ensure '$UNK' is not externally controlled, otherwise this is an open redirect. + metadata: + asvs: + control_id: 5.5.1 Insecue Redirect + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - express + patterns: + - pattern-either: + - pattern-inside: | + $UNK = query.$B; + ... + - pattern-inside: | + $UNK = $A.query.$B; + ... + - pattern-inside: | + $UNK = req.$SOMETHING; + ... + - pattern: $RES.redirect(..., <... $UNK ...>, ...) + severity: WARNING + - id: javascript.express.security.audit.remote-property-injection.remote-property-injection + languages: + - javascript + - typescript + message: Bracket object notation with user input is present, this might allow an attacker to access all properties of the object and even it's prototype. Use literal values for object properties. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://github.com/nodesecurity/eslint-plugin-security/blob/3c7522ca1be800353513282867a1034c795d9eb4/docs/the-dangers-of-square-bracket-notation.md + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sanitizers: + - patterns: + - pattern: var $X = ... + - pattern-not: var $X = $REQ.$ANY + pattern-sinks: + - patterns: + - pattern-inside: $OBJ[...] = ... + - pattern-not-inside: $OBJ["..."] = ... + - pattern-not-inside: $OBJ[...] = "..." + - pattern: $INDEX + - pattern-not: | + "..." + $INDEX + - pattern-not: | + $INDEX + "..." + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.audit.res-render-injection.res-render-injection + languages: + - javascript + - typescript + message: User controllable data `$REQ` enters `$RES.render(...)` this can lead to the loading of other HTML/templating pages that they may not be authorized to render. An attacker may attempt to use directory traversal techniques e.g. `../folder/index` to access other HTML pages on the file system. Where possible, do not allow users to define what should be loaded in $RES.render or use an allow list for the existing application. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-706: Use of Incorrectly-Resolved Name or Reference' + impact: MEDIUM + interfile: true + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - http://expressjs.com/en/4x/api.html#res.render + subcategory: + - vuln + technology: + - express + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.render($SINK, ...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.audit.xss.direct-response-write.direct-response-write + languages: + - javascript + - typescript + message: Detected directly writing to a Response object from user-defined input. This bypasses any HTML escaping and may expose your application to a Cross-Site-scripting (XSS) vulnerability. Instead, use 'resp.render()' to render safely escaped HTML. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + vulnerability_class: + - Cross-Site-Scripting (XSS) + mode: taint + options: + interfile: true + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + $S = new Remarkable() + ... + - pattern: $S.render(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'express-xss-sanitizer'; + ... + - pattern-inside: | + import * as $S from "express-xss-sanitizer"; + ... + - pattern-inside: | + const { ..., $S, ... } = require('express-xss-sanitizer'); + ... + - pattern-inside: | + var { ..., $S, ... } = require('express-xss-sanitizer'); + ... + - pattern-inside: | + let { ...,$S,... } = require('express-xss-sanitizer'); + ... + - pattern-inside: | + $S = require("express-xss-sanitizer") + ... + - pattern: $S(...) + - patterns: + - pattern: $RES. ... .type('$F'). ... .send(...) + - metavariable-regex: + metavariable: $F + regex: (?!.*text/html) + - patterns: + - pattern-inside: | + $X = [...]; + ... + - pattern: | + if(<... !$X.includes($SOURCE)...>) { + ... + return ... + } + ... + - pattern: $SOURCE + pattern-sinks: + - patterns: + - pattern-inside: function ... (..., $RES,...) {...} + - pattern-either: + - pattern: $RES.write($ARG) + - pattern: $RES.send($ARG) + - pattern-not: $RES. ... .set('...'). ... .send($ARG) + - pattern-not: $RES. ... .type('...'). ... .send($ARG) + - pattern-not-inside: $RES.$METHOD({ ... }) + - focus-metavariable: $ARG + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options) + - pattern-not-inside: | + function ... ($REQ, $RES) { + ... + $RES.$SET('Content-Type', '$TYPE') + } + - pattern-not-inside: | + $APP.$METHOD(..., function $FUNC($REQ, $RES) { + ... + $RES.$SET('Content-Type', '$TYPE') + }) + - pattern-not-inside: | + function ... ($REQ, $RES, $NEXT) { + ... + $RES.$SET('Content-Type', '$TYPE') + } + - pattern-not-inside: | + function ... ($REQ, $RES) { + ... + $RES.set('$TYPE') + } + - pattern-not-inside: | + $APP.$METHOD(..., function $FUNC($REQ, $RES) { + ... + $RES.set('$TYPE') + }) + - pattern-not-inside: | + function ... ($REQ, $RES, $NEXT) { + ... + $RES.set('$TYPE') + } + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - pattern-not-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + { + ... + $RES.$SET('Content-Type', '$TYPE') + } + - pattern-not-inside: | + ({ $REQ }: Request,$RES: Response) => { + ... + $RES.$SET('Content-Type', '$TYPE') + } + - pattern-not-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + { + ... + $RES.set('$TYPE') + } + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: body + severity: WARNING + - fix-regex: + regex: <%-(.*?)%> + replacement: <%=\1%> + id: javascript.express.security.audit.xss.ejs.explicit-unescape.template-explicit-unescape + languages: + - regex + message: Detected an explicit unescape in an EJS template, using '<%- ... %>' If external data can reach these locations, your application is exposed to a cross-site scripting (XSS) vulnerability. Use '<%= ... %>' to escape this data. If you need escaping, ensure no external data can reach this location. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - http://www.managerjs.com/blog/2015/05/will-ejs-escape-save-me-from-xss-sorta/ + subcategory: + - audit + technology: + - express + paths: + include: + - '*.ejs' + - '*.html' + pattern-regex: <%-((?!include).)*?%> + severity: WARNING + - id: javascript.express.security.audit.xss.ejs.var-in-href.var-in-href + languages: + - regex + message: 'Detected a template variable used in an anchor tag with the ''href'' attribute. This allows a malicious actor to input the ''javascript:'' URI and is subject to cross- site scripting (XSS) attacks. If using a relative URL, start with a literal forward slash and concatenate the URL, like this: href=''/<%= link %>''. You may also consider setting the Content Security Policy (CSP) header.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss#:~:text=javascript:%20URI + - https://github.com/pugjs/pug/issues/2952 + subcategory: + - audit + technology: + - express + paths: + include: + - '*.ejs' + - '*.html' + pattern-regex: ]*?[^\/&=]<%.*?%>.*?> + severity: WARNING + - id: javascript.express.security.audit.xss.ejs.var-in-script-src.var-in-script-src + languages: + - generic + message: Detected a template variable used as the 'src' in a script tag. Although template variables are HTML escaped, HTML escaping does not always prevent malicious URLs from being injected and could results in a cross-site scripting (XSS) vulnerability. Prefer not to dynamically generate the 'src' attribute and use static URLs instead. If you must do this, carefully check URLs against an allowlist and be sure to URL-encode the result. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://www.veracode.com/blog/secure-development/nodejs-template-engines-why-default-encoders-are-not-enough + - https://github.com/ESAPI/owasp-esapi-js + subcategory: + - audit + technology: + - express + paths: + include: + - '*.ejs' + - '*.html' + patterns: + - pattern-inside: + - pattern-not-inside: + - pattern: '{{ ... }}' + severity: WARNING + - id: javascript.express.security.audit.xss.pug.and-attributes.template-and-attributes + languages: + - regex + message: Detected a unescaped variables using '&attributes'. If external data can reach these locations, your application is exposed to a cross-site scripting (XSS) vulnerability. If you must do this, ensure no external data can reach this location. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://pugjs.org/language/attributes.html#attributes + subcategory: + - audit + technology: + - express + paths: + include: + - '*.pug' + pattern-regex: .*&attributes.* + severity: WARNING + - id: javascript.express.security.audit.xss.pug.explicit-unescape.template-explicit-unescape + languages: + - regex + message: Detected an explicit unescape in a Pug template, using either '!=' or '!{...}'. If external data can reach these locations, your application is exposed to a cross-site scripting (XSS) vulnerability. If you must do this, ensure no external data can reach this location. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://pugjs.org/language/code.html#unescaped-buffered-code + - https://pugjs.org/language/attributes.html#unescaped-attributes + subcategory: + - audit + technology: + - express + paths: + include: + - '*.pug' + pattern-either: + - pattern-regex: \w.*(!=)[^=].* + - pattern-regex: '!{.*?}' + severity: WARNING + - id: javascript.express.security.audit.xss.pug.var-in-href.var-in-href + languages: + - regex + message: 'Detected a template variable used in an anchor tag with the ''href'' attribute. This allows a malicious actor to input the ''javascript:'' URI and is subject to cross- site scripting (XSS) attacks. If using a relative URL, start with a literal forward slash and concatenate the URL, like this: a(href=''/''+url). You may also consider setting the Content Security Policy (CSP) header.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://github.com/pugjs/pug/issues/2952 + - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss#:~:text=javascript:%20URI + subcategory: + - audit + technology: + - express + paths: + include: + - '*.pug' + pattern-regex: a\(.*href=[^'"].*\) + severity: WARNING + - id: javascript.express.security.audit.xss.pug.var-in-script-tag.var-in-script-tag + languages: + - regex + message: Detected a template variable used in a script tag. Although template variables are HTML escaped, HTML escaping does not always prevent cross-site scripting (XSS) attacks when used directly in JavaScript. If you need this data on the rendered page, consider placing it in the HTML portion (outside of a script tag). Alternatively, use a JavaScript-specific encoder, such as the one available in OWASP ESAPI. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://www.veracode.com/blog/secure-development/nodejs-template-engines-why-default-encoders-are-not-enough + - https://github.com/ESAPI/owasp-esapi-js + subcategory: + - audit + technology: + - express + paths: + include: + - '*.pug' + pattern-either: + - pattern-regex: script\s*=[A-Za-z0-9]+ + - pattern-regex: script\s*=.*["']\s*\+.* + - pattern-regex: script\s*=[^'"]+\+.* + - pattern-regex: script\(.*?\)\s*=\s*[A-Za-z0-9]+ + - pattern-regex: script\(.*?\)\s*=\s*.*["']\s*\+.* + - pattern-regex: script\(.*?\)\s*=\s*[^'"]+\+.* + severity: WARNING + - id: javascript.express.security.cors-misconfiguration.cors-misconfiguration + languages: + - javascript + - typescript + message: By letting user input control CORS parameters, there is a risk that software does not properly verify that the source of data or communication is valid. Use literal values for CORS settings. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-346: Origin Validation Error' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.set($HEADER, $X) + - pattern: $RES.header($HEADER, $X) + - pattern: $RES.setHeader($HEADER, $X) + - pattern: | + $RES.set({$HEADER: $X}, ...) + - pattern: | + $RES.writeHead($STATUS, {$HEADER: $X}, ...) + - focus-metavariable: $X + - metavariable-regex: + metavariable: $HEADER + regex: .*(Access-Control-Allow-Origin|access-control-allow-origin).* + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.express-data-exfiltration.express-data-exfiltration + languages: + - javascript + - typescript + message: Depending on the context, user control data in `Object.assign` can cause web response to include data that it should not have or can lead to a mass assignment vulnerability. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://en.wikipedia.org/wiki/Mass_assignment_vulnerability + - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html + subcategory: + - audit + technology: + - express + mode: taint + pattern-sinks: + - pattern: Object.assign(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.express-expat-xxe.express-expat-xxe + languages: + - javascript + - typescript + message: Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities. + metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + likelihood: MEDIUM + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://github.com/astro/node-expat + subcategory: + - vuln + technology: + - express + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $XML = require('node-expat') + ... + - pattern-inside: | + import $XML from 'node-expat' + ... + - pattern-inside: | + import * as $XML from 'node-expat' + ... + - pattern-either: + - pattern-inside: | + $PARSER = new $XML.Parser(...); + ... + - pattern-either: + - pattern: $PARSER.parse($QUERY) + - pattern: $PARSER.write($QUERY) + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-insecure-template-usage.express-insecure-template-usage + languages: + - javascript + - typescript + message: User data from `$REQ` is being compiled into the template, which can lead to a Server Side Template Injection (SSTI) vulnerability. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine' + impact: MEDIUM + interfile: true + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + - A01:2017 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html + source_rule_url: + - https://github.com/github/codeql/blob/2ba2642c7ab29b9eedef33bcc2b8cd1d203d0c10/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js + subcategory: + - vuln + technology: + - javascript + - typescript + - express + - pug + - jade + - dot + - ejs + - nunjucks + - lodash + - handlbars + - mustache + - hogan.js + - eta + - squirrelly + mode: taint + options: + interfile: true + pattern-propagators: + - from: $E + pattern: $MODEL.$FIND($E).then((...,$S,...)=>{...}) + to: $S + pattern-sinks: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('pug') + ... + - pattern-inside: | + import * as $PUG from 'pug' + ... + - pattern-inside: | + $PUG = require('jade') + ... + - pattern-inside: | + import * as $PUG from 'jade' + ... + - pattern-either: + - pattern: $PUG.compile(...) + - pattern: $PUG.compileClient(...) + - pattern: $PUG.compileClientWithDependenciesTracked(...) + - pattern: $PUG.render(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('dot') + ... + - pattern-inside: | + import * as $PUG from 'dot' + ... + - pattern-either: + - pattern: $PUG.template(...) + - pattern: $PUG.compile(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('ejs') + ... + - pattern-inside: | + import * as $PUG from 'ejs' + ... + - pattern-either: + - pattern: $PUG.render(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('nunjucks') + ... + - pattern-inside: | + import * as $PUG from 'nunjucks' + ... + - pattern-either: + - pattern: $PUG.renderString(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('lodash') + ... + - pattern-inside: | + import * as $PUG from 'lodash' + ... + - pattern-either: + - pattern: $PUG.template(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('mustache') + ... + - pattern-inside: | + import * as $PUG from 'mustache' + ... + - pattern-inside: | + $PUG = require('eta') + ... + - pattern-inside: | + import * as $PUG from 'eta' + ... + - pattern-inside: | + $PUG = require('squirrelly') + ... + - pattern-inside: | + import * as $PUG from 'squirrelly' + ... + - pattern-either: + - pattern: $PUG.render(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('hogan.js') + ... + - pattern-inside: | + import * as $PUG from 'hogan.js' + ... + - pattern-inside: | + $PUG = require('handlebars') + ... + - pattern-inside: | + import * as $PUG from 'handlebars' + ... + - pattern-either: + - pattern: $PUG.compile(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.express-jwt-hardcoded-secret.express-jwt-hardcoded-secret + languages: + - javascript + - typescript + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + likelihood: HIGH + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + subcategory: + - audit + technology: + - express + - secrets + options: + interfile: true + patterns: + - pattern-either: + - pattern-inside: | + $JWT = require('express-jwt'); + ... + - pattern-inside: | + import $JWT from 'express-jwt'; + ... + - pattern-inside: | + import * as $JWT from 'express-jwt'; + ... + - pattern-inside: | + import { ..., $JWT, ... } from 'express-jwt'; + ... + - pattern-either: + - pattern: | + $JWT({...,secret: "$Y",...},...) + - pattern: | + $OPTS = "$Y"; + ... + $JWT({...,secret: $OPTS},...); + - focus-metavariable: $Y + severity: WARNING + - id: javascript.express.security.express-phantom-injection.express-phantom-injection + languages: + - javascript + - typescript + message: If unverified user data can reach the `phantom` methods it can result in Server-Side Request Forgery vulnerabilities + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://phantomjs.org/page-automation.html + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('phantom'); + ... + - pattern-inside: | + import 'phantom'; + ... + - pattern-either: + - pattern: $PAGE.open($SINK,...) + - pattern: $PAGE.setContent($SINK,...) + - pattern: $PAGE.openUrl($SINK,...) + - pattern: $PAGE.evaluateJavaScript($SINK,...) + - pattern: $PAGE.property("content",$SINK,...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-puppeteer-injection.express-puppeteer-injection + languages: + - javascript + - typescript + message: If unverified user data can reach the `puppeteer` methods it can result in Server-Side Request Forgery vulnerabilities + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://pptr.dev/api/puppeteer.page + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('puppeteer'); + ... + - pattern-inside: | + import 'puppeteer'; + ... + - pattern-either: + - pattern: $PAGE.goto($SINK,...) + - pattern: $PAGE.setContent($SINK,...) + - pattern: $PAGE.evaluate($SINK,...) + - pattern: $PAGE.evaluate($CODE,$SINK,...) + - pattern: $PAGE.evaluateHandle($SINK,...) + - pattern: $PAGE.evaluateHandle($CODE,$SINK,...) + - pattern: $PAGE.evaluateOnNewDocument($SINK,...) + - pattern: $PAGE.evaluateOnNewDocument($CODE,$SINK,...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-sandbox-injection.express-sandbox-code-injection + languages: + - javascript + - typescript + message: Make sure that unverified user data can not reach `sandbox`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + $SANDBOX = require('sandbox'); + ... + - pattern-either: + - patterns: + - pattern-inside: | + $S = new $SANDBOX(...); + ... + - pattern: | + $S.run(...) + - pattern: | + new $SANDBOX($OPTS).run(...) + - pattern: new $SANDBOX().run(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-vm-injection.express-vm-injection + languages: + - javascript + - typescript + message: Make sure that unverified user data can not reach `$VM`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + $VM = require('vm'); + ... + - pattern-either: + - pattern: | + $VM.runInContext(...) + - pattern: | + $VM.runInNewContext(...) + - pattern: | + $VM.compileFunction(...) + - pattern: | + $VM.runInThisContext(...) + - pattern: new $VM.Script(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-vm2-injection.express-vm2-injection + languages: + - javascript + - typescript + message: Make sure that unverified user data can not reach `vm2`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + require('vm2') + ... + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $VM = new VM(...) + ... + - pattern-inside: | + $VM = new NodeVM(...) + ... + - pattern: | + $VM.run(...) + - pattern: | + new VM(...).run(...) + - pattern: | + new NodeVM(...).run(...) + - pattern: | + new VMScript(...) + - pattern: | + new VM(...) + - pattern: new NodeVM(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.express-wkhtml-injection.express-wkhtmltoimage-injection + languages: + - javascript + - typescript + message: If unverified user data can reach the `phantom` methods it can result in Server-Side Request Forgery vulnerabilities + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://www.npmjs.com/package/wkhtmltopdf + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern: $WK.generate($SINK,...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-wkhtml-injection.express-wkhtmltopdf-injection + languages: + - javascript + - typescript + message: If unverified user data can reach the `wkhtmltopdf` methods it can result in Server-Side Request Forgery vulnerabilities + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://www.npmjs.com/package/wkhtmltopdf + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + $WK = require('wkhtmltopdf'); + ... + - pattern: $WK($SINK,...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-xml2json-xxe.express-xml2json-xxe + languages: + - javascript + - typescript + message: Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities + metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://www.npmjs.com/package/xml2json + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('xml2json'); + ... + - pattern-inside: | + import 'xml2json'; + ... + - pattern: $EXPAT.toJson($SINK,...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - pattern: $REQ.files.$ANYTHING.data.toString('utf8') + - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - pattern: files.$ANYTHING.data.toString('utf8') + - pattern: files.$ANYTHING['data'].toString('utf8') + severity: ERROR + - id: javascript.express.security.injection.raw-html-format.raw-html-format + languages: + - javascript + - typescript + message: User data flows into the host portion of this manually-constructed HTML. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. Consider using a sanitization library such as DOMPurify to sanitize the HTML within. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: '"$HTMLSTR" + $EXPR' + - pattern: '"$HTMLSTR".concat(...)' + - pattern: util.format($HTMLSTR, ...) + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... + - patterns: + - pattern: | + `...` + - pattern-regex: | + .*<\w+.* + requires: (EXPRESS and not CLEAN) or (EXPRESSTS and not CLEAN) + pattern-sources: + - label: EXPRESS + patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - label: EXPRESSTS + patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - by-side-effect: true + label: CLEAN + patterns: + - pattern-either: + - pattern: $A($SOURCE) + - pattern: $SANITIZE. ... .$A($SOURCE) + - pattern: $A. ... .$SANITIZE($SOURCE) + - focus-metavariable: $SOURCE + - metavariable-regex: + metavariable: $A + regex: (?i)(.*valid|.*sanitiz) + severity: WARNING + - id: javascript.express.security.injection.tainted-sql-string.tainted-sql-string + languages: + - javascript + - typescript + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/SQL_Injection + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + "$SQLSTR" + $EXPR + - pattern-inside: | + "$SQLSTR".concat($EXPR) + - pattern: util.format($SQLSTR, $EXPR) + - pattern: | + `$SQLSTR${$EXPR}...` + - metavariable-regex: + metavariable: $SQLSTR + regex: .*\b(?i)(select|delete|insert|create|update\s+.+\sset|alter|drop)\b.* + - focus-metavariable: $EXPR + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... (...,$REQ, ...) {...} + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + (...,{ $REQ }: Request,...) => {...} + - pattern-inside: | + (...,{ $REQ }: $EXPRESS.Request,...) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.require-request.require-request + languages: + - javascript + - typescript + message: If an attacker controls the x in require(x) then they can cause code to load that was not intended to run on the server. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-706: Use of Incorrectly-Resolved Name or Reference' + impact: MEDIUM + interfile: true + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://github.com/google/node-sec-roadmap/blob/master/chapter-2/dynamism.md#dynamism-when-you-need-it + source-rule-url: https://nodesecroadmap.fyi/chapter-1/threat-UIR.html + subcategory: + - vuln + technology: + - express + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern: require($SINK) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.x-frame-options-misconfiguration.x-frame-options-misconfiguration + languages: + - javascript + - typescript + message: By letting user input control `X-Frame-Options` header, there is a risk that software does not properly verify whether or not a browser should be allowed to render a page in an `iframe`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-451: User Interface (UI) Misrepresentation of Critical Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A04:2021 - Insecure Design + references: + - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + subcategory: + - vuln + technology: + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.set($HEADER, ...) + - pattern: $RES.header($HEADER, ...) + - pattern: $RES.setHeader($HEADER, ...) + - pattern: | + $RES.set({$HEADER: ...}, ...) + - pattern: | + $RES.writeHead($STATUS, {$HEADER: ...}, ...) + - metavariable-regex: + metavariable: $HEADER + regex: .*(X-Frame-Options|x-frame-options).* + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.fbjs.security.audit.insecure-createnodesfrommarkup.insecure-createnodesfrommarkup + languages: + - javascript + - typescript + message: User controlled data in a `createNodesFromMarkup` is an anti-pattern that can lead to XSS vulnerabilities + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - fbjs + patterns: + - pattern-either: + - pattern: createNodesFromMarkup(...) + - pattern: $X.createNodesFromMarkup(...) + - pattern-not: createNodesFromMarkup("...",...) + - pattern-not: $X.createNodesFromMarkup("...",...) + severity: WARNING + - id: javascript.grpc.security.grpc-nodejs-insecure-connection.grpc-nodejs-insecure-connection + languages: + - javascript + - typescript + message: Found an insecure gRPC connection. This creates a connection without encryption to a gRPC client/server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://blog.gopheracademy.com/advent-2017/go-grpc-beyond-basics/#:~:text=disables%20transport%20security + subcategory: + - audit + technology: + - grpc + pattern-either: + - pattern: | + require('grpc'); + ... + $GRPC($ADDR,...,$CREDENTIALS.createInsecure(),...); + - pattern: | + require('grpc'); + ... + new $GRPC($ADDR,...,$CREDENTIALS.createInsecure(),...); + - pattern: |- + require('grpc'); + ... + $CREDS = <... $CREDENTIALS.createInsecure() ...>; + ... + $GRPC($ADDR,...,$CREDS,...); + - pattern: |- + require('grpc'); + ... + $CREDS = <... $CREDENTIALS.createInsecure() ...>; + ... + new $GRPC($ADDR,...,$CREDS,...); + severity: ERROR + - id: javascript.intercom.security.audit.intercom-settings-user-identifier-without-user-hash.intercom-settings-user-identifier-without-user-hash + languages: + - js + message: Found an initialization of the Intercom Messenger that identifies a User, but does not specify a `user_hash`.This configuration allows users to impersonate one another. See the Intercom Identity Verification docs for more context https://www.intercom.com/help/en/articles/183-set-up-identity-verification-for-web-and-mobile + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-287: Improper Authentication' + impact: HIGH + likelihood: MEDIUM + references: + - https://www.intercom.com/help/en/articles/183-set-up-identity-verification-for-web-and-mobile + subcategory: + - guardrail + technology: + - intercom + patterns: + - pattern-either: + - pattern: | + window.intercomSettings = {..., email: $EMAIL, ...}; + - pattern: | + window.intercomSettings = {..., user_id: $USER_ID, ...}; + - pattern: | + Intercom('boot', {..., email: $EMAIL, ...}); + - pattern: | + Intercom('boot', {..., user_id: $USER_ID, ...}); + - pattern: | + $VAR = {..., email: $EMAIL, ...}; + ... + Intercom('boot', $VAR); + - pattern: | + $VAR = {..., user_id: $EMAIL, ...}; + ... + Intercom('boot', $VAR); + - pattern-not: | + window.intercomSettings = {..., user_hash: $USER_HASH, ...}; + - pattern-not: | + Intercom('boot', {..., user_hash: $USER_HASH, ...}); + - pattern-not: | + $VAR = {..., user_hash: $USER_HASH, ...}; + ... + Intercom('boot', $VAR); + severity: WARNING + - id: javascript.jose.security.audit.jose-exposed-data.jose-exposed-data + languages: + - javascript + - typescript + message: The object is passed strictly to jose.JWT.sign(...) Make sure that sensitive information is not exposed through JWT token payload. + metadata: + asvs: + control_id: 3.5.2 Static API keys or secret + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jose + - jwt + patterns: + - pattern-inside: | + require('jose'); + ... + - pattern-either: + - patterns: + - pattern-inside: function (...,$INPUT,...) {...} + - pattern-either: + - pattern: $JOSE.JWT.sign($INPUT,...) + - pattern: $JWT.sign($INPUT,...) + - patterns: + - pattern-inside: function $F(...,$INPUT,...) {...} + - pattern-either: + - pattern: $JOSE.JWT.sign($INPUT,...) + - pattern: $JWT.sign($INPUT,...) + severity: WARNING + - id: javascript.jose.security.jwt-hardcode.hardcoded-jwt-secret + languages: + - javascript + - typescript + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + metadata: + asvs: + control_id: 3.5.2 Static API keys or secret + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + likelihood: HIGH + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + subcategory: + - vuln + technology: + - jose + - jwt + - secrets + options: + interfile: true + symbolic_propagation: true + patterns: + - pattern-inside: | + $JOSE = require("jose"); + ... + - pattern-either: + - pattern-inside: | + var {JWT} = $JOSE; + ... + - pattern-inside: | + var {JWK, JWT} = $JOSE; + ... + - pattern-inside: | + const {JWT} = $JOSE; + ... + - pattern-inside: | + const {JWK, JWT} = $JOSE; + ... + - pattern-inside: | + let {JWT} = $JOSE; + ... + - pattern-inside: | + let {JWK, JWT} = $JOSE; + ... + - pattern-either: + - pattern: | + JWT.verify($P, "...", ...); + - pattern: | + JWT.sign($P, "...", ...); + - pattern: "JWT.verify($P, JWK.asKey(\"...\"), ...); \n" + - pattern: | + $JWT.sign($P, JWK.asKey("..."), ...); + severity: WARNING + - id: javascript.jose.security.jwt-none-alg.jwt-none-alg + languages: + - javascript + - typescript + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + metadata: + asvs: + control_id: 3.5.3 Insecue Stateless Session Tokens + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - vuln + technology: + - jose + - jwt + pattern-either: + - pattern: | + var $JOSE = require("jose"); + ... + var { JWK, JWT } = $JOSE; + ... + var $T = JWT.verify($P, JWK.None,...); + - pattern: | + var $JOSE = require("jose"); + ... + var { JWK, JWT } = $JOSE; + ... + $T = JWT.verify($P, JWK.None,...); + - pattern: | + var $JOSE = require("jose"); + ... + var { JWK, JWT } = $JOSE; + ... + JWT.verify($P, JWK.None,...); + severity: ERROR + - id: javascript.jquery.security.audit.jquery-insecure-method.jquery-insecure-method + languages: + - javascript + - typescript + message: User controlled data in a jQuery's `.$METHOD(...)` is an anti-pattern that can lead to XSS vulnerabilities + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/xss/ + - https://bugs.jquery.com/ticket/9521 + subcategory: + - audit + technology: + - jquery + options: + symbolic_propagation: true + pattern-either: + - patterns: + - pattern-either: + - pattern: $.$METHOD($VAR,...) + - pattern: $(...).$METHOD($VAR,...) + - pattern: jQuery.$METHOD($VAR,...) + - pattern: jQuery(...).$METHOD($VAR,...) + - pattern-not: $.$METHOD("...",...) + - pattern-not: $(...).$METHOD("...",...) + - pattern-not: jQuery.$METHOD("...",...) + - pattern-not: jQuery(...).$METHOD("...",...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(html|append|prepend|wrap|wrapInner|wrapAll|before|after|globalEval|getScript)$ + - patterns: + - pattern-either: + - pattern: $(...).$METHOD($VAR,...) + - pattern: jQuery(...).$METHOD($VAR,...) + - pattern-not: $("...",...).$METHOD(...) + - pattern-not: jQuery("...",...).$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(appendTo|insertAfter|insertBefore|prependTo)$ + severity: WARNING + - id: javascript.jquery.security.audit.jquery-insecure-selector.jquery-insecure-selector + languages: + - javascript + - typescript + message: User controlled data in a `$(...)` is an anti-pattern that can lead to XSS vulnerabilities + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/xss/ + - https://bugs.jquery.com/ticket/9521 + subcategory: + - audit + technology: + - jquery + patterns: + - pattern-either: + - pattern: | + $(<... window ...>) + - pattern: | + $(<... location ...>) + - patterns: + - pattern: | + $X = <... window ...>; + ... + $(<... $X ...>); + - focus-metavariable: $X + - patterns: + - pattern: | + $X = <... location ...>; + ... + $(<... $X ...>); + - focus-metavariable: $X + - patterns: + - pattern-either: + - pattern-inside: | + function $FUNC(..., $Y, ...) { + ... + } + - pattern-inside: | + function (..., $Y, ...) { + ... + } + - pattern-inside: | + function $FUNC(...,$Z,...) { + ... + $Y = <... $Z ...>; + ... + } + - pattern-inside: | + function (...,$Z,...) { + ... + $Y = <... $Z ...>; + ... + } + - pattern-either: + - pattern: | + $(<... $Y ...>) + - pattern: | + $("..." + (<... $Y ...>)) + - pattern: | + $((<... $Y ...>) + "...") + - pattern-not-inside: | + $JQUERY.each(function($INDEX, $Y) { + ... + }) + - focus-metavariable: $Y + - pattern-not: | + $(window) + - pattern-not: | + $(document) + - pattern-not: | + $(this) + severity: WARNING + - id: javascript.jquery.security.audit.prohibit-jquery-html.prohibit-jquery-html + languages: + - javascript + - typescript + message: JQuery's `html` function is susceptible to Cross Site Scripting (XSS) attacks. If you're just passing text, consider `text` instead. Otherwise, use a function that escapes HTML such as edX's `HtmlUtils.setHtml()`. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + help: | + ## Remediation + Avoid using JQuery's html() function. If the string is plain text, use the text() function instead. + Otherwise, use a function that escapes html such as edx's HtmlUtils.setHtml(). + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + precision: high + references: + - https://edx.readthedocs.io/projects/edx-developer-guide/en/latest/preventing_xss/preventing_xss.html#javascript-concat-html + - https://stackoverflow.com/questions/8318581/html-vs-innerhtml-jquery-javascript-xss-attacks + - https://api.jquery.com/text/#text-text + shortDesription: Use of JQuery's unsafe html() function. + subcategory: + - audit + tags: + - security + technology: + - jquery + patterns: + - pattern: | + $X.html(...) + - pattern-not: | + $X.html("...",...) + severity: WARNING + - id: javascript.jsonwebtoken.security.audit.jwt-decode-without-verify.jwt-decode-without-verify + languages: + - javascript + - typescript + message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token. + metadata: + asvs: + control_id: 3.5.3 Insecue Stateless Session Tokens + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-345: Insufficient Verification of Data Authenticity' + impact: LOW + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + patterns: + - pattern-inside: | + $JWT = require('jsonwebtoken'); + ... + - pattern-not-inside: | + ... + $JWT.verify($TOKEN, ...) + ... + - pattern-not-inside: | + ... + if (<... $JWT.verify($TOKEN, ...) ...>) { ... } + ... + - pattern: $JWT.decode($TOKEN, ...) + severity: WARNING + - id: javascript.jsonwebtoken.security.audit.jwt-exposed-data.jwt-exposed-data + languages: + - javascript + - typescript + message: The object is passed strictly to jsonwebtoken.sign(...) Make sure that sensitive information is not exposed through JWT token payload. + metadata: + asvs: + control_id: 3.5.3 Insecue Stateless Session Tokens + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + patterns: + - pattern-inside: | + $JWT = require('jsonwebtoken'); + ... + - pattern-either: + - pattern-inside: function (...,$INPUT,...) {...} + - pattern-inside: function $F(...,$INPUT,...) {...} + - pattern: $JWT.sign($INPUT,...) + severity: WARNING + - id: javascript.jsonwebtoken.security.jwt-hardcode.hardcoded-jwt-secret + languages: + - javascript + - typescript + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + metadata: + asvs: + control_id: 3.5.2 Static API keys or secret + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + subcategory: + - vuln + technology: + - jwt + - javascript + - secrets + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $JWT = require("jsonwebtoken") + ... + - pattern-inside: | + import $JWT from "jsonwebtoken" + ... + - pattern-inside: | + import * as $JWT from "jsonwebtoken" + ... + - pattern-inside: | + import {...,$JWT,...} from "jsonwebtoken" + ... + - pattern-either: + - pattern-inside: | + $JWT.sign($DATA,$VALUE,...); + - pattern-inside: | + $JWT.verify($DATA,$VALUE,...); + - focus-metavariable: $VALUE + pattern-sources: + - patterns: + - pattern: "$X = '...' \n" + - pattern: "$X = '$Y' \n" + - patterns: + - pattern-either: + - pattern-inside: | + $JWT.sign($DATA,"...",...); + - pattern-inside: | + $JWT.verify($DATA,"...",...); + severity: WARNING + - id: javascript.jsonwebtoken.security.jwt-none-alg.jwt-none-alg + languages: + - javascript + - typescript + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + metadata: + asvs: + control_id: 3.5.3 Insecue Stateless Session Tokens + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - vuln + technology: + - jwt + patterns: + - pattern-inside: | + $JWT = require("jsonwebtoken"); + ... + - pattern: $JWT.verify($P, $X, {algorithms:[...,'none',...]},...) + severity: ERROR + - id: javascript.jwt-simple.security.jwt-simple-noverify.jwt-simple-noverify + languages: + - javascript + - typescript + message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Set 'verify' to `true` before using the token. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-287: Improper Authentication' + - 'CWE-345: Insufficient Verification of Data Authenticity' + - 'CWE-347: Improper Verification of Cryptographic Signature' + impact: HIGH + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + - A07:2021 - Identification and Authentication Failures + references: + - https://www.npmjs.com/package/jwt-simple + - https://cwe.mitre.org/data/definitions/287 + - https://cwe.mitre.org/data/definitions/345 + - https://cwe.mitre.org/data/definitions/347 + subcategory: + - vuln + technology: + - jwt-simple + - jwt + patterns: + - pattern-inside: | + $JWT = require('jwt-simple'); + ... + - pattern: $JWT.decode($TOKEN, $SECRET, $NOVERIFY, ...) + - metavariable-pattern: + metavariable: $NOVERIFY + patterns: + - pattern-either: + - pattern: | + true + - pattern: | + "..." + severity: ERROR + - id: javascript.lang.best-practice.assigned-undefined.assigned-undefined + languages: + - javascript + - typescript + message: '`undefined` is not a reserved keyword in Javascript, so this is "valid" Javascript but highly confusing and likely to result in bugs.' + metadata: + category: best-practice + technology: + - javascript + pattern-either: + - pattern: undefined = $X; + - pattern: var undefined = $X; + - pattern: let undefined = $X; + - pattern: const undefined = $X; + severity: WARNING + - id: javascript.lang.best-practice.lazy-load-module.lazy-load-module + languages: + - javascript + - typescript + message: Lazy loading can complicate code bundling if care is not taken, also `require`s are run synchronously by Node.js. If they are called from within a function, it may block other requests from being handled at a more critical time. The best practice is to `require` modules at the beginning of each file, before and outside of any functions. + metadata: + category: best-practice + references: + - https://nodesecroadmap.fyi/chapter-2/dynamism.html + - https://github.com/goldbergyoni/nodebestpractices#-38-require-modules-first-not-inside-functions + technology: + - javascript + patterns: + - pattern: require(...) + - pattern-inside: | + function $NAME(...) { + ... + } + severity: WARNING + - id: javascript.lang.best-practice.leftover_debugging.javascript-alert + languages: + - javascript + - typescript + message: found alert() call; should this be in production code? + metadata: + category: best-practice + technology: + - javascript + pattern-either: + - pattern: alert() + - pattern: alert($X) + severity: WARNING + - id: javascript.lang.best-practice.leftover_debugging.javascript-debugger + languages: + - javascript + - typescript + message: found debugger call; should this be in production code? + metadata: + category: best-practice + technology: + - javascript + pattern: debugger; + severity: WARNING + - id: javascript.lang.best-practice.leftover_debugging.javascript-confirm + languages: + - javascript + - typescript + message: found confirm() call; should this be in production code? + metadata: + category: best-practice + technology: + - javascript + pattern: confirm(...) + severity: WARNING + - id: javascript.lang.best-practice.leftover_debugging.javascript-prompt + languages: + - javascript + - typescript + message: found prompt() call; should this be in production code? + metadata: + category: best-practice + technology: + - javascript + pattern-either: + - pattern: prompt() + - pattern: prompt($X) + - pattern: prompt($X, $Y) + severity: WARNING + - id: javascript.lang.best-practice.zlib-async-loop.zlib-async-loop + languages: + - javascript + - typescript + message: Creating and using a large number of zlib objects simultaneously can cause significant memory fragmentation. It is strongly recommended that the results of compression operations be cached or made synchronous to avoid duplication of effort. + metadata: + category: best-practice + references: + - https://nodejs.org/api/zlib.html#zlib_threadpool_usage_and_performance_considerations + technology: + - javascript + patterns: + - pattern-either: + - pattern-inside: | + for (...) { + ... + } + - pattern-inside: | + while (...) { + ... + } + - pattern-inside: | + do { + ... + } while (...) + - pattern-inside: | + $SMTH.forEach(...) + - pattern-inside: | + $SMTH.map(...) + - pattern-inside: | + $SMTH.reduce(...) + - pattern-inside: | + $SMTH.reduceRight(...) + - pattern: zlib.$METHOD(...); + - metavariable-regex: + metavariable: $METHOD + regex: ^.+$(?; + severity: INFO + - id: javascript.lang.correctness.useless-eqeq.eqeq-is-bad + languages: + - javascript + - typescript + message: Detected a useless comparison operation `$X == $X` or `$X != $X`. This operation is always true. If testing for floating point NaN, use `math.isnan`, or `cmath.isnan` if the number is complex. + metadata: + category: correctness + technology: + - javascript + patterns: + - pattern-not-inside: assert(...) + - pattern-either: + - pattern: $X == $X + - pattern: $X != $X + - pattern-not: 1 == 1 + severity: INFO + - id: javascript.lang.security.audit.code-string-concat.code-string-concat + languages: + - javascript + - typescript + message: Found data from an Express or Next web request flowing to `eval`. If this data is user-controllable this can lead to execution of arbitrary system commands in the context of your application process. Avoid `eval` whenever possible. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: MEDIUM + interfile: true + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval + - https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback + - https://www.stackhawk.com/blog/nodejs-command-injection-examples-and-prevention/ + - https://ckarande.gitbooks.io/owasp-nodegoat-tutorial/content/tutorial/a1_-_server_side_js_injection.html + subcategory: + - vuln + technology: + - node.js + - Express + - Next.js + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern: | + eval(...) + pattern-sources: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + import { ...,$IMPORT,... } from 'next/router' + ... + - pattern-inside: | + import $IMPORT from 'next/router'; + ... + - pattern-either: + - patterns: + - pattern-inside: | + $ROUTER = $IMPORT() + ... + - pattern-either: + - pattern-inside: | + const { ...,$PROPS,... } = $ROUTER.query + ... + - pattern-inside: | + var { ...,$PROPS,... } = $ROUTER.query + ... + - pattern-inside: | + let { ...,$PROPS,... } = $ROUTER.query + ... + - focus-metavariable: $PROPS + - patterns: + - pattern-inside: | + $ROUTER = $IMPORT() + ... + - pattern: "$ROUTER.query.$VALUE \n" + - patterns: + - pattern: $IMPORT().query.$VALUE + severity: ERROR + - id: javascript.lang.security.audit.dangerous-spawn-shell.dangerous-spawn-shell + languages: + - javascript + - typescript + message: Detected non-literal calls to $EXEC(). This could lead to a command injection vulnerability. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#do-not-use-dangerous-functions + source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-child-process.js + subcategory: + - vuln + technology: + - javascript + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('child_process') + ... + - pattern-inside: | + import 'child_process' + ... + - pattern-either: + - pattern: spawn(...) + - pattern: spawnSync(...) + - pattern: $CP.spawn(...) + - pattern: $CP.spawnSync(...) + - pattern-either: + - pattern: | + $EXEC("=~/(sh|bash|ksh|csh|tcsh|zsh)/",["-c", $ARG, ...],...) + - patterns: + - pattern: $EXEC($CMD,["-c", $ARG, ...],...) + - pattern-inside: | + $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/" + ... + - pattern: | + $EXEC("=~/(sh|bash|ksh|csh|tcsh|zsh)/",[$ARG, ...],...) + - patterns: + - pattern: $EXEC($CMD,[$ARG, ...],...) + - pattern-inside: | + $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/" + ... + - focus-metavariable: $ARG + pattern-sources: + - patterns: + - pattern-inside: | + function ... (...,$FUNC,...) { + ... + } + - focus-metavariable: $FUNC + severity: ERROR + - id: javascript.lang.security.audit.detect-non-literal-fs-filename.detect-non-literal-fs-filename + languages: + - typescript + - javascript + message: Detected that function argument `$ARG` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are validated. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-fs-filename.js + subcategory: + - vuln + technology: + - typescript + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $FS = require('fs') + ... + - pattern-inside: | + $FS = require('fs/promises') + ... + - pattern-inside: | + import * as $FS from 'fs' + ... + - pattern-inside: | + import $FS from 'fs' + ... + - pattern-inside: | + import * as $FS from 'fs/promises' + ... + - pattern-inside: | + import $FS from 'fs/promises' + ... + - pattern-not: $FS. ... .$METHOD("...", ...) + - pattern-either: + - pattern: $FS. ... .access($FILE,...) + - pattern: $FS. ... .appendFile($FILE,...) + - pattern: $FS. ... .chmod($FILE,...) + - pattern: $FS. ... .chown($FILE,...) + - pattern: $FS. ... .close($FILE,...) + - pattern: $FS. ... .copyFile($FILE,...) + - pattern: $FS. ... .copyFile($SMTH, $FILE,...) + - pattern: $FS. ... .cp($FILE, ...) + - pattern: $FS. ... .cp($SMTH, $FILE, ...) + - pattern: $FS. ... .createReadStream($FILE,...) + - pattern: $FS. ... .createWriteStream($FILE,...) + - pattern: $FS. ... .exists($FILE, ...) + - pattern: $FS. ... .fchmod($FILE, ...) + - pattern: $FS. ... .fchown($FILE, ...) + - pattern: $FS. ... .fdatasync($FILE, ...) + - pattern: $FS. ... .fstat($FILE, ...) + - pattern: $FS. ... .fsync($FILE, ...) + - pattern: $FS. ... .ftruncate($FILE, ...) + - pattern: $FS. ... .futimes($FILE, ...) + - pattern: $FS. ... .lchmod($FILE, ...) + - pattern: $FS. ... .lchown($FILE, ...) + - pattern: $FS. ... .lutimes($FILE, ...) + - pattern: $FS. ... .link($FILE, ...) + - pattern: $FS. ... .link($SMTH, $FILE, ...) + - pattern: $FS. ... .lstat($FILE, ...) + - pattern: $FS. ... .mkdir($FILE, ...) + - pattern: $FS. ... .mkdtemp($FILE, ...) + - pattern: $FS. ... .open($FILE, ...) + - pattern: $FS. ... .opendir($FILE, ...) + - pattern: $FS. ... .read($FILE, ...) + - pattern: $FS. ... .read($FILE, ...) + - pattern: $FS. ... .readdir($FILE, ...) + - pattern: $FS. ... .readFile($FILE, ...) + - pattern: $FS. ... .readlink($FILE, ...) + - pattern: $FS. ... .readv($FILE, ...) + - pattern: $FS. ... .realpath($FILE, ...) + - pattern: $FS. ... .realpath.native($FILE, ...) + - pattern: $FS. ... .rename($FILE, ...) + - pattern: $FS. ... .rename($SMTH, $FILE, ...) + - pattern: $FS. ... .rmdir($FILE, ...) + - pattern: $FS. ... .rm($FILE, ...) + - pattern: $FS. ... .stat($FILE, ...) + - pattern: $FS. ... .symlink($SMTH, $FILE, ...) + - pattern: $FS. ... .symlink($FILE, ...) + - pattern: $FS. ... .truncate($FILE, ...) + - pattern: $FS. ... .unlink($FILE, ...) + - pattern: $FS. ... .unwatchFile($FILE, ...) + - pattern: $FS. ... .utimes($FILE, ...) + - pattern: $FS. ... .watch($FILE, ...) + - pattern: $FS. ... .watchFile($FILE, ...) + - pattern: $FS. ... .write($FILE, ...) + - pattern: $FS. ... .writeFile($FILE, ...) + - pattern: $FS. ... .writev($FILE, ...) + - pattern: $FS. ... .accessSync($FILE, ...) + - pattern: $FS. ... .appendFileSync($FILE, ...) + - pattern: $FS. ... .chmodSync($FILE, ...) + - pattern: $FS. ... .chownSync($FILE, ...) + - pattern: $FS. ... .closeSync($FILE, ...) + - pattern: $FS. ... .copyFileSync($FILE, ...) + - pattern: $FS. ... .copyFileSync($SMTH, $FILE, ...) + - pattern: $FS. ... .cpSync($FILE, ...) + - pattern: $FS. ... .cpSync($SMTH, $FILE, ...) + - pattern: $FS. ... .existsSync($FILE, ...) + - pattern: $FS. ... .fchmodSync($FILE, ...) + - pattern: $FS. ... .fchownSync($FILE, ...) + - pattern: $FS. ... .fdatasyncSync($FILE, ...) + - pattern: $FS. ... .fstatSync($FILE, ...) + - pattern: $FS. ... .fsyncSync($FILE, ...) + - pattern: $FS. ... .ftruncateSync($FILE, ...) + - pattern: $FS. ... .futimesSync($FILE, ...) + - pattern: $FS. ... .lchmodSync($FILE, ...) + - pattern: $FS. ... .lchownSync($FILE, ...) + - pattern: $FS. ... .lutimesSync($FILE, ...) + - pattern: $FS. ... .linkSync($FILE, ...) + - pattern: $FS. ... .linkSync($SMTH, $FILE, ...) + - pattern: $FS. ... .lstatSync($FILE, ...) + - pattern: $FS. ... .mkdirSync($FILE, ...) + - pattern: $FS. ... .mkdtempSync($FILE, ...) + - pattern: $FS. ... .opendirSync($FILE, ...) + - pattern: $FS. ... .openSync($FILE, ...) + - pattern: $FS. ... .readdirSync($FILE, ...) + - pattern: $FS. ... .readFileSync($FILE, ...) + - pattern: $FS. ... .readlinkSync($FILE, ...) + - pattern: $FS. ... .readSync($FILE, ...) + - pattern: $FS. ... .readSync($FILE, ...) + - pattern: $FS. ... .readvSync($FILE, ...) + - pattern: $FS. ... .realpathync($FILE, ...) + - pattern: $FS. ... .realpathSync.native($FILE, ...) + - pattern: $FS. ... .renameSync($FILE, ...) + - pattern: $FS. ... .renameSync($SMTH, $FILE, ...) + - pattern: $FS. ... .rmdirSync($FILE, ...) + - pattern: $FS. ... .rmSync($FILE, ...) + - pattern: $FS. ... .statSync($FILE, ...) + - pattern: $FS. ... .symlinkSync($FILE, ...) + - pattern: $FS. ... .symlinkSync($SMTH, $FILE, ...) + - pattern: $FS. ... .truncateSync($FILE, ...) + - pattern: $FS. ... .unlinkSync($FILE, ...) + - pattern: $FS. ... .utimesSync($FILE, ...) + - pattern: $FS. ... .writeFileSync($FILE, ...) + - pattern: $FS. ... .writeSync($FILE, ...) + - pattern: $FS. ... .writevSync($FILE, ...) + - focus-metavariable: $FILE + - patterns: + - pattern-either: + - pattern-inside: | + import 'fs' + ... + - pattern-inside: | + import 'fs/promises' + ... + - pattern-not: $METHOD("...", ...) + - pattern-either: + - pattern: access($FILE,...) + - pattern: appendFile($FILE,...) + - pattern: chmod($FILE,...) + - pattern: chown($FILE,...) + - pattern: close($FILE,...) + - pattern: copyFile($FILE,...) + - pattern: copyFile($SMTH, $FILE,...) + - pattern: cp($FILE, ...) + - pattern: cp($SMTH, $FILE, ...) + - pattern: createReadStream($FILE,...) + - pattern: createWriteStream($FILE,...) + - pattern: exists($FILE, ...) + - pattern: fchmod($FILE, ...) + - pattern: fchown($FILE, ...) + - pattern: fdatasync($FILE, ...) + - pattern: fstat($FILE, ...) + - pattern: fsync($FILE, ...) + - pattern: ftruncate($FILE, ...) + - pattern: futimes($FILE, ...) + - pattern: lchmod($FILE, ...) + - pattern: lchown($FILE, ...) + - pattern: lutimes($FILE, ...) + - pattern: link($FILE, ...) + - pattern: link($SMTH, $FILE, ...) + - pattern: lstat($FILE, ...) + - pattern: mkdir($FILE, ...) + - pattern: mkdtemp($FILE, ...) + - pattern: open($FILE, ...) + - pattern: opendir($FILE, ...) + - pattern: read($FILE, ...) + - pattern: read($FILE, ...) + - pattern: readdir($FILE, ...) + - pattern: readFile($FILE, ...) + - pattern: readlink($FILE, ...) + - pattern: readv($FILE, ...) + - pattern: realpath($FILE, ...) + - pattern: realpath.native($FILE, ...) + - pattern: rename($FILE, ...) + - pattern: rename($SMTH, $FILE, ...) + - pattern: rmdir($FILE, ...) + - pattern: rm($FILE, ...) + - pattern: stat($FILE, ...) + - pattern: symlink($SMTH, $FILE, ...) + - pattern: symlink($FILE, ...) + - pattern: truncate($FILE, ...) + - pattern: unlink($FILE, ...) + - pattern: unwatchFile($FILE, ...) + - pattern: utimes($FILE, ...) + - pattern: watch($FILE, ...) + - pattern: watchFile($FILE, ...) + - pattern: write($FILE, ...) + - pattern: writeFile($FILE, ...) + - pattern: writev($FILE, ...) + - pattern: accessSync($FILE, ...) + - pattern: appendFileSync($FILE, ...) + - pattern: chmodSync($FILE, ...) + - pattern: chownSync($FILE, ...) + - pattern: closeSync($FILE, ...) + - pattern: copyFileSync($FILE, ...) + - pattern: copyFileSync($SMTH, $FILE, ...) + - pattern: cpSync($FILE, ...) + - pattern: cpSync($SMTH, $FILE, ...) + - pattern: existsSync($FILE, ...) + - pattern: fchmodSync($FILE, ...) + - pattern: fchownSync($FILE, ...) + - pattern: fdatasyncSync($FILE, ...) + - pattern: fstatSync($FILE, ...) + - pattern: fsyncSync($FILE, ...) + - pattern: ftruncateSync($FILE, ...) + - pattern: futimesSync($FILE, ...) + - pattern: lchmodSync($FILE, ...) + - pattern: lchownSync($FILE, ...) + - pattern: lutimesSync($FILE, ...) + - pattern: linkSync($FILE, ...) + - pattern: linkSync($SMTH, $FILE, ...) + - pattern: lstatSync($FILE, ...) + - pattern: mkdirSync($FILE, ...) + - pattern: mkdtempSync($FILE, ...) + - pattern: opendirSync($FILE, ...) + - pattern: openSync($FILE, ...) + - pattern: readdirSync($FILE, ...) + - pattern: readFileSync($FILE, ...) + - pattern: readlinkSync($FILE, ...) + - pattern: readSync($FILE, ...) + - pattern: readSync($FILE, ...) + - pattern: readvSync($FILE, ...) + - pattern: realpathync($FILE, ...) + - pattern: realpathSync.native($FILE, ...) + - pattern: renameSync($FILE, ...) + - pattern: renameSync($SMTH, $FILE, ...) + - pattern: rmdirSync($FILE, ...) + - pattern: rmSync($FILE, ...) + - pattern: statSync($FILE, ...) + - pattern: symlinkSync($FILE, ...) + - pattern: symlinkSync($SMTH, $FILE, ...) + - pattern: truncateSync($FILE, ...) + - pattern: unlinkSync($FILE, ...) + - pattern: utimesSync($FILE, ...) + - pattern: writeFileSync($FILE, ...) + - pattern: writeSync($FILE, ...) + - pattern: writevSync($FILE, ...) + - focus-metavariable: $FILE + pattern-sources: + - patterns: + - pattern-inside: function ... (..., $ARG,...) {...} + - focus-metavariable: $ARG + severity: WARNING + - id: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp + languages: + - javascript + - typescript + message: RegExp() called with a `$ARG` function argument, this might allow an attacker to cause a Regular Expression Denial-of-Service (ReDoS) within your application as RegExP blocks the main thread. For this reason, it is recommended to use hardcoded regexes instead. If your regex is run on user-controlled input, consider performing input validation or use a regex checking/sanitization library such as https://www.npmjs.com/package/recheck to verify that the regex does not appear vulnerable to ReDoS. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-1333: Inefficient Regular Expression Complexity' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS + source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-regexp.js + subcategory: + - vuln + technology: + - javascript + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: new RegExp($ARG, ...) + - pattern: RegExp($ARG, ...) + - pattern-not: RegExp("...", ...) + - pattern-not: new RegExp("...", ...) + - pattern-not: RegExp(/.../, ...) + - pattern-not: new RegExp(/.../, ...) + pattern-sources: + - patterns: + - pattern-inside: | + function ... (...,$ARG,...) {...} + - focus-metavariable: $ARG + severity: WARNING + - id: javascript.lang.security.audit.detect-non-literal-require.detect-non-literal-require + languages: + - javascript + - typescript + message: Detected the use of require(variable). Calling require with a non-literal argument might allow an attacker to load and run arbitrary code, or access arbitrary files. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-require.js + source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-require.js + subcategory: + - vuln + technology: + - javascript + mode: taint + pattern-sinks: + - pattern: require(...) + pattern-sources: + - patterns: + - pattern-inside: function ... (..., $ARG,...) {...} + - focus-metavariable: $ARG + severity: WARNING + - id: javascript.lang.security.audit.detect-redos.detect-redos + languages: + - javascript + - typescript + message: Detected the use of a regular expression `$REDOS` which appears to be vulnerable to a Regular expression Denial-of-Service (ReDoS). For this reason, it is recommended to review the regex and ensure it is not vulnerable to catastrophic backtracking, and if possible use a library which offers default safety against ReDoS vulnerabilities. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-1333: Inefficient Regular Expression Complexity' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS + - https://www.regular-expressions.info/redos.html + subcategory: + - vuln + technology: + - javascript + patterns: + - pattern-either: + - pattern: | + new RegExp(/$REDOS/,...) + - pattern: | + new RegExp("$REDOS",...) + - pattern: | + /$REDOS/.test(...) + - pattern: | + "$REDOS".test(...) + - pattern: | + $X.match(/$REDOS/) + - pattern: | + $X.match("$REDOS") + - metavariable-analysis: + analyzer: redos + metavariable: $REDOS + severity: WARNING + - id: javascript.lang.security.audit.hardcoded-hmac-key.hardcoded-hmac-key + languages: + - javascript + - typescript + message: Detected a hardcoded hmac key. Avoid hardcoding secrets and consider using an alternate option such as reading the secret from a config file or using an environment variable. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + interfile: true + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://rules.sonarsource.com/javascript/RSPEC-2068 + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#key-management + subcategory: + - audit + technology: + - crypto + - hmac + options: + interfile: true + pattern-either: + - pattern: $CRYPTO.createHmac($ALGO, '...') + - patterns: + - pattern-inside: | + const $SECRET = '...' + ... + - pattern: $CRYPTO.createHmac($ALGO, $SECRET) + severity: WARNING + - id: javascript.lang.security.audit.incomplete-sanitization.incomplete-sanitization + languages: + - javascript + - typescript + message: '`$STR.replace` method will only replace the first occurrence when used with a string argument ($CHAR). If this method is used for escaping of dangerous data then there is a possibility for a bypass. Try to use sanitization library instead or use a Regex with a global flag.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-116: Improper Encoding or Escaping of Output' + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - javascript + patterns: + - pattern: | + $STR.replace(($CHAR: string), ...) + - metavariable-regex: + metavariable: $CHAR + regex: ^[\"\']([\'\"\<\>\*\|\{\}\[\]\%\$]{1}|\\n|\\r|\\t|\\&)[\"\']$ + severity: WARNING + - id: javascript.lang.security.audit.md5-used-as-password.md5-used-as-password + languages: + - javascript + message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as bcrypt. You can use the `bcrypt` node.js package. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html + - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords + - https://github.com/returntocorp/semgrep-rules/issues/1609 + - https://www.npmjs.com/package/bcrypt + subcategory: + - vuln + technology: + - crypto + - md5 + mode: taint + pattern-sinks: + - patterns: + - pattern: $FUNCTION(...); + - metavariable-regex: + metavariable: $FUNCTION + regex: (?i)(.*password.*) + pattern-sources: + - pattern: $CRYPTO.createHash("md5") + severity: WARNING + - id: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal + languages: + - javascript + - typescript + message: Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to sanitize or validate user input first. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + subcategory: + - vuln + technology: + - javascript + - node.js + mode: taint + pattern-sanitizers: + - pattern: $Y.replace(...) + - pattern: $Y.indexOf(...) + - pattern: | + function ... (...) { + ... + <... $Y.indexOf(...) ...> + ... + } + - patterns: + - pattern: $FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: sanitize + pattern-sinks: + - patterns: + - focus-metavariable: $SINK + - pattern-either: + - pattern-inside: | + $PATH = require('path'); + ... + - pattern-inside: | + import $PATH from 'path'; + ... + - pattern-either: + - pattern: $PATH.join(...,$SINK,...) + - pattern: $PATH.resolve(...,$SINK,...) + - patterns: + - focus-metavariable: $SINK + - pattern-inside: | + import 'path'; + ... + - pattern-either: + - pattern-inside: path.join(...,$SINK,...) + - pattern-inside: path.resolve(...,$SINK,...) + pattern-sources: + - patterns: + - focus-metavariable: $X + - pattern-either: + - pattern-inside: | + function ... (...,$X,...) {...} + - pattern-inside: | + function ... (...,{...,$X,...},...) {...} + severity: WARNING + - id: javascript.lang.security.audit.prototype-pollution.prototype-pollution-assignment.prototype-pollution-assignment + languages: + - javascript + - typescript + message: 'Possibility of prototype polluting assignment detected. By adding or modifying attributes of an object prototype, it is possible to create attributes that exist on every object, or replace critical attributes with malicious ones. This can be problematic if the software depends on existence or non-existence of certain attributes, or uses pre-defined attributes of object prototype (such as hasOwnProperty, toString or valueOf). Possible mitigations might be: freezing the object prototype, using an object without prototypes (via Object.create(null) ), blocking modifications of attributes that resolve to object prototype, using Map instead of object.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: LOW + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf + subcategory: + - audit + technology: + - javascript + patterns: + - pattern: | + $X[$B] = ... + - pattern-not: | + $X[$B] = '...' + - pattern-inside: | + $X = $SMTH[$A] + ... + - pattern-not-inside: | + if (<...'constructor' ...>) { + ... + } + ... + - pattern-not-inside: | + if (<...'__proto__' ...>) { + ... + } + ... + - pattern-not-inside: | + for(var $B = $S; ...; ...) {...} + - pattern-not-inside: | + for($B = $S; ...; ...) {...} + - pattern-not-inside: | + $X.forEach(function $NAME($OBJ, $B,...) {...}) + - metavariable-pattern: + metavariable: $A + patterns: + - pattern-not: '"..."' + - pattern-not: | + `...${...}...` + - pattern-not: | + ($A: float) + - metavariable-pattern: + metavariable: $B + patterns: + - pattern-not: '"..."' + - pattern-not: | + `...${...}...` + - pattern-not: | + ($B: float) + severity: WARNING + - id: javascript.lang.security.audit.prototype-pollution.prototype-pollution-loop.prototype-pollution-loop + languages: + - typescript + - javascript + message: 'Possibility of prototype polluting function detected. By adding or modifying attributes of an object prototype, it is possible to create attributes that exist on every object, or replace critical attributes with malicious ones. This can be problematic if the software depends on existence or non-existence of certain attributes, or uses pre-defined attributes of object prototype (such as hasOwnProperty, toString or valueOf). Possible mitigations might be: freezing the object prototype, using an object without prototypes (via Object.create(null) ), blocking modifications of attributes that resolve to object prototype, using Map instead of object.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: LOW + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf + subcategory: + - audit + technology: + - typescript + patterns: + - pattern-either: + - pattern: | + $SMTH = $SMTH[$A] + - pattern: | + $SMTH = $SMTH[$A] = ... + - pattern: | + $SMTH = $SMTH[$A] && $Z + - pattern: | + $SMTH = $SMTH[$A] || $Z + - pattern-either: + - pattern-inside: | + for(...) { + ... + } + - pattern-inside: | + while(...) { + ... + } + - pattern-inside: | + $X.forEach(function $NAME(...) { + ... + }) + - pattern-not-inside: | + for(var $A = $S; ...; ...) {...} + - pattern-not-inside: | + for($A = $S; ...; ...) {...} + - pattern-not-inside: | + $X.forEach(function $NAME($OBJ, $A,...) {...}) + - metavariable-pattern: + metavariable: $A + patterns: + - pattern-not: '"..."' + - pattern-not: | + `...${...}...` + - pattern-not: | + ($A: float) + severity: WARNING + - id: javascript.lang.security.audit.spawn-shell-true.spawn-shell-true + languages: + - javascript + - typescript + message: 'Found ''$SPAWN'' with ''{shell: $SHELL}''. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use ''{shell: false}'' instead.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - javascript + patterns: + - pattern-either: + - pattern: | + spawn(...,{shell: $SHELL}) + - pattern: | + spawnSync(...,{shell: $SHELL}) + - pattern: | + $CP.spawn(...,{shell: $SHELL}) + - pattern: | + $CP.spawnSync(...,{shell: $SHELL}) + - pattern-not: | + spawn(...,{shell: false}) + - pattern-not: | + spawnSync(...,{shell: false}) + - pattern-not: | + $CP.spawn(...,{shell: false}) + - pattern-not: | + $CP.spawnSync(...,{shell: false}) + severity: ERROR + - id: javascript.lang.security.audit.sqli.node-knex-sqli.node-knex-sqli + languages: + - javascript + - typescript + message: 'Detected SQL statement that is tainted by `$REQ` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements. An example of parameterized queries like so: `knex.raw(''SELECT $1 from table'', [userinput])` can help prevent SQLi.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://knexjs.org/#Builder-fromRaw + - https://knexjs.org/#Builder-whereRaw + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - express + - nodejs + - knex + mode: taint + pattern-sanitizers: + - patterns: + - pattern: parseInt(...) + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern-inside: $KNEX.fromRaw($QUERY, ...) + - pattern-inside: $KNEX.whereRaw($QUERY, ...) + - pattern-inside: $KNEX.raw($QUERY, ...) + - pattern-either: + - pattern-inside: | + require('knex') + ... + - pattern-inside: | + import 'knex' + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options) + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - pattern: $REQ.files.$ANYTHING.data.toString('utf8') + - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - pattern: files.$ANYTHING.data.toString('utf8') + - pattern: files.$ANYTHING['data'].toString('utf8') + severity: WARNING + - id: javascript.lang.security.audit.sqli.node-mssql-sqli.node-mssql-sqli + languages: + - javascript + - typescript + message: 'Detected string concatenation with a non-literal variable in a `mssql` JS SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `$REQ.input(''USER_ID'', mssql.Int, id);`' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://www.npmjs.com/package/mssql + subcategory: + - vuln + technology: + - mssql + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('mssql'); + ... + - pattern-inside: | + import 'mssql'; + ... + - pattern-inside: | + $REQ = $POOL.request(...) + ... + - pattern: | + $REQ.query($QUERY,...) + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-inside: | + function ... (...,$FUNC,...) { + ... + } + - focus-metavariable: $FUNC + severity: WARNING + - id: javascript.lang.security.audit.sqli.node-mysql-sqli.node-mysql-sqli + languages: + - javascript + - typescript + message: Detected a `$IMPORT` SQL statement that comes from a function argument. This could lead to SQL injection if the variable is user-controlled and is not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://www.npmjs.com/package/mysql2 + - https://www.npmjs.com/package/mysql + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - mysql + - mysql2 + - javascript + - nodejs + mode: taint + pattern-sanitizers: + - patterns: + - pattern: parseInt(...) + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern-inside: $POOL.query($QUERY, ...) + - pattern-inside: $POOL.execute($QUERY, ...) + - pattern-either: + - pattern-inside: | + import $S from "$IMPORT" + ... + - pattern-inside: | + import { ... } from "$IMPORT" + ... + - pattern-inside: | + import * as $S from "$IMPORT" + ... + - pattern-inside: | + require("$IMPORT") + ... + - metavariable-regex: + metavariable: $IMPORT + regex: (mysql|mysql2) + pattern-sources: + - patterns: + - pattern-inside: function ... (..., $Y,...) {...} + - pattern: $Y + - pattern-not-inside: | + function ... (..., $Y: number,...) {...} + - pattern-not-inside: $Y.query + - pattern-not-inside: $Y.body + - pattern-not-inside: $Y.params + - pattern-not-inside: $Y.cookies + - pattern-not-inside: $Y.headers + severity: WARNING + - id: javascript.lang.security.audit.sqli.node-postgres-sqli.node-postgres-sqli + languages: + - javascript + - typescript + message: 'Detected string concatenation with a non-literal variable in a node-postgres JS SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `client.query(''SELECT $1 from table'', [userinput])`' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://node-postgres.com/features/queries + subcategory: + - vuln + technology: + - node-postgres + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + const { $CLIENT } = require('pg') + ... + - pattern-inside: | + var { $CLIENT } = require('pg') + ... + - pattern-inside: | + let { $CLIENT } = require('pg') + ... + - pattern-either: + - pattern-inside: | + $DB = new $CLIENT(...) + ... + - pattern-inside: | + $NEWPOOL = new $CLIENT(...) + ... + $NEWPOOL.connect((..., $DB, ...) => { + ... + }) + - pattern: $DB.query($QUERY,...) + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-inside: | + function ... (...,$FUNC,...) { + ... + } + - focus-metavariable: $FUNC + - pattern-not-inside: | + $F. ... .$SOURCE(...) + severity: WARNING + - id: javascript.lang.security.audit.unknown-value-with-script-tag.unknown-value-with-script-tag + languages: + - javascript + - typescript + message: Cannot determine what '$UNK' is and it is used with a ' + - pattern: '{{ ... }}' + - pattern-not-inside: nonce = '...' + - pattern-not-inside: nonce = "..." + severity: ERROR + - id: python.django.security.django-no-csrf-token.django-no-csrf-token + languages: + - generic + message: Manually-created forms in django templates should specify a csrf_token to prevent CSRF attacks + metadata: + category: security + confidence: MEDIUM + cwe: 'CWE-352: Cross-Site Request Forgery (CSRF)' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://docs.djangoproject.com/en/4.2/howto/csrf/ + subcategory: + - guardrail + technology: + - django + paths: + include: + - '*.html' + patterns: + - pattern: ... + - pattern-either: + - pattern: | +
...
+ - pattern: | +
...
+ - pattern: | +
...
+ - metavariable-regex: + metavariable: $METHOD + regex: (?i)(post|put|delete|patch) + - pattern-not-inside: ...{% csrf_token %}... + - pattern-not-inside: ...{{ $VAR.csrf_token }}... + severity: WARNING + - id: python.django.security.django-using-request-post-after-is-valid.django-using-request-post-after-is-valid + languages: + - python + message: Use $FORM.cleaned_data[] instead of request.POST[] after form.is_valid() has been executed to only access sanitized data + metadata: + category: security + confidence: MEDIUM + cwe: 'CWE-20: Improper Input Validation' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://docs.djangoproject.com/en/4.2/ref/forms/api/#accessing-clean-data + subcategory: + - guardrail + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-inside: | + if $FORM.is_valid(): + ... + - pattern-either: + - pattern: request.POST[...] + - pattern: request.POST.get(...) + severity: WARNING + - id: python.django.security.globals-as-template-context.globals-as-template-context + languages: + - python + message: 'Using ''globals()'' as a context to ''render(...)'' is extremely dangerous. This exposes Python functions to the template that were not meant to be exposed. An attacker could use these functions to execute code that was not intended to run and could compromise the application. (This is server-side template injection (SSTI)). Do not use ''globals()''. Instead, specify each variable in a dictionary or ''django.template.Context'' object, like ''{"var1": "hello"}'' and use that instead.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://docs.djangoproject.com/en/3.2/ref/settings/#templates + - https://docs.djangoproject.com/en/3.2/topics/templates/#django.template.backends.django.DjangoTemplates + - https://docs.djangoproject.com/en/3.2/ref/templates/api/#rendering-a-context + subcategory: + - audit + technology: + - django + pattern-either: + - pattern: django.shortcuts.render(..., globals(...), ...) + - pattern: django.template.Template.render(..., globals(...), ...) + - patterns: + - pattern-inside: | + $CONTEXT = globals(...) + ... + - pattern-either: + - pattern: django.shortcuts.render(..., $CONTEXT, ...) + - pattern: django.template.Template.render(..., $CONTEXT, ...) + severity: ERROR + - id: python.django.security.hashids-with-django-secret.hashids-with-django-secret + languages: + - python + message: The Django 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 Django secret key can be obtained by attackers, through the HashIDs. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: HIGH + likelihood: LOW + owasp: + - A02:2021 – Cryptographic Failures + references: + - https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-SECRET_KEY + - http://carnage.github.io/2015/08/cryptanalysis-of-hashids + subcategory: + - vuln + technology: + - django + pattern-either: + - pattern: hashids.Hashids(..., salt=django.conf.settings.SECRET_KEY, ...) + - pattern: hashids.Hashids(django.conf.settings.SECRET_KEY, ...) + severity: ERROR + - id: python.django.security.injection.code.globals-misuse-code-execution.globals-misuse-code-execution + languages: + - python + message: Found request data as an index to 'globals()'. This is extremely dangerous because it allows an attacker to execute arbitrary code on the system. Refactor your code not to use 'globals()'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://github.com/mpirnat/lets-be-bad-guys/blob/d92768fb3ade32956abd53bd6bb06e19d634a084/badguys/vulnerable/views.py#L181-L186 + subcategory: + - audit + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = globals().get($DATA, ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = globals().get("..." % $DATA, ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = globals().get(f"...{$DATA}...", ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = globals().get("...".format(..., $DATA, ...), ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = globals()[$DATA] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = globals()["..." % $DATA] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = globals()[f"...{$DATA}..."] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = globals()["...".format(..., $DATA, ...)] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = globals().get($DATA, ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = globals().get("..." % $DATA, ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = globals().get(f"...{$DATA}...", ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = globals().get("...".format(..., $DATA, ...), ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = globals()[$DATA] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = globals()["..." % $DATA] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = globals()[f"...{$DATA}..."] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = globals()["...".format(..., $DATA, ...)] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = globals().get($DATA, ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = globals().get("..." % $DATA, ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = globals().get(f"...{$DATA}...", ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = globals().get("...".format(..., $DATA, ...), ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = globals()[$DATA] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = globals()["..." % $DATA] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = globals()[f"...{$DATA}..."] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = globals()["...".format(..., $DATA, ...)] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W + ... + $INTERM = globals().get($DATA, ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W + ... + $INTERM = globals().get("..." % $DATA, ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W + ... + $INTERM = globals().get(f"...{$DATA}...", ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W + ... + $INTERM = globals().get("...".format(..., $DATA, ...), ...) + ... + $INTERM(...) + - pattern: | + $DATA = request.$W + ... + $INTERM = globals()[$DATA] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W + ... + $INTERM = globals()["..." % $DATA] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W + ... + $INTERM = globals()[f"...{$DATA}..."] + ... + $INTERM(...) + - pattern: | + $DATA = request.$W + ... + $INTERM = globals()["...".format(..., $DATA, ...)] + ... + $INTERM(...) + severity: WARNING + - id: python.django.security.injection.code.user-eval-format-string.user-eval-format-string + languages: + - python + message: Found user data in a call to 'eval'. This is extremely dangerous because it can enable an attacker to execute remote code. See https://owasp.org/www-community/attacks/Code_Injection for more information. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $F(...): + ... + - pattern-either: + - pattern: eval(..., $STR % request.$W.get(...), ...) + - pattern: | + $V = request.$W.get(...) + ... + eval(..., $STR % $V, ...) + - pattern: | + $V = request.$W.get(...) + ... + $S = $STR % $V + ... + eval(..., $S, ...) + - pattern: eval(..., "..." % request.$W(...), ...) + - pattern: | + $V = request.$W(...) + ... + eval(..., $STR % $V, ...) + - pattern: | + $V = request.$W(...) + ... + $S = $STR % $V + ... + eval(..., $S, ...) + - pattern: eval(..., $STR % request.$W[...], ...) + - pattern: | + $V = request.$W[...] + ... + eval(..., $STR % $V, ...) + - pattern: | + $V = request.$W[...] + ... + $S = $STR % $V + ... + eval(..., $S, ...) + - pattern: eval(..., $STR.format(..., request.$W.get(...), ...), ...) + - pattern: | + $V = request.$W.get(...) + ... + eval(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W.get(...) + ... + $S = $STR.format(..., $V, ...) + ... + eval(..., $S, ...) + - pattern: eval(..., $STR.format(..., request.$W(...), ...), ...) + - pattern: | + $V = request.$W(...) + ... + eval(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W(...) + ... + $S = $STR.format(..., $V, ...) + ... + eval(..., $S, ...) + - pattern: eval(..., $STR.format(..., request.$W[...], ...), ...) + - pattern: | + $V = request.$W[...] + ... + eval(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W[...] + ... + $S = $STR.format(..., $V, ...) + ... + eval(..., $S, ...) + - pattern: | + $V = request.$W.get(...) + ... + eval(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W.get(...) + ... + $S = f"...{$V}..." + ... + eval(..., $S, ...) + - pattern: | + $V = request.$W(...) + ... + eval(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W(...) + ... + $S = f"...{$V}..." + ... + eval(..., $S, ...) + - pattern: | + $V = request.$W[...] + ... + eval(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W[...] + ... + $S = f"...{$V}..." + ... + eval(..., $S, ...) + severity: WARNING + - id: python.django.security.injection.code.user-eval.user-eval + languages: + - python + message: Found user data in a call to 'eval'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html + - https://owasp.org/www-community/attacks/Code_Injection + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $F(...): + ... + - pattern-either: + - pattern: eval(..., request.$W.get(...), ...) + - pattern: | + $V = request.$W.get(...) + ... + eval(..., $V, ...) + - pattern: eval(..., request.$W(...), ...) + - pattern: | + $V = request.$W(...) + ... + eval(..., $V, ...) + - pattern: eval(..., request.$W[...], ...) + - pattern: | + $V = request.$W[...] + ... + eval(..., $V, ...) + severity: WARNING + - id: python.django.security.injection.code.user-exec-format-string.user-exec-format-string + languages: + - python + message: Found user data in a call to 'exec'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/Code_Injection + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $F(...): + ... + - pattern-either: + - pattern: exec(..., $STR % request.$W.get(...), ...) + - pattern: | + $V = request.$W.get(...) + ... + exec(..., $STR % $V, ...) + - pattern: | + $V = request.$W.get(...) + ... + $S = $STR % $V + ... + exec(..., $S, ...) + - pattern: exec(..., "..." % request.$W(...), ...) + - pattern: | + $V = request.$W(...) + ... + exec(..., $STR % $V, ...) + - pattern: | + $V = request.$W(...) + ... + $S = $STR % $V + ... + exec(..., $S, ...) + - pattern: exec(..., $STR % request.$W[...], ...) + - pattern: | + $V = request.$W[...] + ... + exec(..., $STR % $V, ...) + - pattern: | + $V = request.$W[...] + ... + $S = $STR % $V + ... + exec(..., $S, ...) + - pattern: exec(..., $STR.format(..., request.$W.get(...), ...), ...) + - pattern: | + $V = request.$W.get(...) + ... + exec(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W.get(...) + ... + $S = $STR.format(..., $V, ...) + ... + exec(..., $S, ...) + - pattern: exec(..., $STR.format(..., request.$W(...), ...), ...) + - pattern: | + $V = request.$W(...) + ... + exec(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W(...) + ... + $S = $STR.format(..., $V, ...) + ... + exec(..., $S, ...) + - pattern: exec(..., $STR.format(..., request.$W[...], ...), ...) + - pattern: | + $V = request.$W[...] + ... + exec(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W[...] + ... + $S = $STR.format(..., $V, ...) + ... + exec(..., $S, ...) + - pattern: | + $V = request.$W.get(...) + ... + exec(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W.get(...) + ... + $S = f"...{$V}..." + ... + exec(..., $S, ...) + - pattern: | + $V = request.$W(...) + ... + exec(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W(...) + ... + $S = f"...{$V}..." + ... + exec(..., $S, ...) + - pattern: | + $V = request.$W[...] + ... + exec(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W[...] + ... + $S = f"...{$V}..." + ... + exec(..., $S, ...) + - pattern: exec(..., base64.decodestring($S.format(..., request.$W.get(...), ...), ...), ...) + - pattern: exec(..., base64.decodestring($S % request.$W.get(...), ...), ...) + - pattern: exec(..., base64.decodestring(f"...{request.$W.get(...)}...", ...), ...) + - pattern: exec(..., base64.decodestring(request.$W.get(...), ...), ...) + - pattern: exec(..., base64.decodestring(bytes($S.format(..., request.$W.get(...), ...), ...), ...), ...) + - pattern: exec(..., base64.decodestring(bytes($S % request.$W.get(...), ...), ...), ...) + - pattern: exec(..., base64.decodestring(bytes(f"...{request.$W.get(...)}...", ...), ...), ...) + - pattern: exec(..., base64.decodestring(bytes(request.$W.get(...), ...), ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + exec(..., base64.decodestring($DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = base64.decodestring($DATA, ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = base64.decodestring(bytes($DATA, ...), ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + exec(..., base64.decodestring($DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = base64.decodestring($DATA, ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = base64.decodestring(bytes($DATA, ...), ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + exec(..., base64.decodestring($DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = base64.decodestring($DATA, ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = base64.decodestring(bytes($DATA, ...), ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + exec(..., base64.decodestring($DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = base64.decodestring($DATA, ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = base64.decodestring(bytes($DATA, ...), ...) + ... + exec(..., $INTERM, ...) + severity: WARNING + - id: python.django.security.injection.code.user-exec.user-exec + languages: + - python + message: Found user data in a call to 'exec'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/Code_Injection + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $F(...): + ... + - pattern-either: + - pattern: exec(..., request.$W.get(...), ...) + - pattern: | + $V = request.$W.get(...) + ... + exec(..., $V, ...) + - pattern: exec(..., request.$W(...), ...) + - pattern: | + $V = request.$W(...) + ... + exec(..., $V, ...) + - pattern: exec(..., request.$W[...], ...) + - pattern: | + $V = request.$W[...] + ... + exec(..., $V, ...) + - pattern: | + loop = asyncio.get_running_loop() + ... + await loop.run_in_executor(None, exec, request.$W[...]) + - pattern: | + $V = request.$W[...] + ... + loop = asyncio.get_running_loop() + ... + await loop.run_in_executor(None, exec, $V) + - pattern: | + loop = asyncio.get_running_loop() + ... + await loop.run_in_executor(None, exec, request.$W.get(...)) + - pattern: | + $V = request.$W.get(...) + ... + loop = asyncio.get_running_loop() + ... + await loop.run_in_executor(None, exec, $V) + severity: WARNING + - id: python.django.security.injection.command.command-injection-os-system.command-injection-os-system + languages: + - python + message: Request data detected in os.system. This could be vulnerable to a command injection and should be avoided. If this must be done, use the 'subprocess' module instead and pass the arguments as a list. See https://owasp.org/www-community/attacks/Command_Injection for more information. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/Command_Injection + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: os.system(..., request.$W.get(...), ...) + - pattern: os.system(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: os.system(..., $S % request.$W.get(...), ...) + - pattern: os.system(..., f"...{request.$W.get(...)}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + os.system(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + os.system(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + os.system(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + os.system(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + os.system(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + os.system(..., $INTERM, ...) + - pattern: $A = os.system(..., request.$W.get(...), ...) + - pattern: $A = os.system(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $A = os.system(..., $S % request.$W.get(...), ...) + - pattern: $A = os.system(..., f"...{request.$W.get(...)}...", ...) + - pattern: return os.system(..., request.$W.get(...), ...) + - pattern: return os.system(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: return os.system(..., $S % request.$W.get(...), ...) + - pattern: return os.system(..., f"...{request.$W.get(...)}...", ...) + - pattern: os.system(..., request.$W(...), ...) + - pattern: os.system(..., $S.format(..., request.$W(...), ...), ...) + - pattern: os.system(..., $S % request.$W(...), ...) + - pattern: os.system(..., f"...{request.$W(...)}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + os.system(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + os.system(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + os.system(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + os.system(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + os.system(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + os.system(..., $INTERM, ...) + - pattern: $A = os.system(..., request.$W(...), ...) + - pattern: $A = os.system(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $A = os.system(..., $S % request.$W(...), ...) + - pattern: $A = os.system(..., f"...{request.$W(...)}...", ...) + - pattern: return os.system(..., request.$W(...), ...) + - pattern: return os.system(..., $S.format(..., request.$W(...), ...), ...) + - pattern: return os.system(..., $S % request.$W(...), ...) + - pattern: return os.system(..., f"...{request.$W(...)}...", ...) + - pattern: os.system(..., request.$W[...], ...) + - pattern: os.system(..., $S.format(..., request.$W[...], ...), ...) + - pattern: os.system(..., $S % request.$W[...], ...) + - pattern: os.system(..., f"...{request.$W[...]}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + os.system(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + os.system(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + os.system(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + os.system(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + os.system(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + os.system(..., $INTERM, ...) + - pattern: $A = os.system(..., request.$W[...], ...) + - pattern: $A = os.system(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $A = os.system(..., $S % request.$W[...], ...) + - pattern: $A = os.system(..., f"...{request.$W[...]}...", ...) + - pattern: return os.system(..., request.$W[...], ...) + - pattern: return os.system(..., $S.format(..., request.$W[...], ...), ...) + - pattern: return os.system(..., $S % request.$W[...], ...) + - pattern: return os.system(..., f"...{request.$W[...]}...", ...) + - pattern: os.system(..., request.$W, ...) + - pattern: os.system(..., $S.format(..., request.$W, ...), ...) + - pattern: os.system(..., $S % request.$W, ...) + - pattern: os.system(..., f"...{request.$W}...", ...) + - pattern: | + $DATA = request.$W + ... + os.system(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + os.system(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + os.system(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + os.system(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + os.system(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + os.system(..., $INTERM, ...) + - pattern: $A = os.system(..., request.$W, ...) + - pattern: $A = os.system(..., $S.format(..., request.$W, ...), ...) + - pattern: $A = os.system(..., $S % request.$W, ...) + - pattern: $A = os.system(..., f"...{request.$W}...", ...) + - pattern: return os.system(..., request.$W, ...) + - pattern: return os.system(..., $S.format(..., request.$W, ...), ...) + - pattern: return os.system(..., $S % request.$W, ...) + - pattern: return os.system(..., f"...{request.$W}...", ...) + severity: ERROR + - id: python.django.security.injection.command.subprocess-injection.subprocess-injection + languages: + - python + message: Detected user input entering a `subprocess` call unsafely. This could result in a command injection vulnerability. An attacker could use this vulnerability to execute arbitrary commands on the host, which allows them to download malware, scan sensitive data, or run any command they wish on the server. Do not let users choose the command to run. In general, prefer to use Python API versions of system commands. If you must use subprocess, use a dictionary to allowlist a set of commands. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - flask + mode: taint + options: + symbolic_propagation: true + pattern-sanitizers: + - patterns: + - pattern: $DICT[$KEY] + - focus-metavariable: $KEY + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: subprocess.$FUNC(...) + - pattern-not: subprocess.$FUNC("...", ...) + - pattern-not: subprocess.$FUNC(["...", ...], ...) + - pattern-not-inside: | + $CMD = ["...", ...] + ... + subprocess.$FUNC($CMD, ...) + - patterns: + - pattern: subprocess.$FUNC(["$SHELL", "-c", ...], ...) + - metavariable-regex: + metavariable: $SHELL + regex: ^(sh|bash|ksh|csh|tcsh|zsh)$ + - patterns: + - pattern: subprocess.$FUNC(["$INTERPRETER", ...], ...) + - metavariable-regex: + metavariable: $INTERPRETER + regex: ^(python|python\d)$ + pattern-sources: + - patterns: + - pattern-inside: | + def $FUNC(..., $REQUEST, ...): + ... + - focus-metavariable: $REQUEST + - metavariable-pattern: + metavariable: $REQUEST + patterns: + - pattern: request + - pattern-not-inside: request.build_absolute_uri + severity: ERROR + - id: python.django.security.injection.csv-writer-injection.csv-writer-injection + languages: + - python + message: Detected user input into a generated CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1236: Improper Neutralization of Formula Elements in a CSV File' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/raphaelm/defusedcsv + - https://owasp.org/www-community/attacks/CSV_Injection + - https://web.archive.org/web/20220516052229/https://www.contextis.com/us/blog/comma-separated-vulnerabilities + subcategory: + - vuln + technology: + - django + - python + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + $WRITER = csv.writer(...) + + ... + + $WRITER.$WRITE(...) + - pattern: $WRITER.$WRITE(...) + - metavariable-regex: + metavariable: $WRITE + regex: ^(writerow|writerows|writeheader)$ + pattern-sources: + - patterns: + - pattern-inside: | + def $FUNC(..., $REQUEST, ...): + ... + - focus-metavariable: $REQUEST + - metavariable-pattern: + metavariable: $REQUEST + patterns: + - pattern: request + - pattern-not-inside: request.build_absolute_uri + severity: ERROR + - id: python.django.security.injection.email.xss-html-email-body.xss-html-email-body + languages: + - python + message: Found request data in an EmailMessage that is set to use HTML. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component (''Injection'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://www.damonkohler.com/2008/12/email-injection.html + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + $EMAIL.content_subtype = "html" + ... + - pattern-either: + - pattern: django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.EmailMessage($SUBJ, $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) + - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) + - pattern: django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.EmailMessage($SUBJ, $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) + - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) + - pattern: django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.EmailMessage($SUBJ, $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) + - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) + - pattern: django.core.mail.EmailMessage($SUBJ, request.$W, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.EmailMessage($SUBJ, $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W, ...) + - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W, ...) + severity: WARNING + - id: python.django.security.injection.email.xss-send-mail-html-message.xss-send-mail-html-message + languages: + - python + message: Found request data in 'send_mail(...)' that uses 'html_message'. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component (''Injection'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://www.damonkohler.com/2008/12/email-injection.html + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.send_mail(..., html_message=$DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) + - pattern: return django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) + - pattern: django.core.mail.send_mail(..., html_message=request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.send_mail(..., html_message=$DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W(...), ...) + - pattern: return django.core.mail.send_mail(..., html_message=request.$W(...), ...) + - pattern: django.core.mail.send_mail(..., html_message=request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.send_mail(..., html_message=$DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W[...], ...) + - pattern: return django.core.mail.send_mail(..., html_message=request.$W[...], ...) + - pattern: django.core.mail.send_mail(..., html_message=request.$W, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.send_mail(..., html_message=$DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W, ...) + - pattern: return django.core.mail.send_mail(..., html_message=request.$W, ...) + severity: WARNING + - id: python.django.security.injection.mass-assignment.mass-assignment + languages: + - python + message: Mass assignment detected. This can result in assignment to model fields that are unintended and can be exploited by an attacker. Instead of using '**request.$W', assign each field you want to edit individually to prevent mass assignment. You can read more about mass assignment at https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + owaspapi: 'API6: Mass Assignment' + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html + subcategory: + - audit + technology: + - django + pattern-either: + - pattern: $MODEL.objects.create(**request.$W) + - pattern: | + $OBJ.update(**request.$W) + ... + $OBJ.save() + severity: WARNING + - id: python.django.security.injection.open-redirect.open-redirect + languages: + - python + message: Data from request ($DATA) is passed to redirect(). This is an open redirect and could be exploited. Ensure you are redirecting to safe URLs by using django.utils.http.is_safe_url(). See https://cwe.mitre.org/data/definitions/601.html for more information. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://www.djm.org.uk/posts/djangos-little-protections-word-redirect-dangers/ + - https://github.com/django/django/blob/d1b7bd030b1db111e1a3505b1fc029ab964382cc/django/utils/http.py#L231 + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-not-inside: | + def $FUNC(...): + ... + django.utils.http.is_safe_url(...) + ... + - pattern-not-inside: | + def $FUNC(...): + ... + if <... django.utils.http.is_safe_url(...) ...>: + ... + - pattern-not-inside: | + def $FUNC(...): + ... + django.utils.http.url_has_allowed_host_and_scheme(...) + ... + - pattern-not-inside: | + def $FUNC(...): + ... + if <... django.utils.http.url_has_allowed_host_and_scheme(...) ...>: + ... + - pattern-either: + - pattern: django.shortcuts.redirect(..., request.$W.get(...), ...) + - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: django.shortcuts.redirect(..., $S % request.$W.get(...), ...) + - pattern: django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.shortcuts.redirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.shortcuts.redirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.shortcuts.redirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.shortcuts.redirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: $A = django.shortcuts.redirect(..., request.$W.get(...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S % request.$W.get(...), ...) + - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: return django.shortcuts.redirect(..., request.$W.get(...), ...) + - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: return django.shortcuts.redirect(..., $S % request.$W.get(...), ...) + - pattern: return django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: django.shortcuts.redirect(..., request.$W(...), ...) + - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: django.shortcuts.redirect(..., $S % request.$W(...), ...) + - pattern: django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + django.shortcuts.redirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.shortcuts.redirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.shortcuts.redirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.shortcuts.redirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: $A = django.shortcuts.redirect(..., request.$W(...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S % request.$W(...), ...) + - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) + - pattern: return django.shortcuts.redirect(..., request.$W(...), ...) + - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: return django.shortcuts.redirect(..., $S % request.$W(...), ...) + - pattern: return django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) + - pattern: django.shortcuts.redirect(..., request.$W[...], ...) + - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: django.shortcuts.redirect(..., $S % request.$W[...], ...) + - pattern: django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + django.shortcuts.redirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.shortcuts.redirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.shortcuts.redirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.shortcuts.redirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: $A = django.shortcuts.redirect(..., request.$W[...], ...) + - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S % request.$W[...], ...) + - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) + - pattern: return django.shortcuts.redirect(..., request.$W[...], ...) + - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: return django.shortcuts.redirect(..., $S % request.$W[...], ...) + - pattern: return django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) + - pattern: django.shortcuts.redirect(..., request.$W, ...) + - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) + - pattern: django.shortcuts.redirect(..., $S % request.$W, ...) + - pattern: django.shortcuts.redirect(..., f"...{request.$W}...", ...) + - pattern: | + $DATA = request.$W + ... + django.shortcuts.redirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.shortcuts.redirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.shortcuts.redirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.shortcuts.redirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: $A = django.shortcuts.redirect(..., request.$W, ...) + - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S % request.$W, ...) + - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W}...", ...) + - pattern: return django.shortcuts.redirect(..., request.$W, ...) + - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) + - pattern: return django.shortcuts.redirect(..., $S % request.$W, ...) + - pattern: return django.shortcuts.redirect(..., f"...{request.$W}...", ...) + - pattern: django.http.HttpResponseRedirect(..., request.$W.get(...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) + - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseRedirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseRedirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseRedirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., request.$W.get(...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: return django.http.HttpResponseRedirect(..., request.$W.get(...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) + - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: django.http.HttpResponseRedirect(..., request.$W(...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) + - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseRedirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseRedirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseRedirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., request.$W(...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) + - pattern: return django.http.HttpResponseRedirect(..., request.$W(...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) + - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) + - pattern: django.http.HttpResponseRedirect(..., request.$W[...], ...) + - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) + - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseRedirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseRedirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseRedirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., request.$W[...], ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) + - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) + - pattern: return django.http.HttpResponseRedirect(..., request.$W[...], ...) + - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) + - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) + - pattern: django.http.HttpResponseRedirect(..., request.$W, ...) + - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S % request.$W, ...) + - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseRedirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseRedirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseRedirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., request.$W, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) + - pattern: return django.http.HttpResponseRedirect(..., request.$W, ...) + - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W, ...) + - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) + - metavariable-regex: + metavariable: $W + regex: (?!get_full_path) + severity: WARNING + - id: python.django.security.injection.path-traversal.path-traversal-file-name.path-traversal-file-name + languages: + - python + message: Data from request is passed to a file name `$FILE`. This is a path traversal vulnerability, which can lead to sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or the pathlib library. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $F(...): + ... + - pattern-not-inside: | + def $F(...): + ... + os.path.realpath(...) + ... + - pattern-not-inside: | + def $F(...): + ... + os.path.abspath(...) + ... + - pattern-either: + - pattern: | + $V = request.$W.get($X) + ... + $FILE % ($V) + - pattern: | + $V = request.$W[$X] + ... + $FILE % ($V) + - pattern: | + $V = request.$W($X) + ... + $FILE % ($V) + - pattern: | + $V = request.$W + ... + $FILE % ($V) + # match format use cases + - pattern: | + $V = request.$W.get($X) + ... + $FILE.format(..., $V, ...) + - pattern: | + $V = request.$W[$X] + ... + $FILE.format(..., $V, ...) + - pattern: | + $V = request.$W($X) + ... + $FILE.format(..., $V, ...) + - pattern: | + $V = request.$W + ... + $FILE.format(..., $V, ...) + - metavariable-regex: + metavariable: $FILE + regex: .*\.(log|zip|txt|csv|xml|html).* + severity: WARNING + - id: python.django.security.injection.path-traversal.path-traversal-join.path-traversal-join + languages: + - python + message: Data from request is passed to os.path.join() and to open(). This is a path traversal vulnerability, which can lead to sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or Path library. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + subcategory: + - audit + technology: + - django + patterns: + - pattern-inside: | + def $F(...): + ... + - pattern-not-inside: | + def $F(...): + ... + os.path.abspath(...) + ... + - pattern-not-inside: | + def $F(...): + ... + os.path.realpath(...) + ... + - pattern-either: + - pattern: open(os.path.join(..., request.$W.get(...), ...), ...) + - pattern: open(os.path.join(..., request.$W(...), ...), ...) + - pattern: open(os.path.join(..., request.$W, ...), ...) + - pattern: open(os.path.join(..., request.$W[...], ...), ...) + - pattern: | + $P = os.path.join(..., request.$W.get(...), ...) + ... + open($P, ...) + - pattern: | + $P = os.path.join(..., request.$W(...), ...) + ... + open($P, ...) + - pattern: | + $P = os.path.join(..., request.$W, ...) + ... + open($P, ...) + - pattern: | + $P = os.path.join(..., request.$W[...], ...) + ... + open($P, ...) + - pattern: | + $V = request.$W.get($X) + ... + $P = os.path.join(..., $V, ...) + ... + open($P, ...) + - pattern: | + $V = request.$W($X) + ... + $P = os.path.join(..., $V, ...) + ... + open($P, ...) + - pattern: | + $V = request.$W[$X] + ... + $P = os.path.join(..., $V, ...) + ... + open($P, ...) + - pattern: | + $V = request.$W + ... + $P = os.path.join(..., $V, ...) + ... + open($P, ...) + - pattern: | + $P = request.$W.get(...) + ... + open(os.path.join(..., $P, ...), ...) + - pattern: | + $P = request.$W(...) + ... + open(os.path.join(..., $P, ...), ...) + - pattern: | + $P = request.$W + ... + open(os.path.join(..., $P, ...), ...) + - pattern: | + $P = request.$W[...] + ... + open(os.path.join(..., $P, ...), ...) + severity: WARNING + - id: python.django.security.injection.path-traversal.path-traversal-open.path-traversal-open + languages: + - python + message: Found request data in a call to 'open'. Ensure the request data is validated or sanitized, otherwise it could result in path traversal attacks and therefore sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or the pathlib library. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: open(..., request.$W.get(...), ...) + - pattern: open(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: open(..., $S % request.$W.get(...), ...) + - pattern: open(..., f"...{request.$W.get(...)}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + open(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W.get(...) + ... + open(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W.get(...) + ... + open(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W.get(...) + ... + open(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W.get(...) + ... + open(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: $A = open(..., request.$W.get(...), ...) + - pattern: $A = open(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $A = open(..., $S % request.$W.get(...), ...) + - pattern: $A = open(..., f"...{request.$W.get(...)}...", ...) + - pattern: return open(..., request.$W.get(...), ...) + - pattern: return open(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: return open(..., $S % request.$W.get(...), ...) + - pattern: return open(..., f"...{request.$W.get(...)}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + with open(..., $DATA, ...) as $FD: + ... + - pattern: open(..., request.$W(...), ...) + - pattern: open(..., $S.format(..., request.$W(...), ...), ...) + - pattern: open(..., $S % request.$W(...), ...) + - pattern: open(..., f"...{request.$W(...)}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + open(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W(...) + ... + open(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W(...) + ... + open(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W(...) + ... + open(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W(...) + ... + open(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: $A = open(..., request.$W(...), ...) + - pattern: $A = open(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $A = open(..., $S % request.$W(...), ...) + - pattern: $A = open(..., f"...{request.$W(...)}...", ...) + - pattern: return open(..., request.$W(...), ...) + - pattern: return open(..., $S.format(..., request.$W(...), ...), ...) + - pattern: return open(..., $S % request.$W(...), ...) + - pattern: return open(..., f"...{request.$W(...)}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + with open(..., $DATA, ...) as $FD: + ... + - pattern: open(..., request.$W[...], ...) + - pattern: open(..., $S.format(..., request.$W[...], ...), ...) + - pattern: open(..., $S % request.$W[...], ...) + - pattern: open(..., f"...{request.$W[...]}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + open(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W[...] + ... + open(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W[...] + ... + open(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W[...] + ... + open(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W[...] + ... + open(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: $A = open(..., request.$W[...], ...) + - pattern: $A = open(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $A = open(..., $S % request.$W[...], ...) + - pattern: $A = open(..., f"...{request.$W[...]}...", ...) + - pattern: return open(..., request.$W[...], ...) + - pattern: return open(..., $S.format(..., request.$W[...], ...), ...) + - pattern: return open(..., $S % request.$W[...], ...) + - pattern: return open(..., f"...{request.$W[...]}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + with open(..., $DATA, ...) as $FD: + ... + - pattern: open(..., request.$W, ...) + - pattern: open(..., $S.format(..., request.$W, ...), ...) + - pattern: open(..., $S % request.$W, ...) + - pattern: open(..., f"...{request.$W}...", ...) + - pattern: | + $DATA = request.$W + ... + open(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W + ... + open(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W + ... + open(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W + ... + open(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W + ... + open(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: $A = open(..., request.$W, ...) + - pattern: $A = open(..., $S.format(..., request.$W, ...), ...) + - pattern: $A = open(..., $S % request.$W, ...) + - pattern: $A = open(..., f"...{request.$W}...", ...) + - pattern: return open(..., request.$W, ...) + - pattern: return open(..., $S.format(..., request.$W, ...), ...) + - pattern: return open(..., $S % request.$W, ...) + - pattern: return open(..., f"...{request.$W}...", ...) + - pattern: | + $DATA = request.$W + ... + with open(..., $DATA, ...) as $FD: + ... + severity: WARNING + - id: python.django.security.injection.raw-html-format.raw-html-format + languages: + - python + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates (`django.shortcuts.render`) which will safely render HTML instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.djangoproject.com/en/3.2/topics/http/shortcuts/#render + - https://docs.djangoproject.com/en/3.2/topics/security/#cross-site-scripting-xss-protection + subcategory: + - vuln + technology: + - django + mode: taint + pattern-sanitizers: + - pattern: django.utils.html.escape(...) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: '"$HTMLSTR" % ...' + - pattern: '"$HTMLSTR".format(...)' + - pattern: '"$HTMLSTR" + ...' + - pattern: f"$HTMLSTR{...}..." + - patterns: + - pattern-inside: | + $HTML = "$HTMLSTR" + ... + - pattern-either: + - pattern: $HTML % ... + - pattern: $HTML.format(...) + - pattern: $HTML + ... + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... + pattern-sources: + - patterns: + - pattern: request.$ANYTHING + - pattern-not: request.build_absolute_uri + severity: WARNING + - id: python.django.security.injection.reflected-data-httpresponse.reflected-data-httpresponse + languages: + - python + message: Found user-controlled request data passed into HttpResponse. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: django.http.HttpResponse(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: django.http.HttpResponse(..., $S % request.$W.get(...), ...) + - pattern: django.http.HttpResponse(..., f"...{request.$W.get(...)}...", ...) + - pattern: django.http.HttpResponse(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponse(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponse(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponse(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponse(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponse(..., request.$W.get(...), ...) + - pattern: return django.http.HttpResponse(..., request.$W.get(...), ...) + - pattern: django.http.HttpResponse(..., $S.format(..., request.$W(...), ...), ...) + - pattern: django.http.HttpResponse(..., $S % request.$W(...), ...) + - pattern: django.http.HttpResponse(..., f"...{request.$W(...)}...", ...) + - pattern: django.http.HttpResponse(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponse(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponse(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponse(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponse(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponse(..., request.$W(...), ...) + - pattern: return django.http.HttpResponse(..., request.$W(...), ...) + - pattern: django.http.HttpResponse(..., $S.format(..., request.$W[...], ...), ...) + - pattern: django.http.HttpResponse(..., $S % request.$W[...], ...) + - pattern: django.http.HttpResponse(..., f"...{request.$W[...]}...", ...) + - pattern: django.http.HttpResponse(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponse(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponse(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponse(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponse(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponse(..., request.$W[...], ...) + - pattern: return django.http.HttpResponse(..., request.$W[...], ...) + - pattern: django.http.HttpResponse(..., $S.format(..., request.$W, ...), ...) + - pattern: django.http.HttpResponse(..., $S % request.$W, ...) + - pattern: django.http.HttpResponse(..., f"...{request.$W}...", ...) + - pattern: django.http.HttpResponse(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponse(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponse(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponse(..., f"...{$DATA}...", ...) + - pattern: $A = django.http.HttpResponse(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + $A = django.http.HttpResponse(..., $INTERM, ...) + - pattern: return django.http.HttpResponse(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponse(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + severity: WARNING + - id: python.django.security.injection.reflected-data-httpresponsebadrequest.reflected-data-httpresponsebadrequest + languages: + - python + message: Found user-controlled request data passed into a HttpResponseBadRequest. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W.get(...), ...) + - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W.get(...)}...", ...) + - pattern: django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseBadRequest(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) + - pattern: return django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W(...), ...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W(...), ...) + - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W(...)}...", ...) + - pattern: django.http.HttpResponseBadRequest(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseBadRequest(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W(...), ...) + - pattern: return django.http.HttpResponseBadRequest(..., request.$W(...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W[...], ...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W[...], ...) + - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W[...]}...", ...) + - pattern: django.http.HttpResponseBadRequest(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseBadRequest(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W[...], ...) + - pattern: return django.http.HttpResponseBadRequest(..., request.$W[...], ...) + - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W, ...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W, ...) + - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W}...", ...) + - pattern: django.http.HttpResponseBadRequest(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseBadRequest(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W, ...) + - pattern: return django.http.HttpResponseBadRequest(..., request.$W, ...) + severity: WARNING + - id: python.django.security.injection.request-data-fileresponse.request-data-fileresponse + languages: + - python + message: Found user-controlled request data being passed into a file open, which is them passed as an argument into the FileResponse. This is dangerous because an attacker could specify an arbitrary file to read, which could result in leaking important data. Be sure to validate or sanitize the user-inputted filename in the request data before using it in FileResponse. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: django.http.FileResponse(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.FileResponse(..., open($DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = open($DATA, ...) + ... + django.http.FileResponse(..., $INTERM, ...) + - pattern: $A = django.http.FileResponse(..., request.$W.get(...), ...) + - pattern: return django.http.FileResponse(..., request.$W.get(...), ...) + - pattern: django.http.FileResponse(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.FileResponse(..., open($DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = open($DATA, ...) + ... + django.http.FileResponse(..., $INTERM, ...) + - pattern: $A = django.http.FileResponse(..., request.$W(...), ...) + - pattern: return django.http.FileResponse(..., request.$W(...), ...) + - pattern: django.http.FileResponse(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.FileResponse(..., open($DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = open($DATA, ...) + ... + django.http.FileResponse(..., $INTERM, ...) + - pattern: $A = django.http.FileResponse(..., request.$W[...], ...) + - pattern: return django.http.FileResponse(..., request.$W[...], ...) + - pattern: django.http.FileResponse(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + django.http.FileResponse(..., open($DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = open($DATA, ...) + ... + django.http.FileResponse(..., $INTERM, ...) + - pattern: $A = django.http.FileResponse(..., request.$W, ...) + - pattern: return django.http.FileResponse(..., request.$W, ...) + severity: WARNING + - id: python.django.security.injection.request-data-write.request-data-write + languages: + - python + message: Found user-controlled request data passed into '.write(...)'. This could be dangerous if a malicious actor is able to control data into sensitive files. For example, a malicious actor could force rolling of critical log files, or cause a denial-of-service by using up available disk space. Instead, ensure that request data is properly escaped or sanitized. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-93: Improper Neutralization of CRLF Sequences (''CRLF Injection'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - django + pattern-either: + - pattern: $F.write(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $F.write(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $F.write(..., $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $F.write(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $F.write(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + $F.write(..., $INTERM, ...) + - pattern: $A = $F.write(..., request.$W.get(...), ...) + - pattern: return $F.write(..., request.$W.get(...), ...) + - pattern: $F.write(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $F.write(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $F.write(..., $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $F.write(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $F.write(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + $F.write(..., $INTERM, ...) + - pattern: $A = $F.write(..., request.$W(...), ...) + - pattern: return $F.write(..., request.$W(...), ...) + - pattern: $F.write(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $F.write(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $F.write(..., $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $F.write(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $F.write(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + $F.write(..., $INTERM, ...) + - pattern: $A = $F.write(..., request.$W[...], ...) + - pattern: return $F.write(..., request.$W[...], ...) + - pattern: $F.write(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + $F.write(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $F.write(..., $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $F.write(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $F.write(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + $F.write(..., $INTERM, ...) + - pattern: $A = $F.write(..., request.$W, ...) + - pattern: return $F.write(..., request.$W, ...) + severity: WARNING + - id: python.django.security.injection.sql.sql-injection-extra.sql-injection-using-extra-where + languages: + - python + message: User-controlled data from a request is passed to 'extra()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use parameterized queries or escape the user-controlled data by using `params` and not using quote placeholders in the SQL string. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.djangoproject.com/en/3.0/ref/models/expressions/#.objects.extra + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W.get(...), ...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W.get(...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W.get(...)}...", ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) + - pattern: return $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W(...), ...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W(...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W(...)}...", ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) + - pattern: return $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W[...], ...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W[...], ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W[...]}...", ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) + - pattern: return $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W, ...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W, ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W}...", ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) + - pattern: return $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + severity: WARNING + - id: python.django.security.injection.sql.sql-injection-rawsql.sql-injection-using-rawsql + languages: + - python + message: User-controlled data from request is passed to 'RawSQL()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use parameterized queries or escape the user-controlled data by using `params` and not using quote placeholders in the SQL string. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.djangoproject.com/en/3.0/ref/models/expressions/#django.db.models.expressions.RawSQL + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W.get(...), ...) + - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W.get(...)}...", ...) + - pattern: django.db.models.expressions.RawSQL(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.db.models.expressions.RawSQL(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W.get(...), ...) + - pattern: return django.db.models.expressions.RawSQL(..., request.$W.get(...), ...) + - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W(...), ...), ...) + - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W(...), ...) + - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W(...)}...", ...) + - pattern: django.db.models.expressions.RawSQL(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.db.models.expressions.RawSQL(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W(...), ...) + - pattern: return django.db.models.expressions.RawSQL(..., request.$W(...), ...) + - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W[...], ...), ...) + - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W[...], ...) + - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W[...]}...", ...) + - pattern: django.db.models.expressions.RawSQL(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + django.db.models.expressions.RawSQL(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W[...], ...) + - pattern: return django.db.models.expressions.RawSQL(..., request.$W[...], ...) + - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W, ...), ...) + - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W, ...) + - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W}...", ...) + - pattern: django.db.models.expressions.RawSQL(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + django.db.models.expressions.RawSQL(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + django.db.models.expressions.RawSQL(..., $INTERM, ...) + - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W, ...) + - pattern: return django.db.models.expressions.RawSQL(..., request.$W, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.db.models.expressions.RawSQL($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + django.db.models.expressions.RawSQL($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.db.models.expressions.RawSQL($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + django.db.models.expressions.RawSQL($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + django.db.models.expressions.RawSQL($INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + django.db.models.expressions.RawSQL($INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % (..., $DATA, ...) + ... + django.db.models.expressions.RawSQL($INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % (..., $DATA, ...) + ... + django.db.models.expressions.RawSQL($INTERM, ...) + severity: WARNING + - id: python.django.security.injection.sql.sql-injection-using-db-cursor-execute.sql-injection-db-cursor-execute + languages: + - python + message: User-controlled data from a request is passed to 'execute()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use django's QuerySets, which are built with query parameterization and therefore not vulnerable to sql injection. For example, you could use `Entry.objects.filter(date=2006)`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.djangoproject.com/en/3.0/topics/security/#sql-injection-protection + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: $CURSOR.execute(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $CURSOR.execute(..., $S % request.$W.get(...), ...) + - pattern: $CURSOR.execute(..., f"...{request.$W.get(...)}...", ...) + - pattern: $CURSOR.execute(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $CURSOR.execute(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $CURSOR.execute(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $CURSOR.execute(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $CURSOR.execute(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: $A = $CURSOR.execute(..., request.$W.get(...), ...) + - pattern: return $CURSOR.execute(..., request.$W.get(...), ...) + - pattern: $CURSOR.execute(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $CURSOR.execute(..., $S % request.$W(...), ...) + - pattern: $CURSOR.execute(..., f"...{request.$W(...)}...", ...) + - pattern: $CURSOR.execute(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $CURSOR.execute(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $CURSOR.execute(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $CURSOR.execute(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $CURSOR.execute(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: $A = $CURSOR.execute(..., request.$W(...), ...) + - pattern: return $CURSOR.execute(..., request.$W(...), ...) + - pattern: $CURSOR.execute(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $CURSOR.execute(..., $S % request.$W[...], ...) + - pattern: $CURSOR.execute(..., f"...{request.$W[...]}...", ...) + - pattern: $CURSOR.execute(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $CURSOR.execute(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $CURSOR.execute(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $CURSOR.execute(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $CURSOR.execute(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: $A = $CURSOR.execute(..., request.$W[...], ...) + - pattern: return $CURSOR.execute(..., request.$W[...], ...) + - pattern: $CURSOR.execute(..., $S.format(..., request.$W, ...), ...) + - pattern: $CURSOR.execute(..., $S % request.$W, ...) + - pattern: $CURSOR.execute(..., f"...{request.$W}...", ...) + - pattern: $CURSOR.execute(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + $CURSOR.execute(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $CURSOR.execute(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $CURSOR.execute(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $CURSOR.execute(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: $A = $CURSOR.execute(..., request.$W, ...) + - pattern: return $CURSOR.execute(..., request.$W, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $CURSOR.execute($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $CURSOR.execute($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $CURSOR.execute($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $CURSOR.execute($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $CURSOR.execute($INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $CURSOR.execute($INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $CURSOR.execute($INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $CURSOR.execute($INTERM, ...) + severity: WARNING + - id: python.django.security.injection.sql.sql-injection-using-raw.sql-injection-using-raw + languages: + - python + message: Data that is possible user-controlled from a python request is passed to `raw()`. This could lead to SQL injection and attackers gaining access to protected information. Instead, use django's QuerySets, which are built with query parameterization and therefore not vulnerable to sql injection. For example, you could use `Entry.objects.filter(date=2006)`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.djangoproject.com/en/3.0/topics/security/#sql-injection-protection + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $MODEL.objects.raw(..., $S % request.$W.get(...), ...) + - pattern: $MODEL.objects.raw(..., f"...{request.$W.get(...)}...", ...) + - pattern: $MODEL.objects.raw(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: $A = $MODEL.objects.raw(..., request.$W.get(...), ...) + - pattern: return $MODEL.objects.raw(..., request.$W.get(...), ...) + - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $MODEL.objects.raw(..., $S % request.$W(...), ...) + - pattern: $MODEL.objects.raw(..., f"...{request.$W(...)}...", ...) + - pattern: $MODEL.objects.raw(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.raw(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.raw(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.raw(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.raw(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: $A = $MODEL.objects.raw(..., request.$W(...), ...) + - pattern: return $MODEL.objects.raw(..., request.$W(...), ...) + - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $MODEL.objects.raw(..., $S % request.$W[...], ...) + - pattern: $MODEL.objects.raw(..., f"...{request.$W[...]}...", ...) + - pattern: $MODEL.objects.raw(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.raw(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.raw(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.raw(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.raw(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: $A = $MODEL.objects.raw(..., request.$W[...], ...) + - pattern: return $MODEL.objects.raw(..., request.$W[...], ...) + - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W, ...), ...) + - pattern: $MODEL.objects.raw(..., $S % request.$W, ...) + - pattern: $MODEL.objects.raw(..., f"...{request.$W}...", ...) + - pattern: $MODEL.objects.raw(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.raw(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.raw(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.raw(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.raw(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: $A = $MODEL.objects.raw(..., request.$W, ...) + - pattern: return $MODEL.objects.raw(..., request.$W, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.raw($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.raw($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.raw($STR % (..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.raw($INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.raw($INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.raw($INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.raw($INTERM, ...) + severity: WARNING + - id: python.django.security.injection.ssrf.ssrf-injection-requests.ssrf-injection-requests + languages: + - python + message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF). To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. See https://owasp.org/www-community/attacks/Server_Side_Request_Forgery to learn more about SSRF vulnerabilities. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: requests.$METHOD(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: requests.$METHOD(..., $S % request.$W.get(...), ...) + - pattern: requests.$METHOD(..., f"...{request.$W.get(...)}...", ...) + - pattern: requests.$METHOD(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + requests.$METHOD(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + requests.$METHOD(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + requests.$METHOD(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + requests.$METHOD(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: $A = requests.$METHOD(..., request.$W.get(...), ...) + - pattern: return requests.$METHOD(..., request.$W.get(...), ...) + - pattern: requests.$METHOD(..., $S.format(..., request.$W(...), ...), ...) + - pattern: requests.$METHOD(..., $S % request.$W(...), ...) + - pattern: requests.$METHOD(..., f"...{request.$W(...)}...", ...) + - pattern: requests.$METHOD(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + requests.$METHOD(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + requests.$METHOD(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + requests.$METHOD(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + requests.$METHOD(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: $A = requests.$METHOD(..., request.$W(...), ...) + - pattern: return requests.$METHOD(..., request.$W(...), ...) + - pattern: requests.$METHOD(..., $S.format(..., request.$W[...], ...), ...) + - pattern: requests.$METHOD(..., $S % request.$W[...], ...) + - pattern: requests.$METHOD(..., f"...{request.$W[...]}...", ...) + - pattern: requests.$METHOD(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + requests.$METHOD(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + requests.$METHOD(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + requests.$METHOD(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + requests.$METHOD(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: $A = requests.$METHOD(..., request.$W[...], ...) + - pattern: return requests.$METHOD(..., request.$W[...], ...) + - pattern: requests.$METHOD(..., $S.format(..., request.$W, ...), ...) + - pattern: requests.$METHOD(..., $S % request.$W, ...) + - pattern: requests.$METHOD(..., f"...{request.$W}...", ...) + - pattern: requests.$METHOD(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + requests.$METHOD(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + requests.$METHOD(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + requests.$METHOD(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + requests.$METHOD(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: $A = requests.$METHOD(..., request.$W, ...) + - pattern: return requests.$METHOD(..., request.$W, ...) + severity: ERROR + - id: python.django.security.injection.ssrf.ssrf-injection-urllib.ssrf-injection-urllib + languages: + - python + message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF), which could result in attackers gaining access to private organization data. To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: urllib.request.urlopen(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: urllib.request.urlopen(..., $S % request.$W.get(...), ...) + - pattern: urllib.request.urlopen(..., f"...{request.$W.get(...)}...", ...) + - pattern: urllib.request.urlopen(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + urllib.request.urlopen(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + urllib.request.urlopen(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + urllib.request.urlopen(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + urllib.request.urlopen(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: $A = urllib.request.urlopen(..., request.$W.get(...), ...) + - pattern: return urllib.request.urlopen(..., request.$W.get(...), ...) + - pattern: urllib.request.urlopen(..., $S.format(..., request.$W(...), ...), ...) + - pattern: urllib.request.urlopen(..., $S % request.$W(...), ...) + - pattern: urllib.request.urlopen(..., f"...{request.$W(...)}...", ...) + - pattern: urllib.request.urlopen(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + urllib.request.urlopen(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + urllib.request.urlopen(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + urllib.request.urlopen(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + urllib.request.urlopen(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: $A = urllib.request.urlopen(..., request.$W(...), ...) + - pattern: return urllib.request.urlopen(..., request.$W(...), ...) + - pattern: urllib.request.urlopen(..., $S.format(..., request.$W[...], ...), ...) + - pattern: urllib.request.urlopen(..., $S % request.$W[...], ...) + - pattern: urllib.request.urlopen(..., f"...{request.$W[...]}...", ...) + - pattern: urllib.request.urlopen(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + urllib.request.urlopen(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + urllib.request.urlopen(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + urllib.request.urlopen(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + urllib.request.urlopen(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: $A = urllib.request.urlopen(..., request.$W[...], ...) + - pattern: return urllib.request.urlopen(..., request.$W[...], ...) + - pattern: urllib.request.urlopen(..., $S.format(..., request.$W, ...), ...) + - pattern: urllib.request.urlopen(..., $S % request.$W, ...) + - pattern: urllib.request.urlopen(..., f"...{request.$W}...", ...) + - pattern: urllib.request.urlopen(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + urllib.request.urlopen(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + urllib.request.urlopen(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + urllib.request.urlopen(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + urllib.request.urlopen(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: $A = urllib.request.urlopen(..., request.$W, ...) + - pattern: return urllib.request.urlopen(..., request.$W, ...) + severity: ERROR + - id: python.django.security.injection.tainted-sql-string.tainted-sql-string + languages: + - python + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using the Django object-relational mappers (ORM) instead of raw SQL queries. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: LOW + likelihood: MEDIUM + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.djangoproject.com/en/3.0/topics/security/#sql-injection-protection + subcategory: + - audit + technology: + - django + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR" % ... + - pattern: | + "$SQLSTR".format(...) + - pattern: | + f"$SQLSTR{...}..." + - metavariable-regex: + metavariable: $SQLSTR + regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.* + pattern-sources: + - patterns: + - pattern: request.$ANYTHING + - pattern-not: request.build_absolute_uri + severity: ERROR + - id: python.django.security.injection.tainted-url-host.tainted-url-host + languages: + - python + message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - flask + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: '"$URLSTR" % ...' + - metavariable-pattern: + language: generic + metavariable: $URLSTR + patterns: + - pattern-either: + - pattern: $SCHEME://%s + - pattern: $SCHEME://%r + - patterns: + - pattern: '"$URLSTR".format(...)' + - metavariable-pattern: + language: generic + metavariable: $URLSTR + pattern: $SCHEME:// { ... } + - patterns: + - pattern: '"$URLSTR" + ...' + - metavariable-regex: + metavariable: $URLSTR + regex: .*://$ + - patterns: + - pattern: f"$URLSTR{...}..." + - metavariable-regex: + metavariable: $URLSTR + regex: .*://$ + - patterns: + - pattern-inside: | + $URL = "$URLSTR" + ... + - pattern: $URL += ... + - metavariable-regex: + metavariable: $URLSTR + regex: .*://$ + pattern-sources: + - patterns: + - pattern: request.$ANYTHING + - pattern-not: request.build_absolute_uri + severity: WARNING + - id: python.django.security.locals-as-template-context.locals-as-template-context + languages: + - python + message: 'Using ''locals()'' as a context to ''render(...)'' is extremely dangerous. This exposes Python functions to the template that were not meant to be exposed. An attacker could use these functions to execute code that was not intended to run and could compromise the application. (This is server-side template injection (SSTI)). Do not use ''locals()''. Instead, specify each variable in a dictionary or ''django.template.Context'' object, like ''{"var1": "hello"}'' and use that instead.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://docs.djangoproject.com/en/3.2/ref/settings/#templates + - https://docs.djangoproject.com/en/3.2/topics/templates/#django.template.backends.django.DjangoTemplates + - https://docs.djangoproject.com/en/3.2/ref/templates/api/#rendering-a-context + subcategory: + - audit + technology: + - django + pattern-either: + - pattern: django.shortcuts.render(..., locals(...), ...) + - pattern: django.template.Template.render(..., locals(...), ...) + - patterns: + - pattern-inside: | + $CONTEXT = locals(...) + ... + - pattern-either: + - pattern: django.shortcuts.render(..., $CONTEXT, ...) + - pattern: django.template.Template.render(..., $CONTEXT, ...) + severity: ERROR + - id: python.django.security.nan-injection.nan-injection + languages: + - python + message: Found user input going directly into typecast for bool(), float(), or complex(). This allows an attacker to inject Python's not-a-number (NaN) into the typecast. This results in undefind behavior, particularly when doing comparisons. Either cast to a different type, or add a guard checking for all capitalizations of the string 'nan'. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-704: Incorrect Type Conversion or Cast' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://discuss.python.org/t/nan-breaks-min-max-and-sorting-functions-a-solution/2868 + - https://blog.bitdiscovery.com/2021/12/python-nan-injection/ + subcategory: + - vuln + technology: + - django + mode: taint + pattern-sanitizers: + - not_conflicting: true + pattern: $ANYTHING(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: float(...) + - pattern: bool(...) + - pattern: complex(...) + - pattern-not-inside: | + if $COND: + ... + ... + pattern-sources: + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + severity: ERROR + - id: python.django.security.passwords.password-empty-string.password-empty-string + languages: + - python + message: '''$VAR'' is the empty string and is being used to set the password on ''$MODEL''. If you meant to set an unusable password, set the password to None or call ''set_unusable_password()''.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-521: Weak Password Requirements' + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://docs.djangoproject.com/en/3.0/ref/contrib/auth/#django.contrib.auth.models.User.set_password + subcategory: + - vuln + technology: + - django + patterns: + - pattern-either: + - pattern: | + $MODEL.set_password($EMPTY) + ... + $MODEL.save() + - pattern: | + $VAR = $EMPTY + ... + $MODEL.set_password($VAR) + ... + $MODEL.save() + - metavariable-regex: + metavariable: $EMPTY + regex: (\'\'|\"\") + severity: ERROR + - fix: | + None + id: python.django.security.passwords.use-none-for-password-default.use-none-for-password-default + languages: + - python + message: '''$VAR'' is using the empty string as its default and is being used to set the password on ''$MODEL''. If you meant to set an unusable password, set the default value to ''None'' or call ''set_unusable_password()''.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-521: Weak Password Requirements' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://docs.djangoproject.com/en/3.0/ref/contrib/auth/#django.contrib.auth.models.User.set_password + subcategory: + - vuln + technology: + - django + patterns: + - pattern-either: + - pattern: | + $VAR = request.$W.get($X, $EMPTY) + ... + $MODEL.set_password($VAR) + ... + $MODEL.save(...) + - pattern: | + def $F(..., $VAR=$EMPTY, ...): + ... + $MODEL.set_password($VAR) + - metavariable-pattern: + metavariable: $EMPTY + pattern: '""' + - focus-metavariable: $EMPTY + severity: ERROR + - id: python.docker.security.audit.docker-arbitrary-container-run.docker-arbitrary-container-run + languages: + - python + message: If unverified user data can reach the `run` or `create` method it can result in running arbitrary container. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: HIGH + likelihood: LOW + references: + - https://cwe.mitre.org/data/definitions/250.html + subcategory: + - audit + technology: + - docker + patterns: + - pattern-either: + - pattern-inside: | + $CLIENT = docker.from_env() + ... + - pattern-inside: | + $CLIENT = docker.DockerClient(...) + ... + - pattern-either: + - pattern: | + $CLIENT.containers.run(...) + - pattern: | + $CLIENT.containers.create(...) + - pattern-not: | + $CLIENT.containers.run("...",...) + - pattern-not: | + $CLIENT.containers.create("...",...) + severity: WARNING + - id: python.flask.best-practice.get-class-method-with-side-effects.flask-class-method-get-side-effects + languages: + - python + message: Flask class method GET with side effects + metadata: + category: best-practice + technology: + - flask + patterns: + - pattern-either: + - pattern: | + def get(self,...): + ... + $METHOD(...) + - pattern: | + def get(self,...): + ... + $VAR = $METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (?i)(create|update|delete).* + severity: WARNING + - fix: | + flask.jsonify($...VAR) + id: python.flask.best-practice.use-jsonify.use-jsonify + languages: + - python + message: flask.jsonify() is a Flask helper method which handles the correct settings for returning JSON from Flask routes + metadata: + category: best-practice + references: + - https://flask.palletsprojects.com/en/2.2.x/api/#flask.json.jsonify + technology: + - flask + patterns: + - pattern: $JSONDUMPS + - pattern-either: + - pattern-inside: | + return json.dumps($...VAR) + - pattern-inside: | + $DATA = json.dumps($...VAR) + ... + return $DATA + - pattern-inside: | + @app.route(...) + def $X(): + ... + - metavariable-pattern: + metavariable: $JSONDUMPS + pattern: json.dumps($...VAR) + - focus-metavariable: $JSONDUMPS + severity: ERROR + - id: python.flask.caching.query-string.flask-cache-query-string + languages: + - python + message: Flask-caching doesn't cache query strings by default. You have to use `query_string=True`. Also you shouldn't cache verbs that can mutate state. + metadata: + category: caching + technology: + - flask + patterns: + - pattern-either: + - pattern: | + @app.route("...") + @cache.cached(...) + def $HANDLER(...): + ... + request.args.get(...) + - pattern: | + @app.route("...", methods=[..., "POST", ...]) + @cache.cached(...) + def $HANDLER(...): + ... + - pattern: | + @app.route("...", methods=[..., "PUT", ...]) + @cache.cached(...) + def $HANDLER(...): + ... + - pattern: | + @app.route("...", methods=[..., "DELETE", ...]) + @cache.cached(...) + def $HANDLER(...): + ... + - pattern: | + @app.route("...", methods=[..., "PATCH", ...]) + @cache.cached(...) + def $HANDLER(...): + ... + - pattern-not: | + @app.route("...") + @cache.cached(..., query_string=True) + def $HANDLER(...): + ... + request.args.get(...) + severity: WARNING + - id: python.flask.correctness.access-request-in-wrong-handler.avoid-accessing-request-in-wrong-handler + languages: + - python + message: Accessing request object inside a route handle for HTTP GET command will throw due to missing request body. + metadata: + category: correctness + technology: + - flask + patterns: + - pattern-inside: | + @app.route(..., method="GET") + def $X(...): + ... + - pattern-either: + - pattern: | + $Y = flask.request.json + - pattern: | + $Y = flask.request.form + - pattern: | + $Y = flask.request.data + severity: WARNING + - id: python.flask.correctness.same-handler-name.flask-duplicate-handler-name + languages: + - python + message: Looks like `$R` is a flask function handler that registered to two different routes. This will cause a runtime error + metadata: + category: correctness + technology: + - flask + pattern: | + @app.route("...", ...) + def $R(...): + ... + ... + @app.route("...", ...) + def $R(...): + ... + severity: WARNING + - id: python.flask.maintainability.deprecated.deprecated-apis.flask-deprecated-apis + languages: + - python + message: deprecated Flask API + metadata: + category: maintainability + technology: + - flask + pattern-either: + - pattern: | + $F = Flask(...) + ... + $F.open_session(...) + - pattern: | + $F = Flask(...) + ... + $F.save_session(...) + - pattern: | + $F = Flask(...) + ... + $F.make_null_session(...) + - pattern: | + $F = Flask(...) + ... + $F.init_jinja_globals(...) + - pattern: | + $F = Flask(...) + ... + $F.request_globals_class(...) + - pattern: | + $F = Flask(...) + ... + $F.static_path(...) + - pattern: app.open_session(...) + - pattern: app.save_session(...) + - pattern: app.make_null_session(...) + - pattern: app.init_jinja_globals(...) + - pattern: app.request_globals_class(...) + - pattern: app.static_path(...) + - pattern: app.config.from_json(...) + - pattern: flask.json_available + - pattern: flask.request.module + - pattern: flask.testing.make_test_environ_builder(...) + severity: WARNING + - id: python.flask.security.audit.app-run-param-config.avoid_app_run_with_bad_host + languages: + - python + message: Running flask app with host 0.0.0.0 could expose the server publicly. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-668: Exposure of Resource to Wrong Sphere' + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - flask + pattern-either: + - pattern: app.run(..., host="0.0.0.0", ...) + - pattern: app.run(..., "0.0.0.0", ...) + severity: WARNING + - id: python.flask.security.audit.app-run-security-config.avoid_using_app_run_directly + languages: + - python + message: top-level app.run(...) is ignored by flask. Consider putting app.run(...) behind a guard, like inside a function + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-668: Exposure of Resource to Wrong Sphere' + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - flask + patterns: + - pattern-not-inside: | + if __name__ == '__main__': + ... + - pattern-not-inside: | + def $X(...): + ... + - pattern: app.run(...) + severity: WARNING + - id: python.flask.security.audit.debug-enabled.debug-enabled + languages: + - python + message: Detected Flask app with debug=True. Do not deploy to production with this flag enabled as it will leak sensitive information. Instead, consider using Flask configuration variables or setting 'debug' using system environment variables. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-489: Active Debug Code' + impact: MEDIUM + likelihood: HIGH + owasp: A06:2017 - Security Misconfiguration + references: + - https://labs.detectify.com/2015/10/02/how-patreon-got-hacked-publicly-exposed-werkzeug-debugger/ + subcategory: + - vuln + technology: + - flask + patterns: + - pattern-inside: | + import flask + ... + - pattern: $APP.run(..., debug=True, ...) + severity: WARNING + - id: python.flask.security.audit.directly-returned-format-string.directly-returned-format-string + languages: + - python + message: Detected Flask route directly returning a formatted string. This is subject to cross-site scripting if user input can reach the string. Consider using the template engine instead and rendering pages with 'render_template()'. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - flask + mode: taint + pattern-sinks: + - patterns: + - pattern-not-inside: return "..." + - pattern-either: + - pattern: return "...".format(...) + - pattern: return "..." % ... + - pattern: return "..." + ... + - pattern: return ... + "..." + - pattern: return f"...{...}..." + - patterns: + - pattern: return $X + - pattern-either: + - pattern-inside: | + $X = "...".format(...) + ... + - pattern-inside: | + $X = "..." % ... + ... + - pattern-inside: | + $X = "..." + ... + ... + - pattern-inside: | + $X = ... + "..." + ... + - pattern-inside: | + $X = f"...{...}..." + ... + - pattern-not-inside: | + $X = "..." + ... + pattern-sources: + - pattern-either: + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $PARAM, ...): + ... + - pattern: $PARAM + - pattern: | + request.$FUNC.get(...) + - pattern: | + request.$FUNC(...) + - pattern: request.$FUNC[...] + severity: WARNING + - id: python.flask.security.audit.hardcoded-config.avoid_hardcoded_config_testing + languages: + - python + message: Hardcoded variable `TESTING` detected. Use environment variables or config files instead + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-489: Active Debug Code' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://bento.dev/checks/flask/avoid-hardcoded-config/ + - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#builtin-configuration-values + - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#environment-and-debug-features + subcategory: + - audit + technology: + - flask + pattern-either: + - pattern: $M.config['TESTING'] = True + - pattern: $M.config['TESTING'] = False + - pattern: $M.update(TESTING=True, ...) + - pattern: $M.update(TESTING=False, ...) + severity: WARNING + - id: python.flask.security.audit.hardcoded-config.avoid_hardcoded_config_secret_key + languages: + - python + message: Hardcoded variable `SECRET_KEY` detected. Use environment variables or config files instead + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-489: Active Debug Code' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://bento.dev/checks/flask/avoid-hardcoded-config/ + - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#builtin-configuration-values + - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#environment-and-debug-features + subcategory: + - audit + technology: + - flask + pattern-either: + - pattern: $M.update(SECRET_KEY="=~/.*/") + - pattern: $M.config['SECRET_KEY'] = "=~/.*/" + severity: ERROR + - id: python.flask.security.audit.hardcoded-config.avoid_hardcoded_config_env + languages: + - python + message: Hardcoded variable `ENV` detected. Set this by using FLASK_ENV environment variable + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-489: Active Debug Code' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://bento.dev/checks/flask/avoid-hardcoded-config/ + - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#builtin-configuration-values + - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#environment-and-debug-features + subcategory: + - audit + technology: + - flask + pattern-either: + - pattern: $M.update(ENV="=~/^development|production$/") + - pattern: $M.config['ENV'] = "=~/^development|production$/" + severity: WARNING + - id: python.flask.security.audit.hardcoded-config.avoid_hardcoded_config_debug + languages: + - python + message: Hardcoded variable `DEBUG` detected. Set this by using FLASK_DEBUG environment variable + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-489: Active Debug Code' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://bento.dev/checks/flask/avoid-hardcoded-config/ + - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#builtin-configuration-values + - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#environment-and-debug-features + subcategory: + - audit + technology: + - flask + pattern-either: + - pattern: $M.update(DEBUG=True) + - pattern: $M.update(DEBUG=False) + - pattern: $M.config['DEBUG'] = True + - pattern: $M.config['DEBUG'] = False + severity: WARNING + - id: python.flask.security.audit.host-header-injection-python.host-header-injection-python + languages: + - python + message: The `flask.request.host` is used to construct an HTTP request. This can lead to host header injection issues. Vulnerabilities that generally occur due to this issue are authentication bypasses, password reset issues, Server-Side-Request-Forgery (SSRF), and many more. It is recommended to validate the URL before passing it to a request library, or using application logic such as authentication or password resets. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-20: Improper Input Validation' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + references: + - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/17-Testing_for_Host_Header_Injection + - https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html + subcategory: + - audit + technology: + - flask + patterns: + - pattern-either: + - pattern: | + $X = <... "=~/.*http[s]*:///" + flask.request.host ...>; + - pattern: | + $X = <... "=~/.*http[s]*:///" + flask.request["host"] ...>; + - pattern: | + $Z = flask.request.host; + ... + $X = <... "=~/.*http[s]*:///" + $Z ...>; + - pattern: | + $Z = flask.request["host"]; + ... + $X = <... "=~/.*http[s]*:///" + $Z ...>; + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(): + ... + severity: INFO + - id: python.flask.security.audit.render-template-string.render-template-string + languages: + - python + message: Found a template created with string formatting. This is susceptible to server-side template injection and cross-site scripting attacks. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://nvisium.com/blog/2016/03/09/exploring-ssti-in-flask-jinja2.html + subcategory: + - audit + technology: + - flask + pattern: flask.render_template_string(...) + severity: WARNING + - id: python.flask.security.audit.secure-set-cookie.secure-set-cookie + languages: + - python + message: Found a Flask cookie with insecurely configured properties. By default the secure, httponly and samesite ar configured insecurely. cookies should be handled securely by setting `secure=True`, `httponly=True`, and `samesite='Lax'` in response.set_cookie(...). If these parameters are not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. Include the `secure=True`, `httponly=True`, `samesite='Lax'` arguments or set these to be true in the Flask configuration. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + functional-categories: + - web::search::cookie-config::flask + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://flask.palletsprojects.com/en/3.0.x/api/#flask.Response.set_cookie + - https://flask.palletsprojects.com/en/3.0.x/security/#set-cookie-options + subcategory: + - audit + technology: + - python + - flask + patterns: + - pattern-either: + - pattern-inside: | + $RESP = flask.make_response(...) + ... + - pattern-inside: | + $RESP = flask.Response(...) + ... + - pattern-not: $RESP.set_cookie(..., secure=$A, httponly=$B, samesite=$C, ...) + - pattern-not: $RESP.set_cookie(..., **$A) + - pattern: $RESP.set_cookie(...) + severity: WARNING + - fix: "True" + id: python.flask.security.audit.wtf-csrf-disabled.flask-wtf-csrf-disabled + languages: + - python + message: Setting 'WTF_CSRF_ENABLED' to 'False' explicitly disables CSRF protection. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + functional-categories: + - web::search::csrf-config::flask + - web::search::csrf-config::flask-wtf + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://flask-wtf.readthedocs.io/en/1.2.x/csrf/ + subcategory: + - audit + technology: + - flask + options: + symbolic_propagation: true + 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 + severity: WARNING + - id: python.flask.security.audit.xss.make-response-with-unknown-content.make-response-with-unknown-content + languages: + - python + message: Be careful with `flask.make_response()`. If this response is rendered onto a webpage, this could create a cross-site scripting (XSS) vulnerability. `flask.make_response()` will not autoescape HTML. If you are rendering HTML, write your HTML in a template file and use `flask.render_template()` which will take care of escaping. If you are returning data from an API, consider using `flask.jsonify()`. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://github.com/python-security/pyt//blob/093a077bcf12d1f58ddeb2d73ddc096623985fb0/examples/vulnerable_code/XSS_assign_to_other_var.py#L11 + - https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.make_response + - https://flask.palletsprojects.com/en/1.1.x/api/#response-objects + subcategory: + - audit + technology: + - flask + patterns: + - pattern: flask.make_response(...) + - pattern-not-inside: flask.make_response() + - pattern-not-inside: flask.make_response("...", ...) + - pattern-not-inside: 'flask.make_response({"...": "..."}, ...)' + - pattern-not-inside: flask.make_response(flask.redirect(...), ...) + - pattern-not-inside: flask.make_response(flask.render_template(...), ...) + - pattern-not-inside: flask.make_response(flask.jsonify(...), ...) + - pattern-not-inside: flask.make_response(json.dumps(...), ...) + - pattern-not-inside: | + $X = flask.render_template(...) + ... + flask.make_response($X, ...) + - pattern-not-inside: | + $X = flask.jsonify(...) + ... + flask.make_response($X, ...) + - pattern-not-inside: | + $X = json.dumps(...) + ... + flask.make_response($X, ...) + severity: WARNING + - id: python.flask.security.dangerous-template-string.dangerous-template-string + languages: + - python + message: Found a template created with string formatting. This is susceptible to server-side template injection and cross-site scripting attacks. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://nvisium.com/blog/2016/03/09/exploring-ssti-in-flask-jinja2.html + - https://pequalsnp-team.github.io/cheatsheet/flask-jinja2-ssti + subcategory: + - audit + technology: + - flask + pattern-either: + - pattern: | + $V = "...".format(...) + ... + flask.render_template_string($V, ...) + - pattern: | + $V = "...".format(...) + ... + return flask.render_template_string($V, ...), $MORE + - pattern: | + $V = "..." % $S + ... + flask.render_template_string($V, ...) + - pattern: | + $V = "..." % $S + ... + return flask.render_template_string($V, ...), $MORE + - pattern: | + $V = "..." + ... + $V += $O + ... + flask.render_template_string($V, ...) + - pattern: | + $V = "..." + ... + $V += $O + ... + return flask.render_template_string($V, ...), $MORE + - pattern: | + $V = f"...{$X}..." + ... + flask.render_template_string($V, ...) + - pattern: | + $V = f"...{$X}..." + ... + return flask.render_template_string($V, ...), $CODE + severity: ERROR + - id: python.flask.security.flask-api-method-string-format.flask-api-method-string-format + languages: + - python + message: Method $METHOD in API controller $CLASS provides user arg $ARG to requests method $REQMETHOD + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-134: Use of Externally-Controlled Format String' + impact: MEDIUM + likelihood: LOW + references: + - https://cwe.mitre.org/data/definitions/134.html + subcategory: + - audit + technology: + - flask + patterns: + - pattern-either: + - pattern: | + def $METHOD(...,$ARG,...): + ... + $STRING = "...".format(...,$ARG,...) + ... + ... = requests.$REQMETHOD($STRING,...) + - pattern: | + def $METHOD(...,$ARG,...): + ... + ... = requests.$REQMETHOD("...".format(...,$ARG,...),...) + - pattern-inside: | + class $CLASS(...): + method_decorators = ... + ... + severity: ERROR + - id: python.flask.security.hashids-with-flask-secret.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 + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: HIGH + likelihood: LOW + 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 + subcategory: + - vuln + technology: + - flask + 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 + - id: python.flask.security.injection.csv-writer-injection.csv-writer-injection + languages: + - python + message: Detected user input into a generated CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1236: Improper Neutralization of Formula Elements in a CSV File' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/raphaelm/defusedcsv + - https://owasp.org/www-community/attacks/CSV_Injection + - https://web.archive.org/web/20220516052229/https://www.contextis.com/us/blog/comma-separated-vulnerabilities + subcategory: + - vuln + technology: + - python + - flask + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + $WRITER = csv.writer(...) + + ... + + $WRITER.$WRITE(...) + - pattern: $WRITER.$WRITE(...) + - metavariable-regex: + metavariable: $WRITE + regex: ^(writerow|writerows|writeheader)$ + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + severity: ERROR + - id: python.flask.security.injection.nan-injection.nan-injection + languages: + - python + message: Found user input going directly into typecast for bool(), float(), or complex(). This allows an attacker to inject Python's not-a-number (NaN) into the typecast. This results in undefind behavior, particularly when doing comparisons. Either cast to a different type, or add a guard checking for all capitalizations of the string 'nan'. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-704: Incorrect Type Conversion or Cast' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://discuss.python.org/t/nan-breaks-min-max-and-sorting-functions-a-solution/2868 + - https://blog.bitdiscovery.com/2021/12/python-nan-injection/ + subcategory: + - vuln + technology: + - flask + mode: taint + pattern-sanitizers: + - not_conflicting: true + pattern: $ANYTHING(...) + pattern-sinks: + - pattern-either: + - pattern: float(...) + - pattern: bool(...) + - pattern: complex(...) + pattern-sources: + - pattern-either: + - pattern: flask.request.$SOMETHING.get(...) + - pattern: flask.request.$SOMETHING[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR + severity: ERROR + - id: python.flask.security.injection.os-system-injection.os-system-injection + languages: + - python + message: User data detected in os.system. This could be vulnerable to a command injection and should be avoided. If this must be done, use the 'subprocess' module instead and pass the arguments as a list. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/Command_Injection + subcategory: + - audit + technology: + - flask + pattern-either: + - patterns: + - pattern: os.system(...) + - pattern-either: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + os.system(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + $INTERM = <... $ROUTEVAR ...> + ... + os.system(..., <... $INTERM ...>, ...) + - pattern: os.system(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: os.system(..., <... flask.request.$W[...] ...>, ...) + - pattern: os.system(..., <... flask.request.$W(...) ...>, ...) + - pattern: os.system(..., <... flask.request.$W ...>, ...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + os.system(<... $INTERM ...>) + - pattern: os.system(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + os.system(<... $INTERM ...>) + - pattern: os.system(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + os.system(<... $INTERM ...>) + - pattern: os.system(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + os.system(<... $INTERM ...>) + - pattern: os.system(...) + severity: ERROR + - id: python.flask.security.injection.path-traversal-open.path-traversal-open + languages: + - python + message: Found request data in a call to 'open'. Ensure the request data is validated or sanitized, otherwise it could result in path traversal attacks. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + subcategory: + - audit + technology: + - flask + pattern-either: + - patterns: + - pattern: open(...) + - pattern-either: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + open(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + with open(..., <... $ROUTEVAR ...>, ...) as $FD: + ... + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + $INTERM = <... $ROUTEVAR ...> + ... + open(..., <... $INTERM ...>, ...) + - pattern: open(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: open(..., <... flask.request.$W[...] ...>, ...) + - pattern: open(..., <... flask.request.$W(...) ...>, ...) + - pattern: open(..., <... flask.request.$W ...>, ...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + open(<... $INTERM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + open(<... $INTERM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + open(<... $INTERM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + open(<... $INTERM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + with open(<... $INTERM ...>, ...) as $F: + ... + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + with open(<... $INTERM ...>, ...) as $F: + ... + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + with open(<... $INTERM ...>, ...) as $F: + ... + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + with open(<... $INTERM ...>, ...) as $F: + ... + - pattern: open(...) + severity: ERROR + - id: python.flask.security.injection.raw-html-concat.raw-html-format + languages: + - python + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates (`flask.render_template`) which will safely render HTML instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://flask.palletsprojects.com/en/2.0.x/security/#cross-site-scripting-xss + subcategory: + - vuln + technology: + - flask + mode: taint + pattern-sanitizers: + - pattern: jinja2.escape(...) + - pattern: flask.escape(...) + - pattern: flask.render_template("~=/.*\.html", ...) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: '"$HTMLSTR" % ...' + - pattern: '"$HTMLSTR".format(...)' + - pattern: '"$HTMLSTR" + ...' + - pattern: f"$HTMLSTR{...}..." + - patterns: + - pattern-inside: | + $HTML = "$HTMLSTR" + ... + - pattern-either: + - pattern: $HTML % ... + - pattern: $HTML.format(...) + - pattern: $HTML + ... + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... + pattern-sources: + - patterns: + - pattern-either: + - pattern: flask.request.$ANYTHING + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR + severity: WARNING + - id: python.flask.security.injection.ssrf-requests.ssrf-requests + languages: + - python + message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF). To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery + subcategory: + - vuln + technology: + - flask + pattern-either: + - patterns: + - pattern: requests.$FUNC(...) + - pattern-either: + - pattern-inside: | + @$APP.$ROUTE_METHOD($ROUTE, ...) + def $ROUTE_FUNC(..., $ROUTEVAR, ...): + ... + requests.$FUNC(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.$ROUTE_METHOD($ROUTE, ...) + def $ROUTE_FUNC(..., $ROUTEVAR, ...): + ... + $INTERM = <... $ROUTEVAR ...> + ... + requests.$FUNC(..., <... $INTERM ...>, ...) + - metavariable-regex: + metavariable: $ROUTE_METHOD + regex: ^(route|get|post|put|delete|patch)$ + - pattern: requests.$FUNC(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: requests.$FUNC(..., <... flask.request.$W[...] ...>, ...) + - pattern: requests.$FUNC(..., <... flask.request.$W(...) ...>, ...) + - pattern: requests.$FUNC(..., <... flask.request.$W ...>, ...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + requests.$FUNC(<... $INTERM ...>, ...) + - pattern: requests.$FUNC(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + requests.$FUNC(<... $INTERM ...>, ...) + - pattern: requests.$FUNC(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + requests.$FUNC(<... $INTERM ...>, ...) + - pattern: requests.$FUNC(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + requests.$FUNC(<... $INTERM ...>, ...) + - pattern: requests.$FUNC(...) + severity: ERROR + - id: python.flask.security.injection.subprocess-injection.subprocess-injection + languages: + - python + message: Detected user input entering a `subprocess` call unsafely. This could result in a command injection vulnerability. An attacker could use this vulnerability to execute arbitrary commands on the host, which allows them to download malware, scan sensitive data, or run any command they wish on the server. Do not let users choose the command to run. In general, prefer to use Python API versions of system commands. If you must use subprocess, use a dictionary to allowlist a set of commands. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - flask + mode: taint + options: + symbolic_propagation: true + pattern-sanitizers: + - patterns: + - pattern: $DICT[$KEY] + - focus-metavariable: $KEY + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: subprocess.$FUNC(...) + - pattern-not: subprocess.$FUNC("...", ...) + - pattern-not: subprocess.$FUNC(["...", ...], ...) + - pattern-not-inside: | + $CMD = ["...", ...] + ... + subprocess.$FUNC($CMD, ...) + - patterns: + - pattern: subprocess.$FUNC(["$SHELL", "-c", ...], ...) + - metavariable-regex: + metavariable: $SHELL + regex: ^(sh|bash|ksh|csh|tcsh|zsh)$ + - patterns: + - pattern: subprocess.$FUNC(["$INTERPRETER", ...], ...) + - metavariable-regex: + metavariable: $INTERPRETER + regex: ^(python|python\d)$ + pattern-sources: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + severity: ERROR + - id: python.flask.security.injection.tainted-sql-string.tainted-sql-string + languages: + - python + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as SQLAlchemy which will protect your queries. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-704: Incorrect Type Conversion or Cast' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql + - https://www.tutorialspoint.com/sqlalchemy/sqlalchemy_quick_guide.htm + - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-more-specific-text-with-table-expression-literal-column-and-expression-column + subcategory: + - vuln + technology: + - sqlalchemy + - flask + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR" % ... + - pattern: | + "$SQLSTR".format(...) + - pattern: | + f"$SQLSTR{...}..." + - metavariable-regex: + metavariable: $SQLSTR + regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.* + pattern-sources: + - patterns: + - pattern-either: + - pattern: flask.request.$ANYTHING + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR + severity: ERROR + - id: python.flask.security.injection.tainted-url-host.tainted-url-host + languages: + - python + message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - flask + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: '"$URLSTR" % ...' + - metavariable-pattern: + language: generic + metavariable: $URLSTR + patterns: + - pattern-either: + - pattern: $SCHEME://%s + - pattern: $SCHEME://%r + - patterns: + - pattern: '"$URLSTR".format(...)' + - metavariable-pattern: + language: generic + metavariable: $URLSTR + pattern: $SCHEME:// { ... } + - patterns: + - pattern: '"$URLSTR" + ...' + - metavariable-regex: + metavariable: $URLSTR + regex: .*://$ + - patterns: + - pattern: f"$URLSTR{...}..." + - metavariable-regex: + metavariable: $URLSTR + regex: .*://$ + - patterns: + - pattern-inside: | + $URL = "$URLSTR" + ... + - pattern: $URL += ... + - metavariable-regex: + metavariable: $URLSTR + regex: .*://$ + pattern-sources: + - patterns: + - pattern-either: + - pattern: flask.request.$ANYTHING + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR + severity: WARNING + - id: python.flask.security.injection.user-eval.eval-injection + languages: + - python + message: Detected user data flowing into eval. This is code injection and should be avoided. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html + subcategory: + - vuln + technology: + - flask + pattern-either: + - patterns: + - pattern: eval(...) + - pattern-either: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + eval(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + $INTERM = <... $ROUTEVAR ...> + ... + eval(..., <... $INTERM ...>, ...) + - pattern: eval(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: eval(..., <... flask.request.$W[...] ...>, ...) + - pattern: eval(..., <... flask.request.$W(...) ...>, ...) + - pattern: eval(..., <... flask.request.$W ...>, ...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + eval(..., <... $INTERM ...>, ...) + - pattern: eval(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + eval(..., <... $INTERM ...>, ...) + - pattern: eval(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + eval(..., <... $INTERM ...>, ...) + - pattern: eval(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + eval(..., <... $INTERM ...>, ...) + - pattern: eval(...) + severity: ERROR + - id: python.flask.security.injection.user-exec.exec-injection + languages: + - python + message: Detected user data flowing into exec. This is code injection and should be avoided. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://nedbatchelder.com/blog/201206/exec_really_is_dangerous.html + subcategory: + - vuln + technology: + - flask + pattern-either: + - patterns: + - pattern: exec(...) + - pattern-either: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + exec(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + $INTERM = <... $ROUTEVAR ...> + ... + exec(..., <... $INTERM ...>, ...) + - pattern: exec(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: exec(..., <... flask.request.$W[...] ...>, ...) + - pattern: exec(..., <... flask.request.$W(...) ...>, ...) + - pattern: exec(..., <... flask.request.$W ...>, ...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + exec(..., <... $INTERM ...>, ...) + - pattern: exec(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + exec(..., <... $INTERM ...>, ...) + - pattern: exec(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + exec(..., <... $INTERM ...>, ...) + - pattern: exec(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + exec(..., <... $INTERM ...>, ...) + - pattern: exec(...) + severity: ERROR + - id: python.flask.security.insecure-deserialization.insecure-deserialization + languages: + - python + message: Detected the use of an insecure deserialization library in a Flask route. These libraries are prone to code execution vulnerabilities. Ensure user data does not enter this function. To fix this, try to avoid serializing whole objects. Consider instead using a serializer such as JSON. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.python.org/3/library/pickle.html + subcategory: + - audit + technology: + - flask + patterns: + - pattern-inside: | + @app.route(...) + def $X(...): + ... + - pattern-not: $MODULE.$FUNC("...") + - pattern-not: $MODULE.$FUNC(open("...", ...)) + - pattern-either: + - pattern: pickle.$FUNC(...) + - pattern: _pickle.$FUNC(...) + - pattern: cPickle.$FUNC(...) + - pattern: dill.$FUNC(...) + - pattern: shelve.$FUNC(...) + - pattern: yaml.load(...) + severity: ERROR + - id: python.flask.security.open-redirect.open-redirect + languages: + - python + message: Data from request is passed to redirect(). This is an open redirect and could be exploited. Consider using 'url_for()' to generate links to known locations. If you must use a URL to unknown pages, consider using 'urlparse()' or similar and checking if the 'netloc' property is the same as your site's host name. See the references for more information. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://flask-login.readthedocs.io/en/latest/#login-example + - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html#dangerous-url-redirect-example-1 + - https://docs.python.org/3/library/urllib.parse.html#url-parsing + subcategory: + - audit + technology: + - flask + patterns: + - pattern-inside: | + @$APP.route(...) + def $X(...): + ... + - pattern-not-inside: | + @$APP.route(...) + def $X(...): + ... + if <... werkzeug.urls.url_parse($V) ...>: + ... + - pattern-either: + - pattern: flask.redirect(<... flask.request.$W.get(...) ...>, ...) + - pattern: flask.redirect(<... flask.request.$W[...] ...>, ...) + - pattern: flask.redirect(<... flask.request.$W(...) ...>, ...) + - pattern: flask.redirect(<... flask.request.$W ...>, ...) + - pattern: | + $V = flask.request.$W.get(...) + ... + flask.redirect(<... $V ...>, ...) + - pattern: | + $V = flask.request.$W[...] + ... + flask.redirect(<... $V ...>, ...) + - pattern: | + $V = flask.request.$W(...) + ... + flask.redirect(<... $V ...>, ...) + - pattern: | + $V = flask.request.$W + ... + flask.redirect(<... $V ...>, ...) + - pattern-not: flask.redirect(flask.request.path) + - pattern-not: flask.redirect(flask.request.path + ...) + - pattern-not: flask.redirect(f"{flask.request.path}...") + severity: ERROR + - id: python.flask.security.secure-static-file-serve.avoid_send_file_without_path_sanitization + languages: + - python + message: Detected a user-controlled `filename` that could flow to `flask.send_file()` function. This could lead to an attacker reading arbitrary file from the system, leaking private information. Make sure to properly sanitize filename or use `flask.send_from_directory` + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-73: External Control of File Name or Path' + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit + technology: + - flask + patterns: + - pattern-inside: | + @app.route(...) + def $X(filename): + ... + - pattern: flask.send_file(filename, ...) + severity: WARNING + - id: python.flask.security.unsanitized-input.response-contains-unsanitized-input + languages: + - python + message: Flask response reflects unsanitized user input. This could lead to a cross-site scripting vulnerability (https://owasp.org/www-community/attacks/xss/) in which an attacker causes arbitrary code to be executed in the user's browser. To prevent, please sanitize the user input, e.g. by rendering the response in a Jinja2 template (see considerations in https://flask.palletsprojects.com/en/1.0.x/security/). + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://flask.palletsprojects.com/en/1.0.x/security/ + - https://owasp.org/www-community/attacks/xss/ + subcategory: + - audit + technology: + - flask + pattern-either: + - pattern: | + $X = flask.request.args.get(...) + ... + flask.make_response("...".format($X)) + - pattern: | + $X = flask.request.args.get(...) + ... + flask.make_response(f"...{$X}...") + - pattern: | + $X = flask.request.args.get(...) + ... + flask.make_response(f"...{$X}") + - pattern: | + $X = flask.request.args.get(...) + ... + flask.make_response(f"{$X}...") + severity: WARNING + - id: python.flask.security.xss.audit.direct-use-of-jinja2.direct-use-of-jinja2 + languages: + - python + message: Detected direct use of jinja2. If not done properly, this may bypass HTML escaping which opens up the application to cross-site scripting (XSS) vulnerabilities. Prefer using the Flask method 'render_template()' and templates with a '.html' extension in order to prevent XSS. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://jinja.palletsprojects.com/en/2.11.x/api/#basics + subcategory: + - audit + technology: + - flask + pattern-either: + - pattern: jinja2.Environment(...) + - pattern: jinja2.Template.render(...) + - patterns: + - pattern-inside: | + $TEMPLATE = $ENV.get_template(...) + ... + - pattern: $TEMPLATE.render(...) + - patterns: + - pattern-inside: | + $TEMPLATE = jinja2.Template(...) + ... + - pattern: $TEMPLATE.render(...) + severity: WARNING + - id: python.flask.security.xss.audit.explicit-unescape-with-markup.explicit-unescape-with-markup + languages: + - python + message: Detected explicitly unescaped content using 'Markup()'. This permits the unescaped data to include unescaped HTML which could result in cross-site scripting. Ensure this data is not externally controlled, or consider rewriting to not use 'Markup()'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://tedboy.github.io/flask/generated/generated/flask.Markup.html + subcategory: + - audit + technology: + - flask + pattern-either: + - pattern: flask.Markup.unescape(...) + - pattern: $MARKUPOBJ.unescape() + - patterns: + - pattern-either: + - pattern: flask.Markup($Q) + - pattern: markupsafe.Markup($Q) + - metavariable-pattern: + metavariable: $Q + patterns: + - pattern-not: '"..."' + severity: WARNING + - id: python.flask.security.xss.audit.template-autoescape-off.template-autoescape-off + languages: + - regex + message: Detected a segment of a Flask template where autoescaping is explicitly disabled with '{% autoescape off %}'. This allows rendering of raw HTML in this segment. Ensure no user data is rendered here, otherwise this is a cross-site scripting (XSS) vulnerability, or turn autoescape on. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://flask.palletsprojects.com/en/1.1.x/templating/#controlling-autoescaping + - https://flask.palletsprojects.com/en/1.1.x/templating/#jinja-setup + subcategory: + - audit + technology: + - flask + paths: + include: + - '*.html' + pattern-regex: '{%\s*autoescape\s+false\s*%}' + severity: WARNING + - id: python.flask.security.xss.audit.template-href-var.template-href-var + languages: + - generic + message: Detected a template variable used in an anchor tag with the 'href' attribute. This allows a malicious actor to input the 'javascript:' URI and is subject to cross- site scripting (XSS) attacks. Use 'url_for()' to safely generate a URL. You may also consider setting the Content Security Policy (CSP) header. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss + - https://content-security-policy.com/ + subcategory: + - audit + technology: + - flask + paths: + include: + - '*.html' + patterns: + - pattern-inside: + - pattern-either: + - pattern: href = {{ ... }} + - pattern: href = "{{ ... }}" + - pattern: href = '{{ ... }}' + - pattern-not-inside: href = {{ url_for(...) ... }} + - pattern-not-inside: href = "{{ url_for(...) ... }}" + - pattern-not-inside: href = '{{ url_for(...) ... }}' + severity: WARNING + - id: python.flask.security.xss.audit.template-unescaped-with-safe.template-unescaped-with-safe + languages: + - regex + message: Detected a segment of a Flask template where autoescaping is explicitly disabled with '| safe' filter. This allows rendering of raw HTML in this segment. Ensure no user data is rendered here, otherwise this is a cross-site scripting (XSS) vulnerability. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss + subcategory: + - audit + technology: + - flask + paths: + include: + - '*.html' + pattern-regex: '{{.*?\|\s*safe(\s*}})?' + severity: WARNING + - fix: | + ="{{$...VAR}}" + id: python.flask.security.xss.audit.template-unquoted-attribute-var.template-unquoted-attribute-var + languages: + - generic + message: 'Detected a unquoted template variable as an attribute. If unquoted, a malicious actor could inject custom JavaScript handlers. To fix this, add quotes around the template expression, like this: "{{ $...VAR }}".' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss + subcategory: + - audit + technology: + - flask + paths: + include: + - '*.html' + - '*.py' + patterns: + - pattern: ={{$...VAR}} + - pattern-inside: | + <$TAG ... > + - metavariable-pattern: + metavariable: $...VAR + pattern-either: + - pattern: | + request.$VALUE.get(...) + - pattern: | + request.$VALUE['...'] + - patterns: + - pattern: $REQ + - pattern-either: + - pattern-inside: "$REQ = request.$VALUE.get(...)\n... \n" + - pattern-inside: "$REQ = request.$VALUE['...']\n... \n" + severity: WARNING + - fix: | + True + id: python.jinja2.security.audit.autoescape-disabled-false.incorrect-autoescape-disabled + languages: + - python + message: Detected a Jinja2 environment with 'autoescaping' disabled. This is dangerous if you are rendering to a browser because this allows for cross-site scripting (XSS) attacks. If you are in a web context, enable 'autoescaping' by setting 'autoescape=True.' You may also consider using 'jinja2.select_autoescape()' to only enable automatic escaping for certain file extensions. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-116: Improper Encoding or Escaping of Output' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://jinja.palletsprojects.com/en/2.11.x/api/#basics + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html + subcategory: + - vuln + technology: + - jinja2 + patterns: + - pattern: jinja2.Environment(... , autoescape=$VAL, ...) + - pattern-not: jinja2.Environment(... , autoescape=True, ...) + - pattern-not: jinja2.Environment(... , autoescape=jinja2.select_autoescape(...), ...) + - focus-metavariable: $VAL + severity: WARNING + - fix-regex: + regex: (.*)\) + replacement: \1, autoescape=True) + id: python.jinja2.security.audit.missing-autoescape-disabled.missing-autoescape-disabled + languages: + - python + message: Detected a Jinja2 environment without autoescaping. Jinja2 does not autoescape by default. This is dangerous if you are rendering to a browser because this allows for cross-site scripting (XSS) attacks. If you are in a web context, enable autoescaping by setting 'autoescape=True.' You may also consider using 'jinja2.select_autoescape()' to only enable automatic escaping for certain file extensions. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-116: Improper Encoding or Escaping of Output' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://jinja.palletsprojects.com/en/2.11.x/api/#basics + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html + subcategory: + - vuln + technology: + - jinja2 + patterns: + - pattern-not: jinja2.Environment(..., autoescape=$VAL, ...) + - pattern: jinja2.Environment(...) + severity: WARNING + - id: python.jwt.security.audit.jwt-exposed-data.jwt-python-exposed-data + languages: + - python + message: The object is passed strictly to jwt.encode(...) Make sure that sensitive information is not exposed through JWT token payload. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + patterns: + - pattern-inside: | + def $FUNC(...,$INPUT,...): + ... + - pattern: jwt.encode($INPUT,...) + severity: WARNING + - id: python.jwt.security.jwt-exposed-credentials.jwt-python-exposed-credentials + languages: + - python + message: Password is exposed through JWT token payload. This is not encrypted and the password could be compromised. Do not store passwords in JWT tokens. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://cwe.mitre.org/data/definitions/522.html + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + pattern-either: + - pattern: | + jwt.encode({...,"password":$P,...},...) + - pattern: | + $PAYLOAD = {...,"password":$P,...} + ... + jwt.encode($PAYLOAD,...) + severity: ERROR + - id: python.jwt.security.jwt-hardcode.jwt-python-hardcoded-secret + languages: + - python + message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - vuln + technology: + - jwt + patterns: + - pattern: | + jwt.encode($X, $SECRET, ...) + - focus-metavariable: $SECRET + - pattern: | + "..." + severity: ERROR + - id: python.jwt.security.jwt-none-alg.jwt-python-none-alg + languages: + - python + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - vuln + technology: + - jwt + pattern-either: + - pattern: | + jwt.encode(...,algorithm="none",...) + - pattern: jwt.decode(...,algorithms=[...,"none",...],...) + severity: ERROR + - fix: | + True + id: python.jwt.security.unverified-jwt-decode.unverified-jwt-decode + languages: + - python + message: Detected JWT token decoded with 'verify=False'. This bypasses any integrity checks for the token which means the token could be tampered with by malicious actors. Ensure that the JWT token is verified. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-287: Improper Authentication' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A02:2017 - Broken Authentication + - A07:2021 - Identification and Authentication Failures + references: + - https://github.com/we45/Vulnerable-Flask-App/blob/752ee16087c0bfb79073f68802d907569a1f0df7/app/app.py#L96 + subcategory: + - audit + technology: + - jwt + patterns: + - pattern-either: + - patterns: + - pattern: | + jwt.decode(..., options={..., "verify_signature": $BOOL, ...}, ...) + - metavariable-pattern: + metavariable: $BOOL + pattern: | + False + - focus-metavariable: $BOOL + - patterns: + - pattern: | + $OPTS = {..., "verify_signature": $BOOL, ...} + ... + jwt.decode(..., options=$OPTS, ...) + - metavariable-pattern: + metavariable: $BOOL + pattern: | + False + - focus-metavariable: $BOOL + severity: ERROR + - id: python.lang.best-practice.hardcoded-tmp-path.hardcoded-tmp-path + languages: + - python + message: Detected hardcoded temp directory. Consider using 'tempfile.TemporaryFile' instead. + metadata: + category: best-practice + references: + - https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryFile + technology: + - python + pattern: open("=~/^\/tmp.*/", ...) + severity: WARNING + - id: python.lang.best-practice.logging-error-without-handling.logging-error-without-handling + languages: + - python + message: Errors should only be logged when handled. The code logs the error and propogates the exception, consider reducing the level to warning or info. + metadata: + category: best-practice + technology: + - python + patterns: + - pattern-inside: | + try: + ... + except ...: + ... + ... + - pattern-either: + - pattern: | + logger.$FUNC(...) + ... + raise + - pattern: | + logger.$FUNC(...) + ... + raise $EX + - pattern: | + logger.$FUNC(...) + ... + raise $EX from $EX2 + - metavariable-regex: + metavariable: $FUNC + regex: (error|exception) + severity: WARNING + - id: python.lang.best-practice.manual-collections-create.manual-defaultdict-dict-create + languages: + - python + message: manually creating a defaultdict - use collections.defaultdict(dict) + metadata: + category: best-practice + technology: + - python + pattern-either: + - pattern: | + $DICT = {} + ... + for $KEY, $VALUE in $OTHERDICT.items(): + ... + if $KEY not in $DICT: + ... + $DICT[$KEY] = {} + ... + $DICT[$KEY].update(...) + - pattern: | + $DICT = {} + ... + for $KEY, $VALUE in $OTHERDICT.items(): + ... + $DICT.setdefault($KEY, {}).update(...) + severity: WARNING + - id: python.lang.best-practice.manual-collections-create.manual-defaultdict-set-create + languages: + - python + message: manually creating a defaultdict - use collections.defaultdict(set) + metadata: + category: best-practice + technology: + - python + pattern-either: + - pattern: | + $DICT = {} + ... + for $KEY, $VALUE in $OTHERDICT.items(): + ... + if $KEY not in $DICT: + ... + $DICT[$KEY] = set() + ... + $DICT[$KEY].add(...) + - pattern: | + $DICT = {} + ... + for $KEY, $VALUE in $OTHERDICT.items(): + ... + $DICT.setdefault($KEY, set()).add(...) + severity: WARNING + - id: python.lang.best-practice.manual-collections-create.manual-defaultdict-list-create + languages: + - python + message: manually creating a defaultdict - use collections.defaultdict(list) + metadata: + category: best-practice + technology: + - python + pattern-either: + - pattern: | + $DICT = {} + ... + for $KEY, $VALUE in $OTHERDICT.items(): + ... + if $KEY not in $DICT: + ... + $DICT[$KEY] = [] + ... + $DICT[$KEY].append(...) + - pattern: | + $DICT = {} + ... + for $KEY, $VALUE in $OTHERDICT.items(): + ... + $DICT.setdefault($KEY, []).append(...) + severity: WARNING + - id: python.lang.best-practice.manual-collections-create.manual-counter-create + languages: + - python + message: manually creating a counter - use collections.Counter + metadata: + category: best-practice + technology: + - python + pattern: | + $DICT = {} + ... + for $KEY, $VALUE in $OTHERDICT.items(): + ... + if $KEY not in $DICT: + ... + $DICT[$KEY] = 0 + ... + $DICT[$KEY] += 1 + severity: WARNING + - id: python.lang.best-practice.missing-hash-with-eq.missing-hash-with-eq + languages: + - python + message: 'Class `$A` has defined `__eq__` which means it should also have defined `__hash__`; ' + metadata: + category: best-practice + technology: + - python + patterns: + - pattern-not-inside: | + class A(...): + ... + def __hash__(self): + ... + ... + def __eq__(self, $O): + ... + - pattern: | + class A(...): + ... + def __eq__(self, $O): ... + ... + severity: WARNING + - id: python.lang.best-practice.open-never-closed.open-never-closed + languages: + - python + message: file object opened without corresponding close + metadata: + category: best-practice + technology: + - python + patterns: + - pattern-not-inside: | + $F = open(...) + ... + $F.close() + - pattern-not-inside: | + $F = io.open(...) + ... + $F.close() + - pattern-not-inside: | + $F = tarfile.open(...) + ... + $F.close() + - pattern-not-inside: | + $F = ZipFile.open(...) + ... + $F.close() + - pattern-not-inside: | + $F = tempfile.TemporaryFile(...) + ... + $F.close() + - pattern-not-inside: | + $F = tempfile.NamedTemporaryFile(...) + ... + $F.close() + - pattern-not-inside: | + $F = tempfile.SpooledTemporaryFile(...) + ... + $F.close() + - pattern-not-inside: | + $F = open(...) + ... + try: + ... + finally: + $F.close() + - pattern-not-inside: | + $F = io.open(...) + ... + try: + ... + finally: + $F.close() + - pattern-not-inside: | + $F = tarfile.open(...) + ... + try: + ... + finally: + $F.close() + - pattern-not-inside: | + $F = ZipFile.open(...) + ... + try: + ... + finally: + $F.close() + - pattern-not-inside: | + $F = tempfile.TemporaryFile(...) + ... + try: + ... + finally: + $F.close() + - pattern-not-inside: | + $F = tempfile.NamedTemporaryFile(...) + ... + try: + ... + finally: + $F.close() + - pattern-not-inside: | + $F = tempfile.SpooledTemporaryFile(...) + ... + try: + ... + finally: + $F.close() + - pattern-either: + - pattern: $F = open(...) + - pattern: $F = io.open(...) + - pattern: $F = tarfile.open(...) + - pattern: $F = ZipFile.open(...) + - pattern: $F = tempfile.TemporaryFile(...) + - pattern: $F = tempfile.NamedTemporaryFile(...) + - pattern: $F = tempfile.SpooledTemporaryFile(...) + severity: ERROR + - id: python.lang.best-practice.pass-body.pass-body-fn + languages: + - python + message: '`pass` is the body of function $X. Consider removing this or raise NotImplementedError() if this is a TODO' + metadata: + category: best-practice + technology: + - python + patterns: + - pattern-not-inside: | + def __init__(self, ...): + ... + - pattern-not-inside: | + class $A: + ... + - pattern: | + def $X(...): + pass + severity: WARNING + - id: python.lang.best-practice.pass-body.pass-body-range + languages: + - python + message: '`pass` is the body of for $X in $Y. Consider removing this or raise NotImplementedError() if this is a TODO' + metadata: + category: best-practice + technology: + - python + pattern: | + for $X in $Y: + pass + severity: WARNING + - id: python.lang.best-practice.pdb.python-debugger-found + languages: + - python + message: Importing the python debugger; did you mean to leave this in? + metadata: + category: best-practice + technology: + - python + pattern-either: + - pattern: import pdb + - pattern: pdb.set_trace() + severity: WARNING + - id: python.lang.best-practice.sleep.arbitrary-sleep + languages: + - python + message: time.sleep() call; did you mean to leave this in? + metadata: + category: best-practice + technology: + - python + patterns: + - pattern-not: time.sleep($F(...)) + - pattern-either: + - pattern: | + time.sleep($X: int) + - pattern: | + time.sleep($X: float) + severity: ERROR + - id: python.lang.best-practice.unspecified-open-encoding.unspecified-open-encoding + languages: + - python + message: Missing 'encoding' parameter. 'open()' uses device locale encodings by default, corrupting files with special characters. Specify the encoding to ensure cross-platform support when opening files in text mode (e.g. encoding="utf-8"). + metadata: + category: best-practice + references: + - https://www.python.org/dev/peps/pep-0597/ + - https://docs.python.org/3/library/functions.html#open + technology: + - python + patterns: + - pattern-inside: open(...) + - pattern-not: open(..., encoding="...", ...) + - pattern-not: open($F, "...", $B, "...", ...) + - pattern-either: + - pattern: open($FILE) + - patterns: + - pattern: open($FILE, ...) + - pattern-not: open($FILE, $M, ...) + - pattern-not-regex: open\(.*(?:encoding|mode)=.*\) + - patterns: + - pattern: open($FILE, $MODE, ...) + - metavariable-regex: + metavariable: $MODE + regex: (?!.*b.*) + - patterns: + - pattern: open($FILE, ..., mode=$MODE, ...) + - metavariable-regex: + metavariable: $MODE + regex: (?!.*b.*) + severity: WARNING + - id: python.lang.compatibility.python36.python36-compatibility-ssl + languages: + - python + message: this function is only available on Python 3.6+ + metadata: + category: compatibility + technology: + - python + pattern: ssl.get_ciphers() + severity: ERROR + - id: python.lang.compatibility.python36.python36-compatibility-popen1 + languages: + - python + message: the `errors` argument to Popen is only available on Python 3.6+ + metadata: + category: compatibility + technology: + - python + pattern: subprocess.Popen(errors=$X, ...) + severity: ERROR + - id: python.lang.compatibility.python36.python36-compatibility-popen2 + languages: + - python + message: the `encoding` argument to Popen is only available on Python 3.6+ + metadata: + category: compatibility + technology: + - python + pattern: subprocess.Popen(encoding=$X, ...) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-importlib + languages: + - python + message: source_hash' is only available on Python 3.7+. This does not work in lower versions, and therefore is not backwards compatible. Instead, use another hash function. + metadata: + category: compatibility + technology: + - python + pattern: importlib.source_hash() + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-importlib2 + languages: + - python + message: Found 'importlib.resources', which is a module only available on Python 3.7+. This does not work in lower versions, and therefore is not backwards compatible. Use importlib_resources instead for older Python versions. + metadata: + category: compatibility + technology: + - python + pattern: import importlib.resources + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-httpconn + languages: + - python + message: Found usage of the 'blocksize' argument in a HTTPConnection call. This is only available on Python 3.7+ and is therefore not backwards compatible. Remove this in order for this code to work in Python 3.6 and below. + metadata: + category: compatibility + technology: + - python + pattern: http.client.HTTPConnection(blocksize=$X,...) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-httpsconn + languages: + - python + message: Found usage of the 'blocksize' argument in a HTTPSConnection call. This is only available on Python 3.7+ and is therefore not backwards compatible. Remove this in order for this code to work in Python 3.6 and below. + metadata: + category: compatibility + technology: + - python + pattern: http.client.HTTPSConnection(blocksize=$X,...) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-importlib3 + languages: + - python + message: Found usage of 'importlib.abc.ResourceReader'. This module is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use another loader. + metadata: + category: compatibility + technology: + - python + pattern: import importlib.abc.ResourceReader + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-textiowrapper + languages: + - python + message: Found usage of 'importlib.abc.ResourceReader'. This module is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use another loader. + metadata: + category: compatibility + technology: + - python + pattern: TextIOWrapper.reconfigure(...) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-ipv6network1 + languages: + - python + message: IPv6Network.subnet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the subnet is in 'subnets'. + metadata: + category: compatibility + technology: + - python + pattern: ipaddress.IPv6Network.subnet_of($X) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-ipv6network2 + languages: + - python + message: IPv6Network.supernet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the supernet is in 'supernet'. + metadata: + category: compatibility + technology: + - python + pattern: ipaddress.IPv6Network.supernet_of($X) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-ipv4network1 + languages: + - python + message: IPv4Network.subnet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the subnet is in 'subnets'. + metadata: + category: compatibility + technology: + - python + pattern: ipaddress.IPv4Network.subnet_of($X) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-ipv4network2 + languages: + - python + message: IPv4Network.supernet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the supernet is in 'supernet'. + metadata: + category: compatibility + technology: + - python + pattern: ipaddress.IPv4Network.supernet_of($X) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-locale1 + languages: + - python + message: Found usage of the 'monetary' argument in a function call of 'locale.format_string'. This is only available on Python 3.7+ and is therefore not backwards compatible. Instead, remove the 'monetary' argument. + metadata: + category: compatibility + technology: + - python + pattern: locale.format_string(monetary=$X, ...) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-math1 + languages: + - python + message: math.remainder is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use math.fmod() or calculate $X - n* $Y. + metadata: + category: compatibility + technology: + - python + pattern: math.remainder($X, $Y) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-multiprocess1 + languages: + - python + message: multiprocessing.Process.close() is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use join(). + metadata: + category: compatibility + technology: + - python + pattern: multiprocessing.Process.close() + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-multiprocess2 + languages: + - python + message: multiprocessing.Process.kill() is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use terminate(). + metadata: + category: compatibility + technology: + - python + pattern: multiprocessing.Process.kill() + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-os1 + languages: + - python + message: os.preadv() is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use a combination of os.readv() and os.pread(). + metadata: + category: compatibility + technology: + - python + pattern: os.preadv(...) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-os2-ok2 + languages: + - python + message: os.pwritev() is only available on Python 3.3+ and is therefore not backwards compatible. Instead, use a combination of pwrite() and writev(). + metadata: + category: compatibility + technology: + - python + patterns: + - pattern-not-inside: | + if hasattr(os, 'pwritev'): + ... + - pattern: os.pwritev(...) + severity: ERROR + - id: python.lang.compatibility.python37.python37-compatibility-pdb + languages: + - python + message: pdb.set_trace() with the header argument is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use set_trace() without the header argument. + metadata: + category: compatibility + technology: + - python + pattern: pdb.set_trace(header=$X, ...) + severity: ERROR + - id: python.lang.correctness.baseclass-attribute-override.baseclass-attribute-override + languages: + - python + message: Class $C inherits from both `$A` and `$B` which both have a method named `$F`; one of these methods will be overwritten. + metadata: + category: correctness + references: + - https://docs.python.org/3/tutorial/classes.html#multiple-inheritance + technology: + - python + patterns: + - pattern-inside: | + class $A(...): + ... + def $F(...): + ... + ... + ... + - pattern-inside: | + class $B(...): + ... + def $F(...): + ... + ... + ... + - pattern: | + class $C(..., $A, ..., $B, ...): + ... + - focus-metavariable: $C + severity: WARNING + - id: python.lang.correctness.cannot-cache-generators.cannot-cache-generators + languages: + - python + message: Generators can only be consumed once, so in most cases, caching them will cause an error when the already-consumed generator is retrieved from cache. + metadata: + category: correctness + technology: + - python + patterns: + - pattern-inside: | + @functools.lru_cache(...) + def $FUNC(...): + ... + yield ... + - pattern: functools.lru_cache(...) + severity: WARNING + - id: python.lang.correctness.common-mistakes.default-mutable-dict.default-mutable-dict + languages: + - python + message: 'Function $F mutates default dict $D. Python only instantiates default function arguments once and shares the instance across the function calls. If the default function argument is mutated, that will modify the instance used by all future function calls. This can cause unexpected results, or lead to security vulnerabilities whereby one function consumer can view or modify the data of another function consumer. Instead, use a default argument (like None) to indicate that no argument was provided and instantiate a new dictionary at that time. For example: `if $D is None: $D = {}`.' + metadata: + category: correctness + references: + - https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments + technology: + - python + options: + symbolic_propagation: true + patterns: + - pattern-not-inside: | + def $A(...): + ... + def $F(..., $D={}, ...): + ... + - pattern-inside: | + def $F(..., $D={}, ...): + ... + - pattern-not-inside: | + $D = {} + ... + - pattern-not-inside: | + $D = dict(...) + ... + - pattern-not-inside: | + $D = $D.copy() + ... + - pattern-not-inside: | + $D = copy.deepcopy($D) + ... + - pattern-not-inside: | + $D = copy.copy($D) + ... + - pattern-not-inside: | + $D = dict.copy($D) + ... + - pattern-not-inside: | + $D = {... for ... in ...} + ... + - pattern-not-inside: | + $D = $D or {} + ... + - pattern-either: + - pattern: | + $D[...] = ... + - pattern: | + $D.update(...) + - pattern: | + $D.setdefault(...) + severity: ERROR + - id: python.lang.correctness.common-mistakes.default-mutable-list.default-mutable-list + languages: + - python + message: 'Function $F mutates default list $D. Python only instantiates default function arguments once and shares the instance across the function calls. If the default function argument is mutated, that will modify the instance used by all future function calls. This can cause unexpected results, or lead to security vulnerabilities whereby one function consumer can view or modify the data of another function consumer. Instead, use a default argument (like None) to indicate that no argument was provided and instantiate a new list at that time. For example: `if $D is None: $D = []`.' + metadata: + category: correctness + references: + - https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments + technology: + - python + options: + symbolic_propagation: true + patterns: + - pattern-not-inside: | + def $A(...): + ... + def $F(..., $D=[], ...): + ... + - pattern-inside: | + def $F(..., $D=[], ...): + ... + - pattern-not-inside: | + $D = [] + ... + - pattern-not-inside: | + $D = [...] + ... + - pattern-not-inside: | + $D = list(...) + ... + - pattern-not-inside: | + $D = copy.deepcopy($D) + ... + - pattern-not-inside: | + $D = copy.copy($D) + ... + - pattern-not-inside: | + $D = list.copy($D) + ... + - pattern-not-inside: | + $D = $D[:] + ... + - pattern-not-inside: | + $D = [... for ... in ...] + ... + - pattern-not-inside: | + $D = $D or [] + ... + - pattern-either: + - pattern: | + $D.append(...) + - pattern: | + $D.extend(...) + - pattern: | + $D.insert(...) + severity: ERROR + - id: python.lang.correctness.common-mistakes.is-comparison-string.identical-is-comparison + languages: + - python + message: Found identical comparison using is. Ensure this is what you intended. + metadata: + category: correctness + technology: + - python + pattern: $S is $S + severity: ERROR + - id: python.lang.correctness.common-mistakes.is-comparison-string.string-is-comparison + languages: + - python + message: Found string comparison using 'is' operator. The 'is' operator is for reference equality, not value equality, and therefore should not be used to compare strings. For more information, see https://github.com/satwikkansal/wtfpython#-how-not-to-use-is-operator" + metadata: + category: correctness + technology: + - python + patterns: + - pattern-not: $S is None + - pattern-not: type($X) is $T + - pattern-not: $S is True + - pattern-not: $S is False + - pattern-not: $S is "" + - pattern-either: + - pattern: $S is "..." + - pattern: '"..." is $S' + severity: ERROR + - id: python.lang.correctness.common-mistakes.is-not-is-not.is-not-is-not + languages: + - python + message: In Python 'X is not ...' is different from 'X is (not ...)'. In the latter the 'not' converts the '...' directly to boolean. + metadata: + category: correctness + technology: + - python + pattern: $S is (not ...) + severity: ERROR + - id: python.lang.correctness.common-mistakes.string-concat-in-list.string-concat-in-list + languages: + - python + message: Detected strings that are implicitly concatenated inside a list. Python will implicitly concatenate strings when not explicitly delimited. Was this supposed to be individual elements of the list? + metadata: + category: correctness + technology: + - python + patterns: + - pattern-either: + - pattern-inside: '[...]' + - pattern-inside: '{...}' + - pattern: '"..." "..."' + - pattern-not-inside: f"..." + - pattern-not-inside: '{..., $KEY: $VALUE, ...}' + severity: WARNING + - id: python.lang.correctness.concurrent.uncaught-executor-exceptions + languages: + - python + message: 'Values returned by thread pool map must be read in order to raise exceptions. Consider using `for _ in $EXECUTOR.map(...): pass`.' + metadata: + category: correctness + references: + - https://superfastpython.com/threadpoolexecutor-exception-handling/ + technology: + - python + patterns: + - pattern-inside: | + with concurrent.futures.thread.ThreadPoolExecutor(...) as $EXECUTOR: + ... + - pattern-not-inside: | + $VAR = $EXECUTOR.map(...) + ... + for ... in $VAR: + ... + - pattern-not-inside: | + $VAR = $EXECUTOR.map(...) + ... + [... for ... in $VAR] + - pattern-not-inside: | + [... for ... in $EXECUTOR.map(...)] + - pattern-not-inside: | + for $IT in $EXECUTOR.map(...): + ... + - pattern: $EXECUTOR.map(...) + severity: WARNING + - id: python.lang.correctness.dict-modify-iterating.dict-del-while-iterate + languages: + - python + message: 'It appears that `$DICT[$KEY]` is a dict with items being deleted while in a for loop. This is usually a bad idea and will likely lead to a RuntimeError: dictionary changed size during iteration' + metadata: + category: correctness + references: + - https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects + technology: + - python + pattern-either: + - pattern: | + for $KEY, $VALUE in $DICT.items(): + ... + del $DICT[$KEY] + - pattern: | + for $KEY in $DICT.keys(): + ... + del $DICT[$KEY] + severity: WARNING + - id: python.lang.correctness.exceptions.exceptions.raise-not-base-exception + languages: + - python + message: In Python3, a runtime `TypeError` will be thrown if you attempt to raise an object or class which does not inherit from `BaseException` + metadata: + category: correctness + technology: + - python + pattern-either: + - pattern: raise "..." + - pattern: | + $X: BaseException + raise $X(...) + - patterns: + - pattern: raise $EXCEPTION + - metavariable-regex: + metavariable: $EXCEPTION + regex: '[0-9]*\.?[0-9]+' + severity: ERROR + - fix: sys.exit($X) + id: python.lang.correctness.exit.use-sys-exit + languages: + - python + message: Detected use of `exit`. Use `sys.exit` over the python shell `exit` built-in. `exit` is a helper for the interactive shell and may not be available on all Python implementations. + metadata: + category: correctness + references: + - https://stackoverflow.com/questions/6501121/difference-between-exit-and-sys-exit-in-python + technology: + - python + patterns: + - pattern: exit($X) + - pattern-not: sys.exit($X) + severity: WARNING + - id: python.lang.correctness.file-object-redefined-before-close.file-object-redefined-before-close + languages: + - python + message: Detected a file object that is redefined and never closed. This could leak file descriptors and unnecessarily consume system resources. + metadata: + category: correctness + technology: + - python + patterns: + - pattern: | + $F = open($X, ...) + ... + $F = open($Y, ...) + - pattern-not: | + $F = open($X, ...) + ... + $F.close() + ... + $F = open($Y, ...) + severity: WARNING + - id: python.lang.correctness.list-modify-iterating.list-modify-while-iterate + languages: + - python + message: It appears that `$LIST` is a list that is being modified while in a for loop. This will likely cause a runtime error or an infinite loop. + metadata: + category: correctness + references: + - https://unspecified.wordpress.com/2009/02/12/thou-shalt-not-modify-a-list-during-iteration/ + technology: + - python + pattern-either: + - pattern: | + for $ELEMENT in $LIST: + ... + $LIST.pop(...) + - pattern: | + for $ELEMENT in $LIST: + ... + $LIST.push(...) + - pattern: | + for $ELEMENT in $LIST: + ... + $LIST.append(...) + - pattern: | + for $ELEMENT in $LIST: + ... + $LIST.extend(...) + - pattern: | + for $ELEMENT in $LIST: + ... + $LIST.remove(...) + severity: ERROR + - id: python.lang.correctness.pdb.pdb-remove + languages: + - python + message: pdb is an interactive debugging tool and you may have forgotten to remove it before committing your code + metadata: + category: correctness + technology: + - python + pattern-either: + - pattern: pdb.$X(...) + - pattern: pdb.Pdb.$X(...) + severity: WARNING + - id: python.lang.correctness.pytest-assert_match-after-path-patch.pytest-assert_match-after-path-patch + languages: + - python + message: snapshot.assert_match makes use of pathlib to create files. Patching $METHOD may result in unexpected snapshot behavior + metadata: + category: correctness + references: + - https://github.com/returntocorp/semgrep/pull/5459 + - https://pypi.org/project/pytest-snapshot/ + technology: + - python + patterns: + - pattern-inside: | + import pytest + ... + - pattern-either: + - pattern-inside: | + mocker.patch("pathlib.Path", $MOCKED_VALUE) + ... + - pattern-inside: | + mocker.patch.object(pathlib.Path, $METHOD, $MOCKED_VALUE) + ... + - pattern: snapshot.assert_match(...) + severity: WARNING + - id: python.lang.correctness.return-in-init.return-in-init + languages: + - python + message: '`return` should never appear inside a class __init__ function. This will cause a runtime error.' + metadata: + category: correctness + technology: + - python + patterns: + - pattern-inside: | + class $A(...): + ... + - pattern-inside: | + def __init__(...): + ... + - pattern-not-inside: | + def __init__(...): + ... + def $F(...): + ... + - patterns: + - pattern: return ... + - pattern-not: return + - pattern-not: return None + severity: ERROR + - id: python.lang.correctness.return-in-init.yield-in-init + languages: + - python + message: '`yield` should never appear inside a class __init__ function. This will cause a runtime error.' + metadata: + category: correctness + technology: + - python + patterns: + - pattern-inside: | + class $A(...): + ... + - pattern-inside: | + def __init__(...): + ... + - pattern-not-inside: | + def __init__(...): + ... + def $F(...): + ... + - pattern-either: + - pattern: yield ... + - pattern: yield + severity: ERROR + - id: python.lang.correctness.sync-sleep-in-async-code.sync-sleep-in-async-code + languages: + - python + message: Synchronous time.sleep in async code will block the event loop and not allow other tasks to execute. Use asyncio.sleep() instead. + metadata: + category: best-practice + technology: + - python + patterns: + - pattern: time.sleep(...) + - pattern-inside: | + async def $F(...): + ... + - pattern-not-inside: | + async def $F(...): + def $INNER(...): + ... + severity: WARNING + - id: python.lang.correctness.tempfile.flush.tempfile-without-flush + languages: + - python + message: Using '$F.name' without '.flush()' or '.close()' may cause an error because the file may not exist when '$F.name' is used. Use '.flush()' or close the file before using '$F.name'. + metadata: + category: correctness + technology: + - python + pattern-either: + - patterns: + - pattern-not-inside: | + $F = tempfile.NamedTemporaryFile(...) + ... + $F.write(...) + ... + $F.flush() + ... + $F.name + - pattern-not-inside: | + $F = tempfile.NamedTemporaryFile(...) + ... + $F.write(...) + ... + $F.close() + ... + $F.name + - pattern-not-inside: | + $F = tempfile.NamedTemporaryFile(..., delete=False, ...) + ... + $F.close() + ... + $F.name + - pattern-inside: | + $F = tempfile.NamedTemporaryFile(...) + ... + - pattern: | + $F.name + - patterns: + - pattern-not-inside: | + with tempfile.NamedTemporaryFile(...) as $F: + ... + $F.write(...) + ... + $F.flush() + ... + $F.name + - pattern-not-inside: | + with tempfile.NamedTemporaryFile(...) as $F: + ... + $F.write(...) + ... + $F.close() + ... + $F.name + - pattern-not-inside: | + with tempfile.NamedTemporaryFile(...) as $F: + ... + $MODULE.dump(..., $F, ...) + ... + $F.flush() + ... + $F.name + - pattern-not-inside: | + with tempfile.NamedTemporaryFile(...) as $F: + ... + $MODULE.dump(..., $F, ...) + ... + $F.close() + ... + $F.name + - pattern-inside: | + with tempfile.NamedTemporaryFile(...) as $F: + ... + - pattern: | + $F.name + severity: ERROR + - id: python.lang.correctness.tempfile.mktemp.tempfile-insecure + languages: + - python + message: 'Use tempfile.NamedTemporaryFile instead. From the official Python documentation: THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED. The file name may refer to a file that did not exist at some point, but by the time you get around to creating it, someone else may have beaten you to the punch.' + metadata: + category: correctness + technology: + - python + pattern: tempfile.mktemp(...) + severity: ERROR + - id: python.lang.correctness.test-is-missing-assert.test-is-missing-assert + languages: + - python + message: Comparison without assertion. The result of this comparison is not used. Perhaps this expression is missing an `assert` keyword. + metadata: + category: correctness + technology: + - python + paths: + include: + - test*.py + patterns: + - pattern: $A == $B + - pattern-not-inside: assert ... + - pattern-not-inside: $X = ... + - pattern-not-inside: $X += ... + - pattern-not-inside: $X |= ... + - pattern-not-inside: $X &= ... + - pattern-not-inside: yield $X + - pattern-not-inside: $X and $Y + - pattern-not-inside: $X or $Y + - pattern-not-inside: return ... + - pattern-not-inside: $FUNC(...) + - pattern-not-inside: | + while $EXPR: + ... + - pattern-not-inside: | + with (...): + ... + - pattern-not-inside: | + [...] + - pattern-not-inside: | + $EXPR[...] + - pattern-not-inside: | + if ...: + ... + severity: WARNING + - fix: check_call + id: python.lang.correctness.unchecked-returns.unchecked-subprocess-call + languages: + - python + message: This is not checking the return value of this subprocess call; if it fails no exception will be raised. Consider subprocess.check_call() instead + metadata: + category: correctness + references: + - https://docs.python.org/3/library/subprocess.html#subprocess.check_call + technology: + - python + patterns: + - pattern: subprocess.$CALL(...) + - pattern-not-inside: $S = subprocess.call(...) + - pattern-not-inside: subprocess.call(...) == $X + - pattern-not-inside: return subprocess.call(...) + - metavariable-pattern: + metavariable: $CALL + pattern: call + - focus-metavariable: $CALL + severity: WARNING + - id: python.lang.correctness.useless-comparison.no-strings-as-booleans + languages: + - python + message: Using strings as booleans in Python has unexpected results. `"one" and "two"` will return "two". `"one" or "two"` will return "one". In Python, strings are truthy, and strings with a non-zero length evaluate to True. + metadata: + category: correctness + technology: + - python + pattern-either: + - pattern: | + if <... "..." and ... ...>: + ... + - pattern: | + if <... "..." or ... ...>: + ... + - patterns: + - pattern-not: | + if $X in "...": + ... + - pattern: | + if "...": + ... + severity: ERROR + - id: python.lang.correctness.useless-eqeq.useless-eqeq + languages: + - python + message: 'This expression is always True: `$X == $X` or `$X != $X`. If testing for floating point NaN, use `math.isnan($X)`, or `cmath.isnan($X)` if the number is complex.' + metadata: + category: correctness + technology: + - python + patterns: + - pattern-not-inside: | + def __eq__(...): + ... + - pattern-not-inside: | + def __cmp__(...): + ... + - pattern-not-inside: assert(...) + - pattern-not-inside: assert ..., ... + - pattern-not-inside: assertTrue(...) + - pattern-not-inside: assertFalse(...) + - pattern-either: + - pattern: $X == $X + - pattern: $X != $X + - pattern-not: 1 == 1 + severity: INFO + - id: python.lang.correctness.writing-to-file-in-read-mode.writing-to-file-in-read-mode + languages: + - python + message: The file object '$FD' was opened in read mode, but is being written to. This will cause a runtime error. + metadata: + category: correctness + technology: + - python + patterns: + - pattern-either: + - pattern-inside: | + $FD = open($NAME, "r", ...) + ... + - pattern-inside: | + $FD = open($NAME, "rb", ...) + ... + - pattern-inside: | + with open($NAME, "r", ...) as $FD: + ... + - pattern-inside: | + with open($NAME, "rb", ...) as $FD: + ... + - pattern: $FD.write(...) + severity: ERROR + - id: python.lang.maintainability.improper-list-concat.improper-list-concat + languages: + - python + message: 'This expression will evaluate to be ONLY value the of the `else` clause if the condition `$EXPRESSION` is false. If you meant to do list concatenation, put parentheses around the entire concatenation expression, like this: `[''a'', ''b'', ''c''] + ([''d''] if x else [''e''])`. If this is the intended behavior, the expression may be confusing to others, and you may wish to add parentheses for readability.' + metadata: + category: maintainability + technology: + - python + pattern: '[...] + [...] if $EXPRESSION else [...]' + severity: INFO + - id: python.lang.maintainability.is-function-without-parentheses.is-function-without-parentheses + languages: + - python + message: Is "$FUNC" a function or an attribute? If it is a function, you may have meant $X.$FUNC() because $X.$FUNC is always true. + metadata: + category: maintainability + technology: + - python + patterns: + - pattern: $X.$FUNC + - pattern-not-inside: $X.$FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: is_.* + severity: WARNING + - id: python.lang.maintainability.return.code-after-unconditional-return + languages: + - python + message: code after return statement will not be executed + metadata: + category: maintainability + technology: + - python + pattern: | + return ... + $S + severity: WARNING + - id: python.lang.maintainability.return.return-not-in-function + languages: + - python + message: '`return` only makes sense inside a function' + metadata: + category: maintainability + technology: + - python + patterns: + - pattern-not-inside: | + def $F(...): + ... + # TODO: first pattern should just automatically include this one + - pattern-not-inside: | + def $F(...) -> $Y: + ... + - pattern: return ... + severity: WARNING + - id: python.lang.maintainability.useless-assign-keyed.useless-assignment-keyed + languages: + - python + message: key `$Y` in `$X` is assigned twice; the first assignment is useless + metadata: + category: maintainability + technology: + - python + pattern-either: + - pattern: | + $X[$Y] = ... + $X[$Y] = ... + - pattern: | + $X[$Y][$Z] = ... + $X[$Y][$Z] = ... + severity: INFO + - id: python.lang.maintainability.useless-ifelse.useless-if-conditional + languages: + - python + message: if block checks for the same condition on both branches (`$X`) + metadata: + category: maintainability + references: + - https://docs.python.org/3/tutorial/controlflow.html + technology: + - python + pattern: | + if $X: + ... + elif $X: + ... + severity: WARNING + - id: python.lang.maintainability.useless-ifelse.useless-if-body + languages: + - python + message: Useless if statement; both blocks have the same body + metadata: + category: maintainability + references: + - https://docs.python.org/3/tutorial/controlflow.html + technology: + - python + pattern: | + if $X: + $S + else: + $S + severity: WARNING + - id: python.lang.maintainability.useless-innerfunction.useless-inner-function + languages: + - python + message: function `$FF` is defined inside a function but never used + metadata: + category: maintainability + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + technology: + - python + patterns: + - pattern-not-inside: | + def $F(...): + ... + def $FF(...): + ... + ... + <... $FF ...> + - pattern-not-inside: | + def $F(...): + ... + class $CLAZZ(...): + ... + - pattern-inside: | + def $F(...): + ... + def $FF(...): + ... + ... + - pattern: | + def $FF(...): + ... + - pattern-not: | + @$DECORATOR + def $FF(...): + ... + severity: ERROR + - id: python.lang.maintainability.useless-literal-set.useless-literal-set + languages: + - python + message: '`$X` is uselessly assigned twice inside the creation of the set' + metadata: + category: maintainability + references: + - https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset + technology: + - python + patterns: + - pattern: | + set(..., ($X, $A), ..., ($X, $B), ...) + - focus-metavariable: $X + severity: ERROR + - id: python.lang.maintainability.useless-literal.useless-literal + languages: + - python + message: key `$X` is uselessly assigned twice + metadata: + category: maintainability + references: + - https://docs.python.org/3/library/stdtypes.html#mapping-types-dict + technology: + - python + patterns: + - pattern-either: + - pattern: | + {..., $X: $A, ..., $X: $B, ...} + - pattern: | + dict(..., ($X, $A), ..., ($X, $B), ...) + - focus-metavariable: $X + severity: WARNING + - id: python.lang.security.audit.conn_recv.multiprocessing-recv + languages: + - python + message: 'The Connection.recv() method automatically unpickles the data it receives, which can be a security risk unless you can trust the process which sent the message. Therefore, unless the connection object was produced using Pipe() you should only use the recv() and send() methods after performing some sort of authentication. See more dettails: https://docs.python.org/3/library/multiprocessing.html?highlight=security#multiprocessing.connection.Connection' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.python.org/3/library/multiprocessing.html?highlight=security#multiprocessing.connection.Connection + subcategory: + - audit + technology: + - python + pattern-either: + - pattern: multiprocessing.connection.Connection.recv(...) + - pattern: multiprocessing.connection.Client.recv(...) + - pattern: | + $C = multiprocessing.connection.Client(...) + ... + $C.recv(...) + severity: WARNING + - id: python.lang.security.audit.dangerous-annotations-usage.dangerous-annotations-usage + languages: + - python + message: Annotations passed to `typing.get_type_hints` are evaluated in `globals` and `locals` namespaces. Make sure that no arbitrary value can be written as the annotation and passed to `typing.get_type_hints` function. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://docs.python.org/3/library/typing.html#typing.get_type_hints + subcategory: + - audit + technology: + - python + patterns: + - pattern: | + $C.__annotations__[$NAME] = $X + - pattern-not: | + $C.__annotations__[$NAME] = "..." + - pattern-not: | + $C.__annotations__[$NAME] = typing.$Y + - metavariable-regex: + metavariable: $X + regex: (?!(int|float|complex|list|tuple|range|str|bytes|bytearray|memoryview|set|frozenset|dict)) + severity: INFO + - id: python.lang.security.audit.dangerous-asyncio-create-exec-audit.dangerous-asyncio-create-exec-audit + languages: + - python + message: Detected 'create_subprocess_exec' function without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.create_subprocess_exec + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - audit + technology: + - python + pattern-either: + - patterns: + - pattern-not: asyncio.create_subprocess_exec($PROG, "...", ...) + - pattern-not: asyncio.create_subprocess_exec($PROG, ["...",...], ...) + - pattern: asyncio.create_subprocess_exec(...) + - patterns: + - pattern-not: asyncio.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) + - pattern: asyncio.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) + - patterns: + - pattern-not: asyncio.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) + - pattern: asyncio.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) + - patterns: + - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, "...", ...) + - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, ["...",...], ...) + - pattern: asyncio.subprocess.create_subprocess_exec(...) + - patterns: + - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) + - pattern: asyncio.subprocess.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) + - patterns: + - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) + - pattern: asyncio.subprocess.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) + severity: ERROR + - id: python.lang.security.audit.dangerous-asyncio-create-exec-tainted-env-args.dangerous-asyncio-create-exec-tainted-env-args + languages: + - python + message: Detected 'create_subprocess_exec' function with user controlled data. You may consider using 'shlex.escape()'. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.create_subprocess_exec + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - pattern-either: + - patterns: + - pattern-not: asyncio.create_subprocess_exec($PROG, "...", ...) + - pattern-not: asyncio.create_subprocess_exec($PROG, ["...",...], ...) + - pattern: asyncio.create_subprocess_exec(...) + - patterns: + - pattern-not: asyncio.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) + - pattern: asyncio.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) + - patterns: + - pattern-not: asyncio.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) + - pattern: asyncio.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) + - patterns: + - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, "...", ...) + - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, ["...",...], ...) + - pattern: asyncio.subprocess.create_subprocess_exec(...) + - patterns: + - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) + - pattern: asyncio.subprocess.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) + - patterns: + - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) + - pattern: asyncio.subprocess.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.audit.dangerous-asyncio-exec-audit.dangerous-asyncio-exec-audit + languages: + - python + message: Detected subprocess function '$LOOP.subprocess_exec' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - audit + technology: + - python + pattern-either: + - patterns: + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "...", ...) + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["...",...], ...) + - pattern: $LOOP.subprocess_exec(...) + - patterns: + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) + - pattern: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) + - patterns: + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) + - pattern: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) + severity: ERROR + - id: python.lang.security.audit.dangerous-asyncio-exec-tainted-env-args.dangerous-asyncio-exec-tainted-env-args + languages: + - python + message: Detected subprocess function '$LOOP.subprocess_exec' with user controlled data. You may consider using 'shlex.escape()'. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - pattern-either: + - patterns: + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "...", ...) + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["...",...], ...) + - pattern: $LOOP.subprocess_exec(...) + - patterns: + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) + - pattern: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) + - patterns: + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) + - pattern: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.audit.dangerous-asyncio-shell-audit.dangerous-asyncio-shell-audit + languages: + - python + message: Detected asyncio subprocess function without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.python.org/3/library/asyncio-subprocess.html + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - audit + technology: + - python + patterns: + - pattern-either: + - pattern: $LOOP.subprocess_shell($PROTOCOL, $CMD) + - pattern: asyncio.subprocess.create_subprocess_shell($CMD, ...) + - pattern: asyncio.create_subprocess_shell($CMD, ...) + - pattern-not-inside: | + $CMD = "..." + ... + - pattern-not: $LOOP.subprocess_shell($PROTOCOL, "...") + - pattern-not: asyncio.subprocess.create_subprocess_shell("...", ...) + - pattern-not: asyncio.create_subprocess_shell("...", ...) + severity: ERROR + - id: python.lang.security.audit.dangerous-asyncio-shell-tainted-env-args.dangerous-asyncio-shell-tainted-env-args + languages: + - python + message: Detected asyncio subprocess function with user controlled data. You may consider using 'shlex.escape()'. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.python.org/3/library/asyncio-subprocess.html + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: $LOOP.subprocess_shell($PROTOCOL, $CMD) + - pattern-inside: asyncio.subprocess.create_subprocess_shell($CMD, ...) + - pattern-inside: asyncio.create_subprocess_shell($CMD, ...) + - focus-metavariable: $CMD + - pattern-not-inside: | + $CMD = "..." + ... + - pattern-not: $LOOP.subprocess_shell($PROTOCOL, "...") + - pattern-not: asyncio.subprocess.create_subprocess_shell("...", ...) + - pattern-not: asyncio.create_subprocess_shell("...", ...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.audit.dangerous-code-run-audit.dangerous-interactive-code-run-audit + languages: + - python + message: Found dynamic content inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. Ensure no external data reaches here. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - audit + technology: + - python + patterns: + - pattern-either: + - pattern: | + $X.push($PAYLOAD,...) + - pattern: | + $X.runsource($PAYLOAD,...) + - pattern: | + $X.runcode(code.compile_command($PAYLOAD),...) + - pattern: | + $PL = code.compile_command($PAYLOAD,...) + ... + $X.runcode($PL,...) + - pattern-either: + - pattern-inside: | + $X = code.InteractiveConsole(...) + ... + - pattern-inside: | + $X = code.InteractiveInterpreter(...) + ... + - pattern-not: | + $X.push("...",...) + - pattern-not: | + $X.runsource("...",...) + - pattern-not: | + $X.runcode(code.compile_command("..."),...) + - pattern-not: | + $PL = code.compile_command("...",...) + ... + $X.runcode($PL,...) + severity: WARNING + - id: python.lang.security.audit.dangerous-code-run-tainted-env-args.dangerous-interactive-code-run-tainted-env-args + languages: + - python + message: Found user controlled data inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $X = code.InteractiveConsole(...) + ... + - pattern-inside: | + $X = code.InteractiveInterpreter(...) + ... + - pattern-either: + - pattern-inside: | + $X.push($PAYLOAD,...) + - pattern-inside: | + $X.runsource($PAYLOAD,...) + - pattern-inside: | + $X.runcode(code.compile_command($PAYLOAD),...) + - pattern-inside: | + $PL = code.compile_command($PAYLOAD,...) + ... + $X.runcode($PL,...) + - pattern: $PAYLOAD + - pattern-not: | + $X.push("...",...) + - pattern-not: | + $X.runsource("...",...) + - pattern-not: | + $X.runcode(code.compile_command("..."),...) + - pattern-not: | + $PL = code.compile_command("...",...) + ... + $X.runcode($PL,...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: WARNING + - id: python.lang.security.audit.dangerous-os-exec-audit.dangerous-os-exec-audit + languages: + - python + message: Found dynamic content when spawning a process. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - audit + technology: + - python + pattern-either: + - patterns: + - pattern-not: os.$METHOD("...", ...) + - pattern: os.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (execl|execle|execlp|execlpe|execv|execve|execvp|execvpe) + - patterns: + - pattern-not: os.$METHOD("...", [$PATH,"...","...",...],...) + - pattern: os.$METHOD($BASH,[$PATH,"-c",$CMD,...],...) + - metavariable-regex: + metavariable: $METHOD + regex: (execv|execve|execvp|execvpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-not: os.$METHOD("...", $PATH, "...", "...",...) + - pattern: os.$METHOD($BASH, $PATH, "-c", $CMD,...) + - metavariable-regex: + metavariable: $METHOD + regex: (execl|execle|execlp|execlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + severity: ERROR + - id: python.lang.security.audit.dangerous-os-exec-tainted-env-args.dangerous-os-exec-tainted-env-args + languages: + - python + message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-not: os.$METHOD("...", ...) + - pattern: os.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (execl|execle|execlp|execlpe|execv|execve|execvp|execvpe) + - patterns: + - pattern-not: os.$METHOD("...", [$PATH,"...","...",...],...) + - pattern-inside: os.$METHOD($BASH,[$PATH,"-c",$CMD,...],...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (execv|execve|execvp|execvpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-not: os.$METHOD("...", $PATH, "...", "...",...) + - pattern-inside: os.$METHOD($BASH, $PATH, "-c", $CMD,...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (execl|execle|execlp|execlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.audit.dangerous-spawn-process-audit.dangerous-spawn-process-audit + languages: + - python + message: Found dynamic content when spawning a process. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + subcategory: + - audit + technology: + - python + pattern-either: + - patterns: + - pattern-not: os.$METHOD($MODE, "...", ...) + - pattern: os.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) + - patterns: + - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...) + - pattern: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...) + - metavariable-regex: + metavariable: $METHOD + regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...) + - pattern: os.$METHOD($MODE, $BASH, "-c", $CMD,...) + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + severity: ERROR + - id: python.lang.security.audit.dangerous-spawn-process-tainted-env-args.dangerous-spawn-process-tainted-env-args + languages: + - python + message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-not: os.$METHOD($MODE, "...", ...) + - pattern-inside: os.$METHOD($MODE, $CMD, ...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) + - patterns: + - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...) + - pattern-inside: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...) + - pattern-inside: os.$METHOD($MODE, $BASH, "-c", $CMD,...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.audit.dangerous-subinterpreters-run-string-audit.dangerous-subinterpreters-run-string-audit + languages: + - python + message: Found dynamic content in `run_string`. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. Ensure no external data reaches here. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://bugs.python.org/issue43472 + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - audit + technology: + - python + patterns: + - pattern: | + _xxsubinterpreters.run_string($ID, $PAYLOAD, ...) + - pattern-not: | + _xxsubinterpreters.run_string($ID, "...", ...) + severity: WARNING + - id: python.lang.security.audit.dangerous-subinterpreters-run-string-tainted-env-args.dangerous-subinterpreters-run-string-tainted-env-args + languages: + - python + message: Found user controlled content in `run_string`. This is dangerous because it allows a malicious actor to run arbitrary Python code. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://bugs.python.org/issue43472 + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-inside: | + _xxsubinterpreters.run_string($ID, $PAYLOAD, ...) + - pattern-not: | + _xxsubinterpreters.run_string($ID, "...", ...) + - pattern: $PAYLOAD + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: WARNING + - id: python.lang.security.audit.dangerous-subprocess-use-audit.dangerous-subprocess-use-audit + languages: + - python + message: Detected subprocess function '$FUNC' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess + - https://docs.python.org/3/library/subprocess.html + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - audit + technology: + - python + pattern-either: + - patterns: + - pattern-not: subprocess.$FUNC("...", ...) + - pattern-not: subprocess.$FUNC(["...",...], ...) + - pattern-not: subprocess.$FUNC(("...",...), ...) + - pattern-not: + patterns: + - pattern-not-inside: | + $ARR = ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...] + ... + - pattern-inside: | + $ARR = [...] + ... + - pattern-either: + - pattern: subprocess.$FUNC(*$ARR, ...) + - pattern: subprocess.$FUNC([*$ARR, ...]) + - pattern-not: subprocess.CalledProcessError(...) + - pattern-not: subprocess.SubprocessError(...) + - pattern: subprocess.$FUNC(...) + - patterns: + - pattern: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",...) + - pattern-not: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...) + - patterns: + - pattern-either: + - pattern: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",...],...) + - pattern: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",...),...) + - pattern-not: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...],...) + - pattern-not: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...),...) + - patterns: + - pattern: subprocess.$FUNC("=~/(python)/",...) + - pattern-not: subprocess.$FUNC("=~/(python)/","...",...) + - patterns: + - pattern-either: + - pattern: subprocess.$FUNC(["=~/(python)/",...],...) + - pattern: subprocess.$FUNC(("=~/(python)/",...),...) + - pattern-not: subprocess.$FUNC(["=~/(python)/","...",...],...) + - pattern-not: subprocess.$FUNC(("=~/(python)/","...",...),...) + severity: ERROR + - id: python.lang.security.audit.dangerous-subprocess-use-tainted-env-args.dangerous-subprocess-use-tainted-env-args + languages: + - python + message: Detected subprocess function '$FUNC' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.escape()'. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess + - https://docs.python.org/3/library/subprocess.html + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-not: subprocess.$FUNC("...", ...) + - pattern-not: subprocess.$FUNC(["...",...], ...) + - pattern-not: subprocess.$FUNC(("...",...), ...) + - pattern-not: subprocess.CalledProcessError(...) + - pattern-not: subprocess.SubprocessError(...) + - pattern: subprocess.$FUNC($CMD, ...) + - patterns: + - pattern-not: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...) + - pattern: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD) + - patterns: + - pattern-not: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...],...) + - pattern-not: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...),...) + - pattern-either: + - pattern: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD], ...) + - pattern: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD), ...) + - patterns: + - pattern-not: subprocess.$FUNC("=~/(python)/","...",...) + - pattern: subprocess.$FUNC("=~/(python)/", $CMD) + - patterns: + - pattern-not: subprocess.$FUNC(["=~/(python)/","...",...],...) + - pattern-not: subprocess.$FUNC(("=~/(python)/","...",...),...) + - pattern-either: + - pattern: subprocess.$FUNC(["=~/(python)/", $CMD],...) + - pattern: subprocess.$FUNC(("=~/(python)/", $CMD),...) + - focus-metavariable: $CMD + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.audit.dangerous-system-call-audit.dangerous-system-call-audit + languages: + - python + message: Found dynamic content used in a system call. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. + metadata: + asvs: + control_id: 5.2.4 Dyanmic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + subcategory: + - audit + technology: + - python + patterns: + - pattern-not: os.$W("...", ...) + - pattern-either: + - pattern: os.system(...) + - pattern: getattr(os, "system")(...) + - pattern: __import__("os").system(...) + - pattern: getattr(__import__("os"), "system")(...) + - pattern: | + $X = __import__("os") + ... + $X.system(...) + - pattern: | + $X = __import__("os") + ... + getattr($X, "system")(...) + - pattern: | + $X = getattr(os, "system") + ... + $X(...) + - pattern: | + $X = __import__("os") + ... + $Y = getattr($X, "system") + ... + $Y(...) + - pattern: os.popen(...) + - pattern: os.popen2(...) + - pattern: os.popen3(...) + - pattern: os.popen4(...) + severity: ERROR + - id: python.lang.security.audit.dangerous-system-call-tainted-env-args.dangerous-system-call-tainted-env-args + languages: + - python + message: Found user-controlled data used in a system call. This could allow a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. + metadata: + asvs: + control_id: 5.2.4 Dyanmic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-not: os.$W("...", ...) + - pattern-either: + - pattern: os.system(...) + - pattern: | + $X = __import__("os") + ... + $X.system(...) + - pattern: | + $X = __import__("os") + ... + getattr($X, "system")(...) + - pattern: | + $X = getattr(os, "system") + ... + $X(...) + - pattern: | + $X = __import__("os") + ... + $Y = getattr($X, "system") + ... + $Y(...) + - pattern: os.popen(...) + - pattern: os.popen2(...) + - pattern: os.popen3(...) + - pattern: os.popen4(...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.audit.dangerous-testcapi-run-in-subinterp-audit.dangerous-testcapi-run-in-subinterp-audit + languages: + - python + message: Found dynamic content in `run_in_subinterp`. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. Ensure no external data reaches here. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - audit + technology: + - python + patterns: + - pattern-either: + - pattern: | + _testcapi.run_in_subinterp($PAYLOAD, ...) + - pattern: | + test.support.run_in_subinterp($PAYLOAD, ...) + - pattern-not: | + _testcapi.run_in_subinterp("...", ...) + - pattern-not: | + test.support.run_in_subinterp("...", ...) + severity: WARNING + - id: python.lang.security.audit.dangerous-testcapi-run-in-subinterp-tainted-env-args.dangerous-testcapi-run-in-subinterp-tainted-env-args + languages: + - python + message: Found user controlled content in `run_in_subinterp`. This is dangerous because it allows a malicious actor to run arbitrary Python code. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + _testcapi.run_in_subinterp($PAYLOAD, ...) + - pattern-inside: | + test.support.run_in_subinterp($PAYLOAD, ...) + - pattern: $PAYLOAD + - pattern-not: | + _testcapi.run_in_subinterp("...", ...) + - pattern-not: | + test.support.run_in_subinterp("...", ...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: WARNING + - id: python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected + languages: + - python + message: Detected a dynamic value being used with urllib. urllib supports 'file://' schemes, so a dynamic value controlled by a malicious actor may allow them to read arbitrary files. Audit uses of urllib calls to ensure user data cannot control the URLs, or consider using the 'requests' library instead. + metadata: + asvs: + control_id: 5.2.4 Dynamic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + bandit-code: B310 + category: security + confidence: LOW + cwe: + - 'CWE-939: Improper Authorization in Handler for Custom URL Scheme' + impact: LOW + likelihood: LOW + owasp: A01:2017 - Injection + references: + - https://cwe.mitre.org/data/definitions/939.html + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/blacklists/calls.py#L163 + subcategory: + - audit + technology: + - python + patterns: + - pattern-not: urllib.$W("...") + - pattern-not: urllib.request.$W("...") + - pattern-not: $OPENER.$W("...") + - pattern-either: + - pattern: urllib.urlopen(...) + - pattern: urllib.request.urlopen(...) + - pattern: urllib.urlretrieve(...) + - pattern: urllib.request.urlretrieve(...) + - patterns: + - pattern-either: + - pattern-inside: | + $OPENER = urllib.URLopener(...) + ... + - pattern-inside: | + $OPENER = urllib.request.URLopener(...) + ... + - pattern-inside: | + $OPENER = urllib.FancyURLopener(...) + ... + - pattern-inside: | + $OPENER = urllib.request.FancyURLopener(...) + ... + - pattern-either: + - pattern: $OPENER.open(...) + - pattern: $OPENER.retrieve(...) + severity: WARNING + - id: python.lang.security.audit.eval-detected.eval-detected + languages: + - python + message: Detected the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources. + metadata: + asvs: + control_id: 5.2.4 Dyanmic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html#b307-eval + subcategory: + - audit + technology: + - python + patterns: + - pattern-not: eval(f"") + - pattern-not: eval("...") + - pattern: eval(...) + severity: WARNING + - id: python.lang.security.audit.exec-detected.exec-detected + languages: + - python + message: Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources. + metadata: + asvs: + control_id: 5.2.4 Dyanmic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b102_exec_used.html + subcategory: + - audit + technology: + - python + patterns: + - pattern-not: exec("...") + - pattern: exec(...) + severity: WARNING + - id: python.lang.security.audit.formatted-sql-query.formatted-sql-query + languages: + - python + message: Detected possible formatted SQL query. Use parameterized queries instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://stackoverflow.com/questions/775296/mysql-parameterized-queries + subcategory: + - audit + technology: + - python + pattern-either: + - pattern: $DB.execute("..." % ...) + - pattern: $DB.execute("...".format(...)) + - pattern: $DB.execute(f"...") + - patterns: + - pattern-either: + - pattern-inside: | + $SQL = "..." % ... + ... + - pattern-inside: | + $SQL = "...".format(...) + ... + - pattern-inside: | + $SQL = f"...{$X}..." + ... + - pattern: $DB.execute($SQL) + severity: WARNING + - id: python.lang.security.audit.ftplib.ftplib + languages: + - python + message: FTP does not encrypt communications by default. This can lead to sensitive data being exposed. Ensure use of FTP here does not expose sensitive data. + metadata: + bandit-code: B321 + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/telnetlib.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L265 + subcategory: + - audit + technology: + - ftplib + pattern: ftplib.$ANYTHING(...) + severity: WARNING + - id: python.lang.security.audit.hardcoded-password-default-argument.hardcoded-password-default-argument + languages: + - python + message: Hardcoded password is used as a default argument to '$FUNC'. This could be dangerous if a real password is not supplied. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + subcategory: + - audit + technology: + - python + patterns: + - pattern: | + def $FUNC(..., password="...", ...): + ... + - pattern-not: | + def $FUNC(..., password="", ...): + ... + severity: WARNING + - id: python.lang.security.audit.httpsconnection-detected.httpsconnection-detected + languages: + - python + message: The HTTPSConnection API has changed frequently with minor releases of Python. Ensure you are using the API for your version of Python securely. For example, Python 3 versions prior to 3.4.3 will not verify SSL certificates by default. See https://docs.python.org/3/library/http.client.html#http.client.HTTPSConnection for more information. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://docs.python.org/3/library/http.client.html#http.client.HTTPSConnection + subcategory: + - audit + technology: + - python + pattern-either: + - pattern: httplib.HTTPSConnection(...) + - pattern: http.client.HTTPSConnection(...) + - pattern: six.moves.http_client.HTTPSConnection(...) + severity: WARNING + - id: python.lang.security.audit.insecure-file-permissions.insecure-file-permissions + languages: + - python + message: These permissions `$BITS` are widely permissive and grant access to more people than may be necessary. A good default is `0o644` which gives read and write access to yourself and read access to everyone else. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-276: Incorrect Default Permissions' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - python + patterns: + - pattern-inside: os.$METHOD(...) + - metavariable-pattern: + metavariable: $METHOD + patterns: + - pattern-either: + - pattern: chmod + - pattern: lchmod + - pattern: fchmod + - pattern-either: + - patterns: + - pattern: os.$METHOD($FILE, $BITS, ...) + - metavariable-comparison: + comparison: $BITS >= 0o650 and $BITS < 0o100000 + metavariable: $BITS + - patterns: + - pattern: os.$METHOD($FILE, $BITS) + - metavariable-comparison: + comparison: $BITS >= 0o100650 + metavariable: $BITS + - patterns: + - pattern: os.$METHOD($FILE, $BITS, ...) + - metavariable-pattern: + metavariable: $BITS + patterns: + - pattern-either: + - pattern: <... stat.S_IWGRP ...> + - pattern: <... stat.S_IXGRP ...> + - pattern: <... stat.S_IWOTH ...> + - pattern: <... stat.S_IXOTH ...> + - pattern: <... stat.S_IRWXO ...> + - pattern: <... stat.S_IRWXG ...> + - patterns: + - pattern: os.$METHOD($FILE, $EXPR | $MOD, ...) + - metavariable-comparison: + comparison: $MOD == 0o111 + metavariable: $MOD + severity: WARNING + - fix-regex: + regex: FTP(.*)\) + replacement: FTP_TLS\1, context=ssl.create_default_context()) + id: python.lang.security.audit.insecure-transport.ftplib.use-ftp-tls.use-ftp-tls + languages: + - python + message: The 'FTP' class sends information unencrypted. Consider using the 'FTP_TLS' class instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/ftplib.html#ftplib.FTP_TLS + subcategory: + - audit + technology: + - ftplib + pattern: ftplib.FTP(...) + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.requests.request-session-http-in-with-context.request-session-http-in-with-context + languages: + - python + message: Detected a request using 'http://'. This request will be unencrypted. Use 'https://' instead. + metadata: + asvs: + control_id: 9.2.1 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - requests + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-inside: | + with requests.Session(...) as $SESSION: + ... + - pattern-either: + - pattern: $SESSION.$W($SINK, ...) + - pattern: $SESSION.request($METHOD, $SINK, ...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern: | + "$URL" + - metavariable-pattern: + language: regex + metavariable: $URL + patterns: + - pattern-regex: http:// + - pattern-not-regex: .*://localhost + - pattern-not-regex: .*://127\.0\.0\.1 + severity: INFO + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.requests.request-session-with-http.request-session-with-http + languages: + - python + message: Detected a request using 'http://'. This request will be unencrypted. Use 'https://' instead. + metadata: + asvs: + control_id: 9.1.1 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - requests + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: requests.Session(...).$W($SINK, ...) + - pattern: requests.Session(...).request($METHOD, $SINK, ...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern: | + "$URL" + - metavariable-pattern: + language: regex + metavariable: $URL + patterns: + - pattern-regex: http:// + - pattern-not-regex: .*://localhost + - pattern-not-regex: .*://127\.0\.0\.1 + severity: INFO + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.requests.request-with-http.request-with-http + languages: + - python + message: Detected a request using 'http://'. This request will be unencrypted, and attackers could listen into traffic on the network and be able to obtain sensitive information. Use 'https://' instead. + metadata: + asvs: + control_id: 9.1.1 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - requests + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: requests.$W($SINK, ...) + - pattern: requests.request($METHOD, $SINK, ...) + - pattern: requests.Request($METHOD, $SINK, ...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern: | + "$URL" + - metavariable-pattern: + language: regex + metavariable: $URL + patterns: + - pattern-regex: http:// + - pattern-not-regex: .*://localhost + - pattern-not-regex: .*://127\.0\.0\.1 + severity: INFO + - id: python.lang.security.audit.insecure-transport.ssl.no-set-ciphers.no-set-ciphers + languages: + - python + message: The 'ssl' module disables insecure cipher suites by default. Therefore, use of 'set_ciphers()' should only be used when you have very specialized requirements. Otherwise, you risk lowering the security of the SSL channel. + metadata: + asvs: + control_id: 9.1.3 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v91-client-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/ssl.html#cipher-selection + - https://docs.python.org/3/library/ssl.html#ssl.SSLContext.set_ciphers + subcategory: + - audit + technology: + - ssl + pattern: $CONTEXT.set_ciphers(...) + severity: WARNING + - id: python.lang.security.audit.insecure-transport.urllib.insecure-openerdirector-open-ftp.insecure-openerdirector-open-ftp + languages: + - python + message: Detected an unsecured transmission channel. 'OpenerDirector.open(...)' is being used with 'ftp://'. Information sent over this connection will be unencrypted. Consider using SFTP instead. urllib does not support SFTP, so consider a library which supports SFTP. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.OpenerDirector.open + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.OpenerDirector(...).open("=~/^[Ff][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.OpenerDirector(...) + ... + - pattern: $OPENERDIRECTOR.open("=~/^[Ff][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.OpenerDirector(...) + ... + - pattern: | + $URL = "=~/^[Ff][Tt][Pp]://.*/" + ... + $OPENERDIRECTOR.open($URL, ...) + - pattern: | + $URL = "=~/^[Ff][Tt][Pp]://.*/" + ... + urllib.request.OpenerDirector(...).open($URL, ...) + - patterns: + - pattern-inside: | + def $FUNC(..., $URL = "=~/^[Ff][Tt][Pp]://.*/", ...): + ... + - pattern-either: + - pattern: urllib.request.OpenerDirector(...).open($URL, ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.OpenerDirector(...) + ... + - pattern: $OPENERDIRECTOR.open($URL, ...) + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.urllib.insecure-openerdirector-open.insecure-openerdirector-open + languages: + - python + message: Detected an unsecured transmission channel. 'OpenerDirector.open(...)' is being used with 'http://'. Use 'https://' instead to secure the channel. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.OpenerDirector.open + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.OpenerDirector(...).open("=~/[Hh][Tt][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.OpenerDirector(...) + ... + - pattern: $OPENERDIRECTOR.open("=~/[Hh][Tt][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.OpenerDirector(...) + ... + - pattern: | + $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" + ... + $OPENERDIRECTOR.open($URL, ...) + - pattern: | + $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" + ... + urllib.request.OpenerDirector(...).open($URL, ...) + - patterns: + - pattern-inside: | + def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): + ... + - pattern-either: + - pattern: urllib.request.OpenerDirector(...).open($URL, ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.OpenerDirector(...) + ... + - pattern: $OPENERDIRECTOR.open($URL, ...) + severity: WARNING + - id: python.lang.security.audit.insecure-transport.urllib.insecure-request-object-ftp.insecure-request-object-ftp + languages: + - python + message: Detected a 'urllib.request.Request()' object using an insecure transport protocol, 'ftp://'. This connection will not be encrypted. Consider using SFTP instead. urllib does not support SFTP natively, so consider using a library which supports SFTP. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.Request + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.Request("=~/^[Ff][Tt][Pp]://.*/", ...) + - pattern: | + $URL = "=~/^[Ff][Tt][Pp]://.*/" + ... + urllib.request.Request($URL, ...) + - pattern: |- + def $FUNC(..., $URL = "=~/^[Ff][Tt][Pp]://.*/", ...): + ... + urllib.request.Request($URL, ...) + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.urllib.insecure-request-object.insecure-request-object + languages: + - python + message: Detected a 'urllib.request.Request()' object using an insecure transport protocol, 'http://'. This connection will not be encrypted. Use 'https://' instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.Request + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.Request("=~/[Hh][Tt][Tt][Pp]://.*/", ...) + - pattern: | + $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" + ... + urllib.request.Request($URL, ...) + - pattern: | + def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): + ... + urllib.request.Request($URL, ...) + severity: WARNING + - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopen-ftp.insecure-urlopen-ftp + languages: + - python + message: Detected 'urllib.urlopen()' using 'ftp://'. This request will not be encrypted. Consider using SFTP instead. urllib does not support SFTP, so consider switching to a library which supports SFTP. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.urlopen + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.urlopen("=~/^[Ff][Tt][Pp]://.*/", ...) + - pattern: | + $URL = "=~/^[Ff][Tt][Pp]://.*/" + ... + urllib.request.urlopen($URL, ...) + - pattern: |- + def $FUNC(..., $URL = "=~/^[Ff][Tt][Pp]://.*/", ...): + ... + urllib.request.urlopen($URL, ...) + severity: WARNING + - fix-regex: + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopen.insecure-urlopen + languages: + - python + message: Detected 'urllib.urlopen()' using 'http://'. This request will not be encrypted. Use 'https://' instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.urlopen + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.urlopen("=~/[Hh][Tt][Tt][Pp]://.*/", ...) + - pattern: | + $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" + ... + urllib.request.urlopen($URL, ...) + - pattern: | + def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): + ... + urllib.request.urlopen($URL, ...) + severity: WARNING + - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopener-open-ftp.insecure-urlopener-open-ftp + languages: + - python + message: Detected an insecure transmission channel. 'URLopener.open(...)' is being used with 'ftp://'. Use SFTP instead. urllib does not support SFTP, so consider using a library which supports SFTP. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.URLopener.open + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.URLopener(...).open("=~/[Ff][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: $OPENERDIRECTOR.open("=~/[Ff][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: | + $URL = "=~/[Ff][Tt][Pp]://.*/" + ... + $OPENERDIRECTOR.open($URL, ...) + - pattern: | + $URL = "=~/[Ff][Tt][Pp]://.*/" + ... + urllib.request.URLopener(...).open($URL, ...) + - patterns: + - pattern-inside: | + def $FUNC(..., $URL = "=~/[Ff][Tt][Pp]://.*/", ...): + ... + - pattern-either: + - pattern: urllib.request.URLopener(...).open($URL, ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: $OPENERDIRECTOR.open($URL, ...) + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopener-open.insecure-urlopener-open + languages: + - python + message: Detected an unsecured transmission channel. 'URLopener.open(...)' is being used with 'http://'. Use 'https://' instead to secure the channel. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.URLopener.open + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.URLopener(...).open("=~/[Hh][Tt][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: $OPENERDIRECTOR.open("=~/[Hh][Tt][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: | + $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" + ... + $OPENERDIRECTOR.open($URL, ...) + - pattern: | + $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" + ... + urllib.request.URLopener(...).open($URL, ...) + - patterns: + - pattern-inside: | + def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): + ... + - pattern-either: + - pattern: urllib.request.URLopener(...).open($URL, ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: $OPENERDIRECTOR.open($URL, ...) + severity: WARNING + - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopener-retrieve-ftp.insecure-urlopener-retrieve-ftp + languages: + - python + message: Detected an insecure transmission channel. 'URLopener.retrieve(...)' is being used with 'ftp://'. Use SFTP instead. urllib does not support SFTP, so consider using a library which supports SFTP. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.URLopener.retrieve + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.URLopener(...).retrieve("=~/[Ff][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: $OPENERDIRECTOR.retrieve("=~/[Ff][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: | + $URL = "=~/[Ff][Tt][Pp]://.*/" + ... + $OPENERDIRECTOR.retrieve($URL, ...) + - pattern: | + $URL = "=~/[Ff][Tt][Pp]://.*/" + ... + urllib.request.URLopener(...).retrieve($URL, ...) + - patterns: + - pattern-inside: | + def $FUNC(..., $URL = "=~/[Ff][Tt][Pp]://.*/", ...): + ... + - pattern-either: + - pattern: urllib.request.URLopener(...).retrieve($URL, ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: $OPENERDIRECTOR.retrieve($URL, ...) + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopener-retrieve.insecure-urlopener-retrieve + languages: + - python + message: Detected an unsecured transmission channel. 'URLopener.retrieve(...)' is being used with 'http://'. Use 'https://' instead to secure the channel. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.URLopener.retrieve + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.URLopener(...).retrieve("=~/[Hh][Tt][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: $OPENERDIRECTOR.retrieve("=~/[Hh][Tt][Tt][Pp]://.*/", ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: | + $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" + ... + $OPENERDIRECTOR.retrieve($URL, ...) + - pattern: | + $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" + ... + urllib.request.URLopener(...).retrieve($URL, ...) + - patterns: + - pattern-inside: | + def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): + ... + - pattern-either: + - pattern: urllib.request.URLopener(...).retrieve($URL, ...) + - patterns: + - pattern-inside: | + $OPENERDIRECTOR = urllib.request.URLopener(...) + ... + - pattern: $OPENERDIRECTOR.retrieve($URL, ...) + severity: WARNING + - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlretrieve-ftp.insecure-urlretrieve-ftp + languages: + - python + message: Detected 'urllib.urlretrieve()' using 'ftp://'. This request will not be encrypted. Use SFTP instead. urllib does not support SFTP, so consider switching to a library which supports SFTP. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.urlretrieve + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.urlretrieve("=~/^[Ff][Tt][Pp]://.*/", ...) + - pattern: | + $URL = "=~/^[Ff][Tt][Pp]://.*/" + ... + urllib.request.urlretrieve($URL, ...) + - pattern: |- + def $FUNC(..., $URL = "=~/^[Ff][Tt][Pp]://.*/", ...): + ... + urllib.request.urlretrieve($URL, ...) + severity: WARNING + - fix-regex: + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.urllib.insecure-urlretrieve.insecure-urlretrieve + languages: + - python + message: Detected 'urllib.urlretrieve()' using 'http://'. This request will not be encrypted. Use 'https://' instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/urllib.request.html#urllib.request.urlretrieve + subcategory: + - audit + technology: + - urllib + pattern-either: + - pattern: urllib.request.urlretrieve("=~/[Hh][Tt][Tt][Pp]://.*/", ...) + - pattern: | + $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" + ... + urllib.request.urlretrieve($URL, ...) + - pattern: | + def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): + ... + urllib.request.urlretrieve($URL, ...) + severity: WARNING + - id: python.lang.security.audit.logging.listeneval.listen-eval + languages: + - python + message: Because portions of the logging configuration are passed through eval(), use of this function may open its users to a security risk. While the function only binds to a socket on localhost, and so does not accept connections from remote machines, there are scenarios where untrusted code could be run under the account of the process which calls listen(). To avoid this happening, use the `verify()` argument to `listen()` to prevent unrecognized configurations. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: LOW + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://docs.python.org/3/library/logging.config.html?highlight=security#logging.config.listen + subcategory: + - audit + technology: + - python + pattern: logging.config.listen(...) + severity: WARNING + - id: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure + languages: + - python + message: Detected a python logger call with a potential hardcoded secret $FORMAT_STRING being logged. This may lead to secret credentials being exposed. Make sure that the logger is not logging sensitive information. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-532: Insertion of Sensitive Information into Log File' + impact: MEDIUM + likelihood: LOW + owasp: + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures + subcategory: + - vuln + technology: + - python + patterns: + - pattern: | + $LOGGER_OBJ.$LOGGER_CALL($FORMAT_STRING,...) + - metavariable-regex: + metavariable: $LOGGER_OBJ + regex: (?i)(_logger|logger|self.logger|log) + - metavariable-regex: + metavariable: $LOGGER_CALL + regex: (debug|info|warn|warning|error|exception|critical) + - metavariable-regex: + metavariable: $FORMAT_STRING + regex: (?i).*(api.key|secret|credential|token|password).*\%s.* + severity: WARNING + - id: python.lang.security.audit.mako-templates-detected.mako-templates-detected + languages: + - python + message: Mako templates do not provide a global HTML escaping mechanism. This means you must escape all sensitive data in your templates using '| u' for URL escaping or '| h' for HTML escaping. If you are using Mako to serve web content, consider using a system such as Jinja2 which enables global escaping. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.makotemplates.org/en/latest/syntax.html#expression-escaping + - https://jinja.palletsprojects.com/en/2.11.x/intro/# + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/mako_templates.py + subcategory: + - audit + technology: + - mako + pattern: mako.template.Template(...) + severity: INFO + - id: python.lang.security.audit.marshal.marshal-usage + languages: + - python + message: 'The marshal module is not intended to be secure against erroneous or maliciously constructed data. Never unmarshal data received from an untrusted or unauthenticated source. See more details: https://docs.python.org/3/library/marshal.html?highlight=security' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.python.org/3/library/marshal.html?highlight=security + subcategory: + - audit + technology: + - python + pattern-either: + - pattern: marshal.dump(...) + - pattern: marshal.dumps(...) + - pattern: marshal.load(...) + - pattern: marshal.loads(...) + severity: WARNING + - id: python.lang.security.audit.md5-used-as-password.md5-used-as-password + languages: + - python + message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as scrypt. You can use `hashlib.scrypt`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: LOW + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://tools.ietf.org/html/rfc6151 + - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords + - https://github.com/returntocorp/semgrep-rules/issues/1609 + - https://docs.python.org/3/library/hashlib.html#hashlib.scrypt + subcategory: + - vuln + technology: + - pycryptodome + - hashlib + - md5 + mode: taint + pattern-sinks: + - patterns: + - pattern: $FUNCTION(...) + - metavariable-regex: + metavariable: $FUNCTION + regex: (?i)(.*password.*) + pattern-sources: + - patterns: + - pattern-either: + - pattern: hashlib.md5 + - pattern: hashlib.new(..., name="MD5", ...) + - pattern: Cryptodome.Hash.MD5 + - pattern: Crypto.Hash.MD5 + - pattern: cryptography.hazmat.primitives.hashes.MD5 + severity: WARNING + - id: python.lang.security.audit.network.bind.avoid-bind-to-all-interfaces + languages: + - python + message: Running `socket.bind` to 0.0.0.0, or empty string could unexpectedly expose the server publicly as it binds to all available interfaces. Consider instead getting correct address from an environment variable or configuration file. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - python + pattern-either: + - pattern: | + $S = socket.socket(...) + ... + $S.bind(("0.0.0.0", ...)) + - pattern: | + $S = socket.socket(...) + ... + $S.bind(("::", ...)) + - pattern: | + $S = socket.socket(...) + ... + $S.bind(("", ...)) + severity: INFO + - id: python.lang.security.audit.network.disabled-cert-validation.disabled-cert-validation + languages: + - python + message: certificate verification explicitly disabled, insecure connections possible + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + subcategory: + - vuln + technology: + - python + patterns: + - pattern-either: + - pattern: urllib3.PoolManager(..., cert_reqs=$REQS, ...) + - pattern: urllib3.ProxyManager(..., cert_reqs=$REQS, ...) + - pattern: urllib3.HTTPSConnectionPool(..., cert_reqs=$REQS, ...) + - pattern: urllib3.connectionpool.HTTPSConnectionPool(..., cert_reqs=$REQS, ...) + - pattern: urllib3.connection_from_url(..., cert_reqs=$REQS, ...) + - pattern: urllib3.proxy_from_url(..., cert_reqs=$REQS, ...) + - pattern: $CONTEXT.wrap_socket(..., cert_reqs=$REQS, ...) + - pattern: ssl.wrap_socket(..., cert_reqs=$REQS, ...) + - metavariable-regex: + metavariable: $REQS + regex: (NONE|CERT_NONE|CERT_OPTIONAL|ssl\.CERT_NONE|ssl\.CERT_OPTIONAL|\'NONE\'|\"NONE\"|\'OPTIONAL\'|\"OPTIONAL\") + severity: ERROR + - id: python.lang.security.audit.network.http-not-https-connection.http-not-https-connection + languages: + - python + message: Detected HTTPConnectionPool. This will transmit data in cleartext. It is recommended to use HTTPSConnectionPool instead for to encrypt communications. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://urllib3.readthedocs.io/en/1.2.1/pools.html#urllib3.connectionpool.HTTPSConnectionPool + subcategory: + - audit + technology: + - python + pattern-either: + - pattern: urllib3.HTTPConnectionPool(...) + - pattern: urllib3.connectionpool.HTTPConnectionPool(...) + severity: ERROR + - id: python.lang.security.audit.non-literal-import.non-literal-import + languages: + - python + message: Untrusted user input in `importlib.import_module()` function allows an attacker to load arbitrary code. Avoid dynamic values in `importlib.import_module()` or use a whitelist to prevent running untrusted code. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-706: Use of Incorrectly-Resolved Name or Reference' + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - python + patterns: + - pattern: | + importlib.import_module($NAME, ...) + - pattern-not: | + importlib.import_module("...", ...) + severity: WARNING + - id: python.lang.security.audit.paramiko-implicit-trust-host-key.paramiko-implicit-trust-host-key + languages: + - python + message: Detected a paramiko host key policy that implicitly trusts a server's host key. Host keys should be verified to ensure the connection is not to a malicious server. Use RejectPolicy or a custom subclass instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-322: Key Exchange without Entity Authentication' + impact: MEDIUM + likelihood: LOW + owasp: + - A02:2021 - Cryptographic Failures + references: + - http://docs.paramiko.org/en/stable/api/client.html#paramiko.client.AutoAddPolicy + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/ssh_no_host_key_verification.py + subcategory: + - audit + technology: + - paramiko + patterns: + - pattern-inside: | + $CLIENT = paramiko.client.SSHClient(...) + ... + $CLIENT.set_missing_host_key_policy(...) + - pattern-either: + - pattern: paramiko.client.AutoAddPolicy + - pattern: paramiko.client.WarningPolicy + severity: WARNING + - id: python.lang.security.audit.paramiko.paramiko-exec-command.paramiko-exec-command + languages: + - python + message: Unverified SSL context detected. This will permit insecure connections without verifying SSL certificates. Use 'ssl.create_default_context()' instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - http://docs.paramiko.org/en/stable/api/client.html#paramiko.client.SSHClient.exec_command + - https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/plugins/injection_paramiko.py + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/plugins/injection_paramiko.py + subcategory: + - audit + technology: + - paramiko + patterns: + - pattern-inside: | + $CLIENT = paramiko.client.SSHClient(...) + ... + - pattern: $CLIENT.exec_command(...) + - pattern-not: $CLIENT.exec_command("...", ...) + severity: ERROR + - id: python.lang.security.audit.python-reverse-shell.python-reverse-shell + languages: + - python + message: Semgrep found a Python reverse shell using $BINPATH to $IP at $PORT + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-553: Command Shell in Externally Accessible Directory' + impact: MEDIUM + likelihood: LOW + references: + - https://cwe.mitre.org/data/definitions/553.html + subcategory: + - audit + technology: + - python + patterns: + - pattern-either: + - pattern: pty.spawn("$BINPATH",...) + - pattern: subprocess.call(["$BINPATH",...],...) + - metavariable-regex: + metavariable: $BINPATH + regex: /bin/.*?sh\b + - pattern-inside: | + import socket + ... + $S = socket.socket(...) + ... + $S.connect(($IP,$PORT),...) + ... + severity: WARNING + - id: python.lang.security.audit.regex-dos.regex_dos + languages: + - python + message: Detected usage of re.compile with an inefficient regular expression. This can lead to regular expression denial of service, which can result in service down time. Instead, check all regexes or use safer alternatives such as pyre2. + metadata: + category: security + confidence: LOW + cwe: 'CWE-1333: Inefficient Regular Expression Complexity' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: A06:2017 - Security Misconfiguration + references: + - https://docs.python.org/3/library/re.html + subcategory: + - vuln + technology: + - python + patterns: + - pattern: | + $A = re.compile("$B", ...) + ... + $A.$METHOD(...) + - metavariable-analysis: + analyzer: redos + metavariable: $B + - metavariable-regex: + metavariable: $METHOD + regex: (?!(escape)|(purge)) + severity: WARNING + - id: python.lang.security.audit.sqli.aiopg-sqli.aiopg-sqli + languages: + - python + message: 'Detected string concatenation with a non-literal variable in an aiopg Python SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries instead. You can create parameterized queries like so: ''cur.execute("SELECT %s FROM table", (user_value,))''.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/aio-libs/aiopg + subcategory: + - audit + technology: + - aiopg + patterns: + - pattern-either: + - patterns: + - pattern: $CUR.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = '...'.format(...) + ... + - pattern-inside: | + $QUERY = '...' % (...) + ... + - pattern-inside: | + $QUERY = f'...{$USERINPUT}...' + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern-not-inside: | + $QUERY = '...'.format() + ... + - pattern-not-inside: | + $QUERY = '...' % () + ... + - pattern: $CUR.$METHOD(..., $X + $Y, ...) + - pattern: $CUR.$METHOD(..., '...'.format(...), ...) + - pattern: $CUR.$METHOD(..., '...' % (...), ...) + - pattern: $CUR.$METHOD(..., f'...{$USERINPUT}...', ...) + - pattern-either: + - pattern-inside: | + $CONN = await aiopg.connect(...) + ... + $CUR = await $CONN.cursor(...) + ... + - pattern-inside: | + $POOL = await aiopg.create_pool(...) + ... + async with $POOL.acquire(...) as $CONN: + ... + async with $CONN.cursor(...) as $CUR: + ... + - pattern-inside: | + $POOL = await aiopg.create_pool(...) + ... + with (await $POOL.cursor(...)) as $CUR: + ... + - pattern-inside: | + $POOL = await aiopg.create_pool(...) + ... + async with $POOL as $CONN: + ... + $CUR = await $CONN.cursor(...) + ... + - pattern-inside: | + $POOL = await aiopg.create_pool(...) + ... + async with $POOL.cursor(...) as $CUR: + ... + - pattern-not: $CUR.$METHOD(..., "..." + "...", ...) + - pattern-not: $CUR.$METHOD(..., '...'.format(), ...) + - pattern-not: $CUR.$METHOD(..., '...'%(), ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(execute)$ + severity: WARNING + - id: python.lang.security.audit.sqli.asyncpg-sqli.asyncpg-sqli + languages: + - python + message: 'Detected string concatenation with a non-literal variable in a asyncpg Python SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can create parameterized queries like so: ''conn.fetch("SELECT $1 FROM table", value)''. You can also create prepared statements with ''Connection.prepare'': ''stmt = conn.prepare("SELECT $1 FROM table"); await stmt.fetch(user_value)''' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/MagicStack/asyncpg + - https://magicstack.github.io/asyncpg/current/ + subcategory: + - audit + technology: + - asyncpg + patterns: + - pattern-either: + - patterns: + - pattern: $CONN.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = '...'.format(...) + ... + - pattern-inside: | + $QUERY = '...' % (...) + ... + - pattern-inside: | + $QUERY = f'...{$USERINPUT}...' + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern-not-inside: | + $QUERY = '...'.format() + ... + - pattern-not-inside: | + $QUERY = '...' % () + ... + - pattern: $CONN.$METHOD(..., $X + $Y, ...) + - pattern: $CONN.$METHOD(..., $Y.format(...), ...) + - pattern: $CONN.$METHOD(..., '...'.format(...), ...) + - pattern: $CONN.$METHOD(..., '...' % (...), ...) + - pattern: $CONN.$METHOD(..., f'...{$USERINPUT}...', ...) + - pattern-either: + - pattern-inside: | + $CONN = await asyncpg.connect(...) + ... + - pattern-inside: | + async with asyncpg.create_pool(...) as $CONN: + ... + - pattern-inside: | + async with $POOL.acquire(...) as $CONN: + ... + - pattern-inside: | + $CONN = await $POOL.acquire(...) + ... + - pattern-inside: | + def $FUNCNAME(..., $CONN: Connection, ...): + ... + - pattern-inside: | + def $FUNCNAME(..., $CONN: asyncpg.Connection, ...): + ... + - pattern-not: $CONN.$METHOD(..., "..." + "...", ...) + - pattern-not: $CONN.$METHOD(..., '...'.format(), ...) + - pattern-not: $CONN.$METHOD(..., '...'%(), ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(fetch|fetchrow|fetchval|execute|executemany|prepare|cursor|copyfromquery)$ + severity: WARNING + - id: python.lang.security.audit.sqli.pg8000-sqli.pg8000-sqli + languages: + - python + message: 'Detected string concatenation with a non-literal variable in a pg8000 Python SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can create parameterized queries like so: ''conn.run("SELECT :value FROM table", value=myvalue)''. You can also create prepared statements with ''conn.prepare'': ''conn.prepare("SELECT (:v) FROM table")''' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/tlocke/pg8000 + subcategory: + - audit + technology: + - pg8000 + patterns: + - pattern-either: + - patterns: + - pattern: $CONN.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = '...'.format(...) + ... + - pattern-inside: | + $QUERY = '...' % (...) + ... + - pattern-inside: | + $QUERY = f'...{$USERINPUT}...' + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern-not-inside: | + $QUERY = '...'.format() + ... + - pattern-not-inside: | + $QUERY = '...' % () + ... + - pattern: $CONN.$METHOD(..., $X + $Y, ...) + - pattern: $CONN.$METHOD(..., '...'.format(...), ...) + - pattern: $CONN.$METHOD(..., '...' % (...), ...) + - pattern: $CONN.$METHOD(..., f'...{$USERINPUT}...', ...) + - pattern-either: + - pattern-inside: | + $CONN = pg8000.native.Connection(...) + ... + - pattern-inside: | + $CONN = pg8000.dhapi.connect(...) + ... + - pattern-inside: | + $CONN1 = pg8000.connect(...) + ... + $CONN = $CONN1.cursor(...) + ... + - pattern-inside: | + $CONN = pg8000.connect(...) + ... + - pattern-not: $CONN.$METHOD(..., "..." + "...", ...) + - pattern-not: $CONN.$METHOD(..., '...'.format(), ...) + - pattern-not: $CONN.$METHOD(..., '...'%(), ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(run|execute|executemany|prepare)$ + severity: WARNING + - id: python.lang.security.audit.sqli.psycopg-sqli.psycopg-sqli + languages: + - python + message: 'Detected string concatenation with a non-literal variable in a psycopg2 Python SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use prepared statements by creating a ''sql.SQL'' string. You can also use the pyformat binding style to create parameterized queries. For example: ''cur.execute(SELECT * FROM table WHERE name=%s, user_input)''' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://www.psycopg.org/docs/sql.html + subcategory: + - audit + technology: + - psycopg + patterns: + - pattern-either: + - patterns: + - pattern: $CUR.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = '...'.format(...) + ... + - pattern-inside: | + $QUERY = '...' % (...) + ... + - pattern-inside: | + $QUERY = f'...{$USERINPUT}...' + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern-not-inside: | + $QUERY = '...'.format() + ... + - pattern-not-inside: | + $QUERY = '...' % () + ... + - pattern: $CUR.$METHOD(..., $X + $Y, ...) + - pattern: $CUR.$METHOD(..., '...'.format(...), ...) + - pattern: $CUR.$METHOD(..., '...' % (...), ...) + - pattern: $CUR.$METHOD(..., f'...{$USERINPUT}...', ...) + - pattern-either: + - pattern-inside: | + $CONN = psycopg2.connect(...) + ... + $CUR = $CONN.cursor(...) + ... + - pattern-inside: | + $CONN = psycopg2.connect(...) + ... + with $CONN.cursor(...) as $CUR: + ... + - pattern-not: $CUR.$METHOD(..., "..." + "...", ...) + - pattern-not: $CUR.$METHOD(..., '...'.format(), ...) + - pattern-not: $CUR.$METHOD(..., '...'%(), ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(execute|executemany|mogrify)$ + severity: WARNING + - id: python.lang.security.audit.ssl-wrap-socket-is-deprecated.ssl-wrap-socket-is-deprecated + languages: + - python + message: '''ssl.wrap_socket()'' is deprecated. This function creates an insecure socket without server name indication or hostname matching. Instead, create an SSL context using ''ssl.SSLContext()'' and use that to wrap a socket.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/ssl.html#ssl.wrap_socket + - https://docs.python.org/3/library/ssl.html#ssl.SSLContext.wrap_socket + subcategory: + - vuln + technology: + - python + pattern: ssl.wrap_socket(...) + severity: WARNING + - fix-regex: + regex: (shell\s*=\s*)True + replacement: \1False + id: python.lang.security.audit.subprocess-shell-true.subprocess-shell-true + languages: + - python + message: Found 'subprocess' function '$FUNC' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess + - https://docs.python.org/3/library/subprocess.html + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html + subcategory: + - vuln + technology: + - python + patterns: + - pattern: subprocess.$FUNC(..., shell=True, ...) + - pattern-not: subprocess.$FUNC("...", shell=True, ...) + severity: ERROR + - id: python.lang.security.audit.system-wildcard-detected.system-wildcard-detected + languages: + - python + message: Detected use of the wildcard character in a system call that spawns a shell. This subjects the wildcard to normal shell expansion, which can have unintended consequences if there exist any non-standard file names. Consider a file named '-e sh script.sh' -- this will execute a script when 'rsync' is called. See https://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt for more information. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-155: Improper Neutralization of Wildcards or Matching Symbols' + impact: LOW + likelihood: LOW + owasp: A01:2017 - Injection + references: + - https://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt + source-url-open: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/injection_wildcard.py + subcategory: + - audit + technology: + - python + patterns: + - pattern-either: + - pattern-inside: os.system("...") + - pattern-inside: os.popen("...") + - pattern-inside: os.popen2("...") + - pattern-inside: os.popen3("...") + - pattern-inside: os.popen4("...") + - pattern-inside: subprocess.$W(..., shell=True, ...) + - pattern-regex: (tar|chmod|chown|rsync)(.*?)\* + severity: WARNING + - id: python.lang.security.audit.telnetlib.telnetlib + languages: + - python + message: Telnet does not encrypt communications. Use SSH instead. + metadata: + bandit-code: B312 + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.python.org/3/library/telnetlib.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L208 + subcategory: + - audit + technology: + - python + pattern: telnetlib.$ANYTHING(...) + severity: WARNING + - id: python.lang.security.audit.weak-ssl-version.weak-ssl-version + languages: + - python + message: An insecure SSL version was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use 'ssl.PROTOCOL_TLSv1_2' or higher. + metadata: + asvs: + control_id: 9.1.3 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v91-client-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://tools.ietf.org/html/rfc7568 + - https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html + - https://docs.python.org/3/library/ssl.html#ssl.PROTOCOL_TLSv1_2 + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/insecure_ssl_tls.py#L30 + subcategory: + - audit + technology: + - python + pattern-either: + - pattern: ssl.PROTOCOL_SSLv2 + - pattern: ssl.PROTOCOL_SSLv3 + - pattern: ssl.PROTOCOL_TLSv1 + - pattern: ssl.PROTOCOL_TLSv1_1 + - pattern: pyOpenSSL.SSL.SSLv2_METHOD + - pattern: pyOpenSSL.SSL.SSLv23_METHOD + - pattern: pyOpenSSL.SSL.SSLv3_METHOD + - pattern: pyOpenSSL.SSL.TLSv1_METHOD + - pattern: pyOpenSSL.SSL.TLSv1_1_METHOD + severity: WARNING + - id: python.lang.security.dangerous-code-run.dangerous-interactive-code-run + languages: + - python + message: Found user controlled data inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $X = code.InteractiveConsole(...) + ... + - pattern-inside: | + $X = code.InteractiveInterpreter(...) + ... + - pattern-either: + - pattern: | + $X.push($PAYLOAD,...) + - pattern: | + $X.runsource($PAYLOAD,...) + - pattern: | + $X.runcode(code.compile_command($PAYLOAD),...) + - pattern: | + $PL = code.compile_command($PAYLOAD,...) + ... + $X.runcode($PL,...) + - focus-metavariable: $PAYLOAD + - pattern-not: | + $X.push("...",...) + - pattern-not: | + $X.runsource("...",...) + - pattern-not: | + $X.runcode(code.compile_command("..."),...) + - pattern-not: | + $PL = code.compile_command("...",...) + ... + $X.runcode($PL,...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: WARNING + - id: python.lang.security.dangerous-globals-use.dangerous-globals-use + languages: + - python + message: Found non static data as an index to 'globals()'. This is extremely dangerous because it allows an attacker to execute arbitrary code on the system. Refactor your code not to use 'globals()'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://github.com/mpirnat/lets-be-bad-guys/blob/d92768fb3ade32956abd53bd6bb06e19d634a084/badguys/vulnerable/views.py#L181-L186 + subcategory: + - audit + technology: + - python + patterns: + - pattern-either: + - pattern: globals().get(...) + - pattern: locals().get(...) + - pattern: globals()[...] + - pattern: locals()[...] + - patterns: + - pattern-either: + - pattern-inside: | + $G = globals() + ... + - pattern-inside: | + $G = locals() + ... + - pattern-either: + - pattern: $G.get(...) + - pattern: $G[...] + - pattern: $FUNC.__globals__[...] + - pattern-not: globals().get("...") + - pattern-not: locals().get("...") + - pattern-not: globals()["..."] + - pattern-not: locals()["..."] + - pattern-not: $G.get("...") + - pattern-not: $G.get["..."] + - pattern-not: $G["..."] + - pattern-not: $FUNC.__globals__["..."] + - pattern-not-inside: globals()[...] = ... + - pattern-not-inside: locals()[...] = ... + - pattern-not-inside: $G[...] = ... + - pattern-not-inside: $FUNC.__globals__[...] = ... + severity: WARNING + - id: python.lang.security.dangerous-os-exec.dangerous-os-exec + languages: + - python + message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-not: os.$METHOD("...", ...) + - pattern: os.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (execl|execle|execlp|execlpe|execv|execve|execvp|execvpe) + - patterns: + - pattern-not: os.$METHOD("...", [$PATH,"...","...",...],...) + - pattern-inside: os.$METHOD($BASH,[$PATH,"-c",$CMD,...],...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (execv|execve|execvp|execvpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-not: os.$METHOD("...", $PATH, "...", "...",...) + - pattern-inside: os.$METHOD($BASH, $PATH, "-c", $CMD,...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (execl|execle|execlp|execlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: ERROR + - id: python.lang.security.dangerous-spawn-process.dangerous-spawn-process + languages: + - python + message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-not: os.$METHOD($MODE, "...", ...) + - pattern-inside: os.$METHOD($MODE, $CMD, ...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) + - patterns: + - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...) + - pattern-inside: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...) + - pattern-inside: os.$METHOD($MODE, $BASH, "-c", $CMD,...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + - patterns: + - pattern-either: + - pattern: os.environ['$ANYTHING'] + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb['$ANYTHING'] + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv[...] + - pattern: sys.orig_argv[...] + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.dangerous-subinterpreters-run-string.dangerous-subinterpreters-run-string + languages: + - python + message: Found user controlled content in `run_string`. This is dangerous because it allows a malicious actor to run arbitrary Python code. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://bugs.python.org/issue43472 + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern: | + _xxsubinterpreters.run_string($ID, $PAYLOAD, ...) + - pattern-not: | + _xxsubinterpreters.run_string($ID, "...", ...) + - focus-metavariable: $PAYLOAD + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: WARNING + - id: python.lang.security.dangerous-subprocess-use.dangerous-subprocess-use + languages: + - python + message: Detected subprocess function '$FUNC' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.escape()'. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess + - https://docs.python.org/3/library/subprocess.html + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-not: subprocess.$FUNC("...", ...) + - pattern-not: subprocess.$FUNC(["...",...], ...) + - pattern-not: subprocess.$FUNC(("...",...), ...) + - pattern-not: subprocess.CalledProcessError(...) + - pattern-not: subprocess.SubprocessError(...) + - pattern: subprocess.$FUNC($CMD, ...) + - patterns: + - pattern-not: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...) + - pattern: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD) + - patterns: + - pattern-not: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...],...) + - pattern-not: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...),...) + - pattern-either: + - pattern: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD], ...) + - pattern: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD), ...) + - patterns: + - pattern-not: subprocess.$FUNC("=~/(python)/","...",...) + - pattern: subprocess.$FUNC("=~/(python)/", $CMD) + - patterns: + - pattern-not: subprocess.$FUNC(["=~/(python)/","...",...],...) + - pattern-not: subprocess.$FUNC(("=~/(python)/","...",...),...) + - pattern-either: + - pattern: subprocess.$FUNC(["=~/(python)/", $CMD],...) + - pattern: subprocess.$FUNC(("=~/(python)/", $CMD),...) + - focus-metavariable: $CMD + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: ERROR + - id: python.lang.security.dangerous-system-call.dangerous-system-call + languages: + - python + message: Found user-controlled data used in a system call. This could allow a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. + metadata: + asvs: + control_id: 5.2.4 Dyanmic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-not: os.$W("...", ...) + - pattern-either: + - pattern: os.system(...) + - pattern: getattr(os, "system")(...) + - pattern: __import__("os").system(...) + - pattern: getattr(__import__("os"), "system")(...) + - pattern: | + $X = __import__("os") + ... + $X.system(...) + - pattern: | + $X = __import__("os") + ... + getattr($X, "system")(...) + - pattern: | + $X = getattr(os, "system") + ... + $X(...) + - pattern: | + $X = __import__("os") + ... + $Y = getattr($X, "system") + ... + $Y(...) + - pattern: os.popen(...) + - pattern: os.popen2(...) + - pattern: os.popen3(...) + - pattern: os.popen4(...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: ERROR + - id: python.lang.security.dangerous-testcapi-run-in-subinterp.dangerous-testcapi-run-in-subinterp + languages: + - python + message: Found user controlled content in `run_in_subinterp`. This is dangerous because it allows a malicious actor to run arbitrary Python code. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: HIGH + owasp: + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + _testcapi.run_in_subinterp($PAYLOAD, ...) + - pattern: | + test.support.run_in_subinterp($PAYLOAD, ...) + - focus-metavariable: $PAYLOAD + - pattern-not: | + _testcapi.run_in_subinterp("...", ...) + - pattern-not: | + test.support.run_in_subinterp("...", ...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: WARNING + - id: python.lang.security.deserialization.avoid-jsonpickle.avoid-jsonpickle + languages: + - python + message: Avoid using `jsonpickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data using `json` module. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://github.com/jsonpickle/jsonpickle#jsonpickle + - https://www.exploit-db.com/exploits/49585 + subcategory: + - audit + technology: + - jsonpickle + patterns: + - pattern: | + jsonpickle.decode($PAYLOAD,...) + - pattern-not: | + jsonpickle.decode("...",...) + severity: WARNING + - fix-regex: + count: 1 + regex: unsafe_load + replacement: safe_load + id: python.lang.security.deserialization.avoid-pyyaml-load.avoid-pyyaml-load + languages: + - python + message: Detected a possible YAML deserialization vulnerability. `yaml.unsafe_load`, `yaml.Loader`, `yaml.CLoader`, and `yaml.UnsafeLoader` are all known to be unsafe methods of deserializing YAML. An attacker with control over the YAML input could create special YAML input that allows the attacker to run arbitrary Python code. This would allow the attacker to steal files, download and install malware, or otherwise take over the machine. Use `yaml.safe_load` or `yaml.SafeLoader` instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation + - https://nvd.nist.gov/vuln/detail/CVE-2017-18342 + subcategory: + - audit + technology: + - pyyaml + patterns: + - pattern-inside: | + import yaml + ... + - pattern-not-inside: | + $YAML = ruamel.yaml.YAML(...) + ... + - pattern-either: + - pattern: yaml.unsafe_load(...) + - pattern: yaml.load(..., Loader=yaml.Loader, ...) + - pattern: yaml.load(..., Loader=yaml.UnsafeLoader, ...) + - pattern: yaml.load(..., Loader=yaml.CLoader, ...) + - pattern: yaml.load_all(..., Loader=yaml.Loader, ...) + - pattern: yaml.load_all(..., Loader=yaml.UnsafeLoader, ...) + - pattern: yaml.load_all(..., Loader=yaml.CLoader, ...) + severity: ERROR + - id: python.lang.security.deserialization.avoid-unsafe-ruamel.avoid-unsafe-ruamel + languages: + - python + message: Avoid using unsafe `ruamel.yaml.YAML()`. `ruamel.yaml.YAML` can create arbitrary Python objects. A malicious actor could exploit this to run arbitrary code. Use `YAML(typ='rt')` or `YAML(typ='safe')` instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://yaml.readthedocs.io/en/latest/basicuse.html?highlight=typ + subcategory: + - audit + technology: + - ruamel.yaml + pattern-either: + - pattern: ruamel.yaml.YAML(..., typ='unsafe', ...) + - pattern: ruamel.yaml.YAML(..., typ='base', ...) + severity: ERROR + - id: python.lang.security.deserialization.pickle.avoid-pickle + languages: + - python + message: Avoid using `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.python.org/3/library/pickle.html + subcategory: + - audit + technology: + - python + patterns: + - pattern-either: + - pattern: pickle.$FUNC(...) + - pattern: _pickle.$FUNC(...) + - pattern-not: pickle.$FUNC("...") + - pattern-not: _pickle.$FUNC("...") + severity: WARNING + - id: python.lang.security.deserialization.pickle.avoid-cpickle + languages: + - python + message: Avoid using `cPickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.python.org/3/library/pickle.html + subcategory: + - audit + technology: + - python + patterns: + - pattern: cPickle.$FUNC(...) + - pattern-not: cPickle.$FUNC("...") + severity: WARNING + - id: python.lang.security.deserialization.pickle.avoid-dill + languages: + - python + message: Avoid using `dill`, which uses `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.python.org/3/library/pickle.html + subcategory: + - audit + technology: + - python + patterns: + - pattern: dill.$FUNC(...) + - pattern-not: dill.$FUNC("...") + severity: WARNING + - id: python.lang.security.deserialization.pickle.avoid-shelve + languages: + - python + message: Avoid using `shelve`, which uses `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://docs.python.org/3/library/pickle.html + subcategory: + - audit + technology: + - python + pattern: shelve.$FUNC(...) + severity: WARNING + - id: python.lang.security.insecure-hash-algorithms-md5.insecure-hash-algorithm-md5 + languages: + - python + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + metadata: + asvs: + control_id: 6.2.2 Insecure Custom Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + bandit-code: B303 + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + subcategory: + - vuln + technology: + - python + patterns: + - pattern: hashlib.md5(...) + - pattern-not: hashlib.md5(..., usedforsecurity=False, ...) + severity: WARNING + - fix-regex: + regex: sha1 + replacement: sha256 + id: python.lang.security.insecure-hash-algorithms.insecure-hash-algorithm-sha1 + languages: + - python + message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + metadata: + asvs: + control_id: 6.2.2 Insecure Custom Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + bandit-code: B303 + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + subcategory: + - vuln + technology: + - python + pattern: hashlib.sha1(...) + severity: WARNING + - id: python.lang.security.insecure-hash-function.insecure-hash-function + languages: + - python + message: Detected use of an insecure MD4 or MD5 hash function. These functions have known vulnerabilities and are considered deprecated. Consider using 'SHA256' or a similar function instead. + metadata: + asvs: + control_id: 6.2.2 Insecure Custom Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://tools.ietf.org/html/rfc6151 + - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/hashlib_new_insecure_functions.py + subcategory: + - audit + technology: + - python + pattern-either: + - pattern: hashlib.new("=~/[M|m][D|d][4|5]/", ...) + - pattern: hashlib.new(..., name="=~/[M|m][D|d][4|5]/", ...) + severity: WARNING + - fix-regex: + regex: _create_unverified_context + replacement: create_default_context + id: python.lang.security.unverified-ssl-context.unverified-ssl-context + languages: + - python + message: Unverified SSL context detected. This will permit insecure connections without verifying SSL certificates. Use 'ssl.create_default_context' instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://docs.python.org/3/library/ssl.html#ssl-security + - https://docs.python.org/3/library/http.client.html#http.client.HTTPSConnection + subcategory: + - audit + technology: + - python + patterns: + - pattern-either: + - pattern: ssl._create_unverified_context(...) + - pattern: ssl._create_default_https_context = ssl._create_unverified_context + severity: ERROR + - fix: defusedxml.etree.ElementTree.parse($...ARGS) + id: python.lang.security.use-defused-xml-parse.use-defused-xml-parse + languages: + - python + message: The native Python `xml` library is vulnerable to XML External Entity (XXE) attacks. These attacks can leak confidential data and "XML bombs" can cause denial of service. Do not use this library to parse untrusted input. Instead the Python documentation recommends using `defusedxml`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://docs.python.org/3/library/xml.html + - https://github.com/tiran/defusedxml + - https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing + subcategory: + - vuln + technology: + - python + patterns: + - pattern: xml.etree.ElementTree.parse($...ARGS) + - pattern-not: xml.etree.ElementTree.parse("...") + severity: ERROR + - id: python.lang.security.use-defused-xml.use-defused-xml + languages: + - python + message: The Python documentation recommends using `defusedxml` instead of `xml` because the native Python `xml` library is vulnerable to XML External Entity (XXE) attacks. These attacks can leak confidential data and "XML bombs" can cause denial of service. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://docs.python.org/3/library/xml.html + - https://github.com/tiran/defusedxml + - https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing + subcategory: + - audit + technology: + - python + pattern: import xml + severity: ERROR + - id: python.lang.security.use-defused-xmlrpc.use-defused-xmlrpc + languages: + - python + message: Detected use of xmlrpc. xmlrpc is not inherently safe from vulnerabilities. Use defusedxml.xmlrpc instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-776: Improper Restriction of Recursive Entity References in DTDs (''XML Entity Expansion'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://pypi.org/project/defusedxml/ + - https://docs.python.org/3/library/xml.html#xml-vulnerabilities + source-rule-url: https://github.com/PyCQA/bandit/blob/07f84cb5f5e7c1055e6feaa0fe93afa471de0ac3/bandit/blacklists/imports.py#L160 + subcategory: + - audit + technology: + - python + pattern-either: + - pattern: import xmlrpclib + - pattern: import SimpleXMLRPCServer + - pattern: import xmlrpc + severity: ERROR + - fix-regex: + regex: csv + replacement: defusedcsv + id: python.lang.security.use-defusedcsv.use-defusedcsv + languages: + - python + message: Detected the generation of a CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-1236: Improper Neutralization of Formula Elements in a CSV File' + impact: LOW + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/raphaelm/defusedcsv + - https://owasp.org/www-community/attacks/CSV_Injection + - https://web.archive.org/web/20220516052229/https://www.contextis.com/us/blog/comma-separated-vulnerabilities + subcategory: + - audit + technology: + - python + patterns: + - pattern: csv.writer(...) + - pattern-not: defusedcsv.writer(...) + severity: INFO + - id: python.pycryptodome.security.insecure-cipher-algorithm-blowfish.insecure-cipher-algorithm-blowfish + languages: + - python + message: Detected Blowfish cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. + metadata: + bandit-code: B304 + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://stackoverflow.com/questions/1135186/whats-wrong-with-xor-encryption + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Cryptodome.Cipher.Blowfish.new(...) + - pattern: Crypto.Cipher.Blowfish.new(...) + severity: WARNING + - id: python.pycryptodome.security.insecure-cipher-algorithm-des.insecure-cipher-algorithm-des + languages: + - python + message: Detected DES cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. + metadata: + bandit-code: B304 + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://cwe.mitre.org/data/definitions/326.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Cryptodome.Cipher.DES.new(...) + - pattern: Crypto.Cipher.DES.new(...) + severity: WARNING + - id: python.pycryptodome.security.insecure-cipher-algorithm-rc2.insecure-cipher-algorithm-rc2 + languages: + - python + message: Detected RC2 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. + metadata: + bandit-code: B304 + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://cwe.mitre.org/data/definitions/326.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Cryptodome.Cipher.ARC2.new(...) + - pattern: Crypto.Cipher.ARC2.new(...) + severity: WARNING + - id: python.pycryptodome.security.insecure-cipher-algorithm-rc4.insecure-cipher-algorithm-rc4 + languages: + - python + message: Detected ARC4 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. + metadata: + bandit-code: B304 + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://cwe.mitre.org/data/definitions/326.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Cryptodome.Cipher.ARC4.new(...) + - pattern: Crypto.Cipher.ARC4.new(...) + severity: WARNING + - id: python.pycryptodome.security.insecure-cipher-algorithm.insecure-cipher-algorithm-xor + languages: + - python + message: Detected XOR cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. + metadata: + bandit-code: B304 + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://stackoverflow.com/questions/1135186/whats-wrong-with-xor-encryption + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Cryptodome.Cipher.XOR.new(...) + - pattern: Crypto.Cipher.XOR.new(...) + severity: WARNING + - id: python.pycryptodome.security.insecure-hash-algorithm-md2.insecure-hash-algorithm-md2 + languages: + - python + message: Detected MD2 hash algorithm which is considered insecure. MD2 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Crypto.Hash.MD2.new(...) + - pattern: Cryptodome.Hash.MD2.new (...) + severity: WARNING + - id: python.pycryptodome.security.insecure-hash-algorithm-md4.insecure-hash-algorithm-md4 + languages: + - python + message: Detected MD4 hash algorithm which is considered insecure. MD4 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Crypto.Hash.MD4.new(...) + - pattern: Cryptodome.Hash.MD4.new (...) + severity: WARNING + - id: python.pycryptodome.security.insecure-hash-algorithm-md5.insecure-hash-algorithm-md5 + languages: + - python + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Crypto.Hash.MD5.new(...) + - pattern: Cryptodome.Hash.MD5.new (...) + severity: WARNING + - id: python.pycryptodome.security.insecure-hash-algorithm.insecure-hash-algorithm-sha1 + languages: + - python + message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Crypto.Hash.SHA.new(...) + - pattern: Cryptodome.Hash.SHA.new (...) + severity: WARNING + - id: python.pycryptodome.security.insufficient-dsa-key-size.insufficient-dsa-key-size + languages: + - python + message: Detected an insufficient key size for DSA. NIST recommends a key size of 2048 or higher. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py + subcategory: + - vuln + technology: + - pycryptodome + patterns: + - pattern-either: + - pattern: Crypto.PublicKey.DSA.generate(..., bits=$SIZE, ...) + - pattern: Crypto.PublicKey.DSA.generate($SIZE, ...) + - pattern: Cryptodome.PublicKey.DSA.generate(..., bits=$SIZE, ...) + - pattern: Cryptodome.PublicKey.DSA.generate($SIZE, ...) + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE + severity: WARNING + - id: python.pycryptodome.security.insufficient-rsa-key-size.insufficient-rsa-key-size + languages: + - python + message: Detected an insufficient key size for RSA. NIST recommends a key size of 2048 or higher. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py + subcategory: + - vuln + technology: + - pycryptodome + patterns: + - pattern-either: + - pattern: Crypto.PublicKey.RSA.generate(..., bits=$SIZE, ...) + - pattern: Crypto.PublicKey.RSA.generate($SIZE, ...) + - pattern: Cryptodome.PublicKey.RSA.generate(..., bits=$SIZE, ...) + - pattern: Cryptodome.PublicKey.RSA.generate($SIZE, ...) + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE + severity: WARNING + - id: python.pycryptodome.security.mode-without-authentication.crypto-mode-without-authentication + languages: + - python + message: 'An encryption mode of operation is being used without proper message authentication. This can potentially result in the encrypted content to be decrypted by an attacker. Consider instead use an AEAD mode of operation like GCM. ' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - cryptography + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + AES.new(..., $PYCRYPTODOME_MODE) + - pattern-not-inside: | + AES.new(..., $PYCRYPTODOME_MODE) + ... + HMAC.new + - metavariable-pattern: + metavariable: $PYCRYPTODOME_MODE + patterns: + - pattern-either: + - pattern: AES.MODE_CBC + - pattern: AES.MODE_CTR + - pattern: AES.MODE_CFB + - pattern: AES.MODE_OFB + severity: ERROR + - fix-regex: + regex: MONGODB-CR + replacement: SCRAM-SHA-256 + id: python.pymongo.security.mongodb.mongo-client-bad-auth + languages: + - python + message: Warning MONGODB-CR was deprecated with the release of MongoDB 3.6 and is no longer supported by MongoDB 4.0 (see https://api.mongodb.com/python/current/examples/authentication.html for details). + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-477: Use of Obsolete Function' + impact: LOW + likelihood: LOW + references: + - https://cwe.mitre.org/data/definitions/477.html + subcategory: + - vuln + technology: + - pymongo + pattern: | + pymongo.MongoClient(..., authMechanism='MONGODB-CR') + severity: WARNING + - fix: | + $...PARAMS, httponly=True + id: python.pyramid.audit.authtkt-cookie-httponly-unsafe-default.pyramid-authtkt-cookie-httponly-unsafe-default + languages: + - python + message: Found a Pyramid Authentication Ticket cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern: pyramid.authentication.$FUNC($...PARAMS) + - metavariable-pattern: + metavariable: $FUNC + pattern-either: + - pattern: AuthTktCookieHelper + - pattern: AuthTktAuthenticationPolicy + - pattern-not: pyramid.authentication.$FUNC(..., httponly=$HTTPONLY, ...) + - pattern-not: pyramid.authentication.$FUNC(..., **$PARAMS, ...) + - focus-metavariable: $...PARAMS + severity: WARNING + - fix: | + True + id: python.pyramid.audit.authtkt-cookie-httponly-unsafe-value.pyramid-authtkt-cookie-httponly-unsafe-value + languages: + - python + message: Found a Pyramid Authentication Ticket cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - patterns: + - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktCookieHelper(..., httponly=$HTTPONLY, ...) + - patterns: + - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., httponly=$HTTPONLY, ...) + - pattern: $HTTPONLY + - metavariable-pattern: + metavariable: $HTTPONLY + pattern: | + False + severity: WARNING + - fix: | + 'Lax' + id: python.pyramid.audit.authtkt-cookie-samesite.pyramid-authtkt-cookie-samesite + languages: + - python + message: Found a Pyramid Authentication Ticket without the samesite option correctly set. Pyramid cookies should be handled securely by setting samesite='Lax'. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - pattern: pyramid.authentication.AuthTktCookieHelper(..., samesite=$SAMESITE, ...) + - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., samesite=$SAMESITE, ...) + - pattern: $SAMESITE + - metavariable-regex: + metavariable: $SAMESITE + regex: (?!'Lax') + severity: WARNING + - fix-regex: + regex: (.*)\) + replacement: \1, secure=True) + id: python.pyramid.audit.authtkt-cookie-secure-unsafe-default.pyramid-authtkt-cookie-secure-unsafe-default + languages: + - python + message: Found a Pyramid Authentication Ticket cookie using an unsafe default for the secure option. Pyramid cookies should be handled securely by setting secure=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - patterns: + - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., secure=$SECURE, ...) + - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktCookieHelper(...) + - patterns: + - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., secure=$SECURE, ...) + - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(...) + severity: WARNING + - fix: | + True + id: python.pyramid.audit.authtkt-cookie-secure-unsafe-value.pyramid-authtkt-cookie-secure-unsafe-value + languages: + - python + message: Found a Pyramid Authentication Ticket cookie without the secure option correctly set. Pyramid cookies should be handled securely by setting secure=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - patterns: + - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktCookieHelper(..., secure=$SECURE, ...) + - patterns: + - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., secure=$SECURE, ...) + - pattern: $SECURE + - metavariable-pattern: + metavariable: $SECURE + pattern: | + False + severity: WARNING + - fix: | + True + id: python.pyramid.audit.csrf-check-disabled.pyramid-csrf-check-disabled + languages: + - python + message: CSRF protection is disabled for this view. This is a security risk. + metadata: + asvs: + control_id: 4.2.2 CSRF + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V4-Access-Control.md#v42-operation-level-access-control + section: V4 Access Control + version: "4" + category: security + confidence: LOW + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - pyramid + patterns: + - pattern-inside: | + from pyramid.view import view_config + ... + @view_config(..., require_csrf=$REQUIRE_CSRF, ...) + def $VIEW(...): + ... + - pattern: $REQUIRE_CSRF + - metavariable-comparison: + comparison: $REQUIRE_CSRF == False + metavariable: $REQUIRE_CSRF + severity: WARNING + - fix: | + True + id: python.pyramid.audit.csrf-origin-check-disabled-globally.pyramid-csrf-origin-check-disabled-globally + languages: + - python + message: Automatic check of the referrer for cross-site request forgery tokens has been explicitly disabled globally, which might leave views unprotected when an unsafe CSRF storage policy is used. Use 'pyramid.config.Configurator.set_default_csrf_options(check_origin=True)' to turn the automatic check for all unsafe methods (per RFC2616). + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-inside: | + $CONFIG.set_default_csrf_options(..., check_origin=$CHECK_ORIGIN, ...) + - pattern: $CHECK_ORIGIN + - metavariable-comparison: + comparison: $CHECK_ORIGIN == False + metavariable: $CHECK_ORIGIN + severity: ERROR + - fix: | + True + id: python.pyramid.audit.csrf-origin-check-disabled.pyramid-csrf-origin-check-disabled + languages: + - python + message: Origin check for the CSRF token is disabled for this view. This might represent a security risk if the CSRF storage policy is not known to be secure. + metadata: + asvs: + control_id: 4.2.2 CSRF + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V4-Access-Control.md#v42-operation-level-access-control + section: V4 Access Control + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-inside: | + from pyramid.view import view_config + ... + @view_config(..., check_origin=$CHECK_ORIGIN, ...) + def $VIEW(...): + ... + - pattern: $CHECK_ORIGIN + - metavariable-comparison: + comparison: $CHECK_ORIGIN == False + metavariable: $CHECK_ORIGIN + severity: WARNING + - fix-regex: + regex: (.*)\) + replacement: \1, httponly=True) + id: python.pyramid.audit.set-cookie-httponly-unsafe-default.pyramid-set-cookie-httponly-unsafe-default + languages: + - python + message: Found a Pyramid cookie using an unsafe default for the httponly option. Pyramid cookies should be handled securely by setting httponly=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., httponly=$HTTPONLY, ...) + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(...) + severity: WARNING + - fix: | + True + id: python.pyramid.audit.set-cookie-httponly-unsafe-value.pyramid-set-cookie-httponly-unsafe-value + languages: + - python + message: Found a Pyramid cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/www-community/controls/SecureCookieAttribute + - https://owasp.org/www-community/HttpOnly + - https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#httponly-attribute + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(..., httponly=$HTTPONLY, ...) + - pattern: $HTTPONLY + - metavariable-pattern: + metavariable: $HTTPONLY + pattern: | + False + severity: WARNING + - fix-regex: + regex: (.*)\) + replacement: \1, samesite='Lax') + id: python.pyramid.audit.set-cookie-samesite-unsafe-default.pyramid-set-cookie-samesite-unsafe-default + languages: + - python + message: Found a Pyramid cookie using an unsafe value for the samesite option. Pyramid cookies should be handled securely by setting samesite='Lax' in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., samesite=$SAMESITE, ...) + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(...) + severity: WARNING + - fix: | + 'Lax' + id: python.pyramid.audit.set-cookie-samesite-unsafe-value.pyramid-set-cookie-samesite-unsafe-value + languages: + - python + message: Found a Pyramid cookie without the samesite option correctly set. Pyramid cookies should be handled securely by setting samesite='Lax' in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(..., samesite=$SAMESITE, ...) + - pattern: $SAMESITE + - metavariable-regex: + metavariable: $SAMESITE + regex: (?!'Lax') + severity: WARNING + - fix-regex: + regex: (.*)\) + replacement: \1, secure=True) + id: python.pyramid.audit.set-cookie-secure-unsafe-default.pyramid-set-cookie-secure-unsafe-default + languages: + - python + message: Found a Pyramid cookie using an unsafe default for the secure option. Pyramid cookies should be handled securely by setting secure=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., secure=$SECURE, ...) + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(...) + severity: WARNING + - fix: | + True + id: python.pyramid.audit.set-cookie-secure-unsafe-value.pyramid-set-cookie-secure-unsafe-value + languages: + - python + message: Found a Pyramid cookie without the secure option correctly set. Pyramid cookies should be handled securely by setting secure=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(..., secure=$SECURE, ...) + - pattern: $SECURE + - metavariable-pattern: + metavariable: $SECURE + pattern: | + False + severity: WARNING + - fix: | + True + id: python.pyramid.security.csrf-check-disabled-globally.pyramid-csrf-check-disabled-globally + languages: + - python + message: Automatic check of cross-site request forgery tokens has been explicitly disabled globally, which might leave views unprotected. Use 'pyramid.config.Configurator.set_default_csrf_options(require_csrf=True)' to turn the automatic check for all unsafe methods (per RFC2616). + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-inside: | + $CONFIG.set_default_csrf_options(..., require_csrf=$REQUIRE_CSRF, ...) + - pattern: $REQUIRE_CSRF + - metavariable-comparison: + comparison: $REQUIRE_CSRF == False + metavariable: $REQUIRE_CSRF + severity: ERROR + - id: python.pyramid.security.direct-use-of-response.pyramid-direct-use-of-response + languages: + - python + message: Detected data rendered directly to the end user via 'Response'. This bypasses Pyramid's built-in cross-site scripting (XSS) defenses and could result in an XSS vulnerability. Use Pyramid's template engines to safely render HTML. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - pyramid + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + pyramid.request.Response.text($SINK) + - pattern: | + pyramid.request.Response($SINK) + - pattern: | + $REQ.response.body = $SINK + - pattern: | + $REQ.response.text = $SINK + - pattern: | + $REQ.response.ubody = $SINK + - pattern: | + $REQ.response.unicode_body = $SINK + - pattern: $SINK + pattern-sources: + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: ERROR + - fix-regex: + regex: format + replacement: bindparams + id: python.pyramid.security.sqlalchemy-sql-injection.pyramid-sqlalchemy-sql-injection + languages: + - python + message: Distinct, Having, Group_by, Order_by, and Filter in SQLAlchemy can cause sql injections if the developer inputs raw SQL into the before-mentioned clauses. This pattern captures relevant cases in which the developer inputs raw SQL into the distinct, having, group_by, order_by or filter clauses and injects user-input into the raw SQL with any function besides "bindparams". Use bindParams to securely bind user-input to SQL statements. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.sqlalchemy.org/en/14/tutorial/data_select.html#tutorial-selecting-data + subcategory: + - vuln + technology: + - pyramid + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + $QUERY = $REQ.dbsession.query(...) + ... + - pattern-either: + - pattern: | + $QUERY.$SQLFUNC("...".$FORMATFUNC(..., $SINK, ...)) + - pattern: | + $QUERY.join(...).$SQLFUNC("...".$FORMATFUNC(..., $SINK, ...)) + - pattern: $SINK + - metavariable-regex: + metavariable: $SQLFUNC + regex: (group_by|order_by|distinct|having|filter) + - metavariable-regex: + metavariable: $FORMATFUNC + regex: (?!bindparams) + pattern-sources: + - patterns: + - pattern-inside: | + from pyramid.view import view_config + ... + @view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: ERROR + - id: python.requests.best-practice.use-raise-for-status.use-raise-for-status + languages: + - python + message: There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a 500 error while you're only checking for a 401. + metadata: + category: best-practice + references: + - https://requests.readthedocs.io/en/master/api/#requests.Response.raise_for_status + technology: + - requests + patterns: + - pattern-either: + - pattern: requests.request(...) + - pattern: requests.get(...) + - pattern: requests.post(...) + - pattern: requests.put(...) + - pattern: requests.delete(...) + - pattern: requests.head(...) + - pattern: requests.patch(...) + - pattern-not-inside: | + $RESP = requests.$METHOD(...) + $RESP.raise_for_status(...) + - pattern-not-inside: | + requests.$METHOD(...).raise_for_status(...) + - pattern-not-inside: | + $RESP = requests.$METHOD(...) + if $RESP.status_code == ...: + ... + - pattern-not-inside: | + $RESP = requests.$METHOD(...) + if $RESP.status_code != ...: + ... + - pattern-not-inside: | + $RESP = requests.$METHOD(...) + ... + if $RESP.ok: + ... + - pattern-not-inside: | + $RESP = requests.$METHOD(...) + ... + if not $RESP.ok: + ... + - pattern-not-inside: | + with ...: + ... + $RESP = requests.$METHOD(...) + ... + $RESP.raise_for_status(...) + - pattern-not-inside: | + with ... as ...: + ... + $RESP = requests.$METHOD(...) + ... + $RESP.raise_for_status(...) + severity: WARNING + - id: python.requests.best-practice.use-request-json-shortcut.python.requests.best-practice.use-request-json-shortcut + languages: + - python + message: The requests library has a convenient shortcut for sending JSON requests, which lets you stop worrying about serializing the body yourself. To use it, replace `body=json.dumps(...)` with `json=...`. + metadata: + category: best-practice + references: + - https://requests.readthedocs.io/en/stable/user/quickstart/#more-complicated-post-requests + technology: + - requests + patterns: + - pattern-inside: import json; ... + - pattern-inside: import requests; ... + - pattern: requests.$METHOD(..., body=json.dumps($BODY), ...) + severity: WARNING + - fix: $RESP.json() + id: python.requests.best-practice.use-response-json-shortcut.python.requests.best-practice.use-response-json-shortcut + languages: + - python + message: The requests library has a convenient shortcut for reading JSON responses, which lets you stop worrying about deserializing the response yourself. + metadata: + category: best-practice + references: + - https://requests.readthedocs.io/en/stable/user/quickstart/#json-response-content + technology: + - requests + patterns: + - pattern-inside: import json; ... + - pattern-inside: import requests; ... + - pattern-inside: $RESP = requests.$METHOD(...); ... + - pattern: json.loads($RESP.text) + severity: WARNING + - fix-regex: + regex: (.*)\)$ + replacement: \1, timeout=30) + id: python.requests.best-practice.use-timeout.use-timeout + languages: + - python + message: Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a timeout for all 'requests'. + metadata: + category: best-practice + references: + - https://docs.python-requests.org/en/latest/user/advanced/?highlight=timeout#timeouts + - https://requests.readthedocs.io/en/latest/user/quickstart/#timeouts + technology: + - requests + pattern-either: + - patterns: + - pattern-not: requests.$W(..., timeout=$N, ...) + - pattern-not: requests.$W(..., **$KWARGS) + - pattern-either: + - pattern: requests.request(...) + - pattern: requests.get(...) + - pattern: requests.post(...) + - pattern: requests.put(...) + - pattern: requests.delete(...) + - pattern: requests.head(...) + - pattern: requests.patch(...) + - patterns: + - pattern-inside: | + $SESSION = requests.Session(...) + ... + - pattern-not: | + $SESSION.$W(..., timeout=$N, ...) + - pattern-not: | + $SESSION.$W(..., **$KWARGS) + - pattern-either: + - pattern: $SESSION.get(...) + - pattern: $SESSION.post(...) + - pattern: $SESSION.put(...) + - pattern: $SESSION.delete(...) + - pattern: $SESSION.head(...) + - pattern: $SESSION.patch(...) + severity: WARNING + - fix-regex: + regex: verify(\s)*=(\s)*False + replacement: verify=True + id: python.requests.security.disabled-cert-validation.disabled-cert-validation + languages: + - python + message: Certificate verification has been explicitly disabled. This permits insecure connections to insecure servers. Re-enable certification validation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://stackoverflow.com/questions/41740361/is-it-safe-to-disable-ssl-certificate-verification-in-pythonss-requests-lib + subcategory: + - audit + technology: + - requests + pattern-either: + - pattern: requests.put(..., verify=False, ...) + - pattern: requests.patch(..., verify=False, ...) + - pattern: requests.delete(..., verify=False, ...) + - pattern: requests.head(..., verify=False, ...) + - pattern: requests.options(..., verify=False, ...) + - pattern: requests.request(..., verify=False, ...) + - pattern: requests.get(..., verify=False, ...) + - pattern: requests.post(..., verify=False, ...) + severity: ERROR + - fix-regex: + count: 1 + regex: http:\/\/ + replacement: https:// + id: python.requests.security.no-auth-over-http.no-auth-over-http + languages: + - python + message: Authentication detected over HTTP. HTTP does not provide any encryption or protection for these authentication credentials. This may expose these credentials to unauthorized parties. Use 'https://' instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-523: Unprotected Transport of Credentials' + impact: LOW + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A02:2021 - Cryptographic Failures + references: + - https://semgrep.dev/blog/2020/bento-check-no-auth-over-http/ + - https://bento.dev/checks/requests/no-auth-over-http/ + source-rule-url: https://pypi.org/project/flake8-flask/ + subcategory: + - audit + technology: + - requests + pattern-either: + - pattern: requests.$W("=~/http:\/\/.*/", ..., auth=$X, ...) + - pattern: | + $URL = "=~/http:\/\/.../" + ... + requests.$W($URL, ..., auth=$X, ...) + severity: ERROR + - id: python.sh.security.string-concat.string-concat + languages: + - python + message: Detected string concatenation or formatting in a call to a command via 'sh'. This could be a command injection vulnerability if the data is user-controlled. Instead, use a list and append the argument. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - sh + pattern-either: + - pattern: sh.$BIN($X + $Y) + - pattern: sh.$BIN($X.format(...)) + - pattern: sh.$BIN(f"...{...}...") + severity: ERROR + - id: python.sqlalchemy.correctness.bad-operator-in-filter.bad-operator-in-filter + languages: + - python + message: Only comparison operators should be used inside SQLAlchemy filter expressions. Use `==` instead of `is`, `!=` instead of `is not`, `sqlalchemy.and_` instead of `and`, `sqlalchemy.or_` instead of `or`, `sqlalchemy.not_` instead of `not`, and `sqlalchemy.in_` instead of `in_`. + metadata: + category: correctness + references: + - https://docs.sqlalchemy.org/en/13/orm/tutorial.html#common-filter-operators + technology: + - sqlalchemy + patterns: + - pattern-inside: | + def $ANY(...): + ... + $MODEL.query + - pattern-inside: | + $TARGET.filter(...) + - pattern-either: + - pattern: not $A + - pattern: $A is $B + - pattern: $A is not $B + - pattern: $A and $B + - pattern: $A or $B + - pattern: $A in $B + - pattern: $A not in $B + severity: WARNING + - id: python.sqlalchemy.correctness.delete-where.delete-where-no-execute + languages: + - python + message: .delete().where(...) results in a no-op in SQLAlchemy unless the command is executed, use .filter(...).delete() instead. + metadata: + category: correctness + technology: + - sqlalchemy + patterns: + - pattern: $X.delete().where(...) + - pattern-not-inside: $X.delete().where(...).execute() + - pattern-not-inside: $C.execute(...) + severity: ERROR + - id: python.sqlalchemy.performance.performance-improvements.len-all-count + languages: + - python + message: Using QUERY.count() instead of len(QUERY.all()) sends less data to the client since the SQLAlchemy method is performed server-side. + metadata: + category: performance + technology: + - sqlalchemy + pattern: len($X.all()) + severity: WARNING + - id: python.sqlalchemy.performance.performance-improvements.batch-import + languages: + - python + message: Rather than adding one element at a time, consider batch loading to improve performance. + metadata: + category: performance + technology: + - sqlalchemy + pattern: | + for $X in $Y: + db.session.add($Z) + severity: WARNING + - id: python.sqlalchemy.security.audit.avoid-sqlalchemy-text.avoid-sqlalchemy-text + languages: + - python + message: sqlalchemy.text passes the constructed SQL statement to the database mostly unchanged. This means that the usual SQL injection protections are not applied and this function is vulnerable to SQL injection if user input can reach here. Use normal SQLAlchemy operators (such as or_, and_, etc.) to construct SQL. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql + subcategory: + - audit + technology: + - sqlalchemy + mode: taint + pattern-sinks: + - pattern: | + sqlalchemy.text(...) + pattern-sources: + - patterns: + - pattern: | + $X + $Y + - metavariable-type: + metavariable: $X + type: string + - patterns: + - pattern: | + $X + $Y + - metavariable-type: + metavariable: $Y + type: string + - patterns: + - pattern: | + f"..." + - patterns: + - pattern: | + $X.format(...) + - metavariable-type: + metavariable: $X + type: string + - patterns: + - pattern: | + $X % $Y + - metavariable-type: + metavariable: $X + type: string + severity: ERROR + - id: python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query + languages: + - python + message: 'Avoiding SQL string concatenation: untrusted input concatenated with raw SQL query can result in SQL Injection. In order to execute raw query safely, prepared statement should be used. SQLAlchemy provides TextualSQL to easily used prepared statement with named parameters. For complex SQL composition, use SQL Expression Language or Schema Definition Language. In most cases, SQLAlchemy ORM will be a better option.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql + - https://www.tutorialspoint.com/sqlalchemy/sqlalchemy_quick_guide.htm + - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-more-specific-text-with-table-expression-literal-column-and-expression-column + subcategory: + - audit + technology: + - sqlalchemy + pattern-either: + - pattern: | + $CONNECTION.execute( $SQL + ..., ... ) + - pattern: | + $CONNECTION.execute( $SQL % (...), ...) + - pattern: | + $CONNECTION.execute( $SQL.format(...), ... ) + - pattern: | + $CONNECTION.execute(f"...{...}...", ...) + - patterns: + - pattern-inside: | + $QUERY = $SQL + ... + ... + - pattern: | + $CONNECTION.execute($QUERY, ...) + - patterns: + - pattern-inside: | + $QUERY = $SQL % (...) + ... + - pattern: | + $CONNECTION.execute($QUERY, ...) + - patterns: + - pattern-inside: | + $QUERY = $SQL.format(...) + ... + - pattern: | + $CONNECTION.execute($QUERY, ...) + - patterns: + - pattern-inside: | + $QUERY = f"...{...}..." + ... + - pattern: | + $CONNECTION.execute($QUERY, ...) + severity: ERROR + - fix-regex: + regex: format + replacement: bindparams + id: python.sqlalchemy.security.sqlalchemy-sql-injection.sqlalchemy-sql-injection + languages: + - python + message: Distinct, Having, Group_by, Order_by, and Filter in SQLAlchemy can cause sql injections if the developer inputs raw SQL into the before-mentioned clauses. This pattern captures relevant cases in which the developer inputs raw SQL into the distinct, having, group_by, order_by or filter clauses and injects user-input into the raw SQL with any function besides "bindparams". Use bindParams to securely bind user-input to SQL statements. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - sqlalchemy + patterns: + - pattern-either: + - pattern: | + def $FUNC(...,$VAR,...): + ... + $SESSION.query(...).$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) + - pattern: | + def $FUNC(...,$VAR,...): + ... + $SESSION.query.join(...).$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) + - pattern: | + def $FUNC(...,$VAR,...): + ... + $SESSION.query.$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) + - pattern: | + def $FUNC(...,$VAR,...): + ... + query.$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) + - metavariable-regex: + metavariable: $SQLFUNC + regex: (group_by|order_by|distinct|having|filter) + - metavariable-regex: + metavariable: $FORMATFUNC + regex: (?!bindparams) + severity: WARNING + - id: python.twilio.security.twiml-injection.twiml-injection + languages: + - python + message: Using non-constant TwiML (Twilio Markup Language) argument when creating a Twilio conversation could allow the injection of additional TwiML commands + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-91: XML Injection' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2021 - Injection + references: + - https://codeberg.org/fennix/funjection + subcategory: vuln + technology: + - python + - twilio + - twiml + mode: taint + pattern-sanitizers: + - pattern: xml.sax.saxutils.escape(...) + - pattern: html.escape(...) + pattern-sinks: + - patterns: + - pattern: | + $CLIENT.calls.create(..., twiml=$SINK, ...) + - focus-metavariable: $SINK + pattern-sources: + - pattern: | + f"..." + - pattern: | + "..." % ... + - pattern: | + "...".format(...) + - patterns: + - pattern: $ARG + - pattern-inside: | + def $F(..., $ARG, ...): + ... + severity: WARNING + - id: ruby.aws-lambda.security.activerecord-sqli.activerecord-sqli + languages: + - ruby + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `Example.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]`' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://guides.rubyonrails.org/active_record_querying.html#finding-by-sql + subcategory: + - vuln + technology: + - aws-lambda + - active-record + mode: taint + pattern-sinks: + - patterns: + - pattern: $QUERY + - pattern-either: + - pattern: ActiveRecord::Base.connection.execute($QUERY,...) + - pattern: $MODEL.find_by_sql($QUERY,...) + - pattern: $MODEL.select_all($QUERY,...) + - pattern-inside: | + require 'active_record' + ... + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context) + ... + end + severity: WARNING + - id: ruby.aws-lambda.security.mysql2-sqli.mysql2-sqli + languages: + - ruby + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use sanitize statements like so: `escaped = client.escape(user_input)`' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/brianmario/mysql2 + subcategory: + - vuln + technology: + - aws-lambda + - mysql2 + mode: taint + pattern-sanitizers: + - pattern: $CLIENT.escape(...) + pattern-sinks: + - patterns: + - pattern: $QUERY + - pattern-either: + - pattern: $CLIENT.query($QUERY,...) + - pattern: $CLIENT.prepare($QUERY,...) + - pattern-inside: | + require 'mysql2' + ... + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context) + ... + end + severity: WARNING + - id: ruby.aws-lambda.security.pg-sqli.pg-sqli + languages: + - ruby + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `conn.exec_params(''SELECT $1 AS a, $2 AS b, $3 AS c'', [1, 2, nil])`' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://www.rubydoc.info/gems/pg/PG/Connection + subcategory: + - vuln + technology: + - aws-lambda + - postgres + - pg + mode: taint + pattern-sinks: + - patterns: + - pattern: $QUERY + - pattern-either: + - pattern: $CONN.exec($QUERY,...) + - pattern: $CONN.exec_params($QUERY,...) + - pattern: $CONN.exec_prepared($QUERY,...) + - pattern: $CONN.async_exec($QUERY,...) + - pattern: $CONN.async_exec_params($QUERY,...) + - pattern: $CONN.async_exec_prepared($QUERY,...) + - pattern-inside: | + require 'pg' + ... + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context) + ... + end + severity: WARNING + - id: ruby.aws-lambda.security.sequel-sqli.sequel-sqli + languages: + - ruby + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `DB[''select * from items where name = ?'', name]`' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/jeremyevans/sequel#label-Arbitrary+SQL+queries + subcategory: + - vuln + technology: + - aws-lambda + - sequel + mode: taint + pattern-sinks: + - patterns: + - pattern: $QUERY + - pattern-either: + - pattern: DB[$QUERY,...] + - pattern: DB.run($QUERY,...) + - pattern-inside: | + require 'sequel' + ... + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context) + ... + end + severity: WARNING + - id: ruby.aws-lambda.security.tainted-deserialization.tainted-deserialization + languages: + - ruby + message: Deserialization of a string tainted by `event` object found. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of `load` can cause remote code execution. Loading user input with MARSHAL, YAML or CSV can potentially be dangerous. If you need to deserialize untrusted data, you should use JSON as it is only capable of returning 'primitive' types such as strings, arrays, hashes, numbers and nil. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://ruby-doc.org/core-3.1.2/doc/security_rdoc.html + - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb + subcategory: + - vuln + technology: + - ruby + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern: $SINK + - pattern-either: + - pattern-inside: | + YAML.load($SINK,...) + - pattern-inside: | + CSV.load($SINK,...) + - pattern-inside: | + Marshal.load($SINK,...) + - pattern-inside: | + Marshal.restore($SINK,...) + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context) + ... + end + severity: WARNING + - id: ruby.aws-lambda.security.tainted-sql-string.tainted-sql-string + languages: + - ruby + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://rorsecurity.info/portfolio/ruby-on-rails-sql-injection-cheat-sheet + subcategory: + - vuln + technology: + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: | + "...#{...}..." + - pattern-regex: (?i)(select|delete|insert|create|update|alter|drop)\b|\w+\s*!?[<>=].* + - patterns: + - pattern-either: + - pattern: Kernel::sprintf("$SQLSTR", ...) + - pattern: | + "$SQLSTR" + $EXPR + - pattern: | + "$SQLSTR" % $EXPR + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b|\w+\s*!?[<>=].* + - pattern-not-inside: | + puts(...) + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context) + ... + end + severity: ERROR + - id: ruby.jwt.security.audit.jwt-decode-without-verify.ruby-jwt-decode-without-verify + languages: + - ruby + message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-345: Insufficient Verification of Data Authenticity' + impact: LOW + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + patterns: + - pattern-inside: | + require 'jwt' + ... + - pattern: JWT.decode($PAYLOAD,$SECRET,false,...) + severity: WARNING + - id: ruby.jwt.security.audit.jwt-exposed-data.ruby-jwt-exposed-data + languages: + - ruby + message: The object is passed strictly to jsonwebtoken.sign(...) Make sure that sensitive information is not exposed through JWT token payload. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + patterns: + - pattern-inside: | + require 'jwt' + ... + - pattern-inside: | + def $FUNC(...,$INPUT,...) + ... + end + - pattern: | + JWT.encode($INPUT,...) + severity: WARNING + - id: ruby.jwt.security.jwt-exposed-credentials.ruby-jwt-exposed-credentials + languages: + - ruby + message: Password is exposed through JWT token payload. This is not encrypted and the password could be compromised. Do not store passwords in JWT tokens. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://cwe.mitre.org/data/definitions/522.html + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + patterns: + - pattern-inside: | + require 'jwt' + ... + - pattern: | + $PAYLOAD = {...,password:...,...} + ... + JWT.encode($PAYLOAD,...) + severity: ERROR + - id: ruby.jwt.security.jwt-hardcode.ruby-jwt-hardcoded-secret + languages: + - ruby + message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: LOW + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + patterns: + - pattern-inside: | + require 'jwt' + ... + - pattern-either: + - pattern: | + JWT.encode($PAYLOAD,"...",...) + - pattern: | + JWT.decode($PAYLOAD,"...",...) + - pattern: | + JWT.encode($PAYLOAD,nil,...) + - pattern: | + JWT.decode($PAYLOAD,nil,...) + - pattern: | + $SECRET = "..." + ... + JWT.encode($PAYLOAD,$SECRET,...) + - pattern: | + $SECRET = "..." + ... + JWT.decode($PAYLOAD,$SECRET,...) + - pattern-not: | + JWT.encode($PAYLOAD, nil, ... , jwks: ..., ...) + - pattern-not: | + JWT.decode($PAYLOAD, nil, ..., jwks: ..., ...) + severity: ERROR + - id: ruby.jwt.security.jwt-none-alg.ruby-jwt-none-alg + languages: + - ruby + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + patterns: + - pattern-inside: | + require 'jwt' + ... + - pattern: | + JWT.encode($PAYLOAD, $SECRET, 'none', ...) + severity: ERROR + - id: ruby.lang.security.bad-deserialization-env.bad-deserialization-env + languages: + - ruby + message: Checks for unsafe deserialization. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of load and object_load can cause remote code execution. Loading user input with MARSHAL or CSV can potentially be dangerous. Use JSON in a secure fashion instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb + subcategory: + - vuln + technology: + - ruby + mode: taint + pattern-sinks: + - pattern-either: + - pattern: | + CSV.load(...) + - pattern: | + Marshal.load(...) + - pattern: | + Marshal.restore(...) + - pattern: | + Oj.object_load(...) + - pattern: | + Oj.load($X) + pattern-sources: + - pattern-either: + - pattern: request.env + severity: ERROR + - fix: Psych.safe_load($...ARGS) + id: ruby.lang.security.bad-deserialization-yaml.bad-deserialization-yaml + languages: + - ruby + message: Unsafe deserialization from YAML. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of load and object_load can cause remote code execution. Loading user input with YAML can potentially be dangerous. Use JSON in a secure fashion instead. However, loading YAML from a static file is not dangerous and should not be flagged. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb + subcategory: + - audit + technology: + - ruby + - yaml + patterns: + - pattern: | + YAML.load($...ARGS) + - pattern-not: | + YAML.load(..., safe: true, ...) + - pattern-not: | + YAML.load("...", ...) + - pattern-not-inside: | + YAML.load(..., File.read(...), ...) + - pattern-not-inside: | + $FILE = File.read(...) + ... + YAML.load(..., $FILE, ...) + - pattern-not-inside: | + $FILENAME = ... + ... + $FILE = File.read($FILENAME, ...) + ... + YAML.load(..., $FILE, ...) + - pattern-not-inside: | + YAML.load(..., $X.$Y(File.read(...)), ...) + - pattern-not-inside: | + YAML.load(..., $X.$Y(File.read(...)).$Z, ...) + - pattern-not-inside: | + $T = $MOD.$MET(File.read(...)) + ... + YAML.load(..., $T, ...) + - pattern-not-inside: | + $T = $MOD.$MET(File.read(...)) + ... + YAML.load(..., $T.$R, ...) + severity: ERROR + - id: ruby.lang.security.bad-deserialization.bad-deserialization + languages: + - ruby + message: Checks for unsafe deserialization. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of load and object_load can cause remote code execution. Loading user input with MARSHAL or CSV can potentially be dangerous. Use JSON in a secure fashion instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb + subcategory: + - vuln + technology: + - ruby + mode: taint + pattern-sinks: + - pattern-either: + - pattern: | + CSV.load(...) + - pattern: | + Marshal.load(...) + - pattern: | + Marshal.restore(...) + - pattern: | + Oj.object_load(...) + - pattern: | + Oj.load($X) + pattern-sources: + - pattern-either: + - pattern: params + - pattern: cookies + severity: ERROR + - id: ruby.lang.security.cookie-serialization.cookie-serialization + languages: + - ruby + message: Checks if code allows cookies to be deserialized using Marshal. If the attacker can craft a valid cookie, this could lead to remote code execution. The hybrid check is just to warn users to migrate to :json for best practice. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_cookie_serialization.rb + - https://robertheaton.com/2013/07/22/how-to-hack-a-rails-app-using-its-secret-token/ + subcategory: + - audit + technology: + - ruby + pattern-either: + - pattern: | + Rails.application.config.action_dispatch.cookies_serializer = :marshal + - pattern: | + Rails.application.config.action_dispatch.cookies_serializer = :hybrid + severity: ERROR + - id: ruby.lang.security.create-with.create-with + languages: + - ruby + message: Checks for strong parameter bypass through usage of create_with. Create_with bypasses strong parameter protection, which could allow attackers to set arbitrary attributes on models. To fix this vulnerability, either remove all create_with calls or use the permit function to specify tags that are allowed to be set. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_create_with.rb + - https://groups.google.com/g/rubyonrails-security/c/M4chq5Sb540/m/CC1Fh0Y_NWwJ + subcategory: + - audit + technology: + - ruby + patterns: + - pattern-not: | + $FUNC.create_with($PARAMSB.permit(...)) + - pattern: | + $FUNC.create_with($PARAMSA) + severity: ERROR + - id: ruby.lang.security.dangerous-exec.dangerous-exec + languages: + - ruby + message: Detected non-static command inside $EXEC. Audit the input to '$EXEC'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://guides.rubyonrails.org/security.html#command-line-injection + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_execute.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern: | + $EXEC(...) + - pattern-not: | + $EXEC("...","...","...",...) + - pattern-not: | + $EXEC(["...","...","...",...],...) + - pattern-not: | + $EXEC({...},"...","...","...",...) + - pattern-not: | + $EXEC({...},["...","...","...",...],...) + - metavariable-regex: + metavariable: $EXEC + regex: ^(system|exec|spawn|Process.exec|Process.spawn|Open3.capture2|Open3.capture2e|Open3.capture3|Open3.popen2|Open3.popen2e|Open3.popen3|IO.popen|Gem::Util.popen|PTY.spawn)$ + pattern-sources: + - patterns: + - pattern: | + def $F(...,$ARG,...) + ... + end + - focus-metavariable: $ARG + - pattern: params + - pattern: cookies + severity: WARNING + - id: ruby.lang.security.dangerous-open.dangerous-open + languages: + - ruby + message: Detected non-static command inside 'open'. Audit the input to 'open'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - ruby + patterns: + - pattern: | + open($CMD,...) + - pattern-not: | + open("...",...) + - metavariable-regex: + metavariable: $CMD + regex: '|' + severity: WARNING + - id: ruby.lang.security.dangerous-open3-pipeline.dangerous-open3-pipeline + languages: + - ruby + message: Detected non-static command inside $PIPE. Audit the input to '$PIPE'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - ruby + patterns: + - pattern: | + Open3.$PIPE(...) + - pattern-not: | + Open3.$PIPE(...,"...",...) + - metavariable-regex: + metavariable: $PIPE + regex: ^(pipeline|pipeline_r|pipeline_rw|pipeline_start|pipeline_w)$ + severity: WARNING + - id: ruby.lang.security.dangerous-subshell.dangerous-subshell + languages: + - ruby + message: Detected non-static command inside `...`. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - ruby + patterns: + - pattern: | + `...#{$VAL}...` + - pattern-not: | + `...#{"..."}...` + - pattern-not-inside: | + $VAL = "..." + ... + severity: WARNING + - id: ruby.lang.security.dangerous-syscall.dangerous-syscall + languages: + - ruby + message: '''syscall'' is essentially unsafe and unportable. The DL (https://apidock.com/ruby/Fiddle) library is preferred for safer and a bit more portable programming.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - ruby + pattern: | + syscall + severity: WARNING + - id: ruby.lang.security.divide-by-zero.divide-by-zero + languages: + - ruby + message: Detected a possible ZeroDivisionError. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-369: Divide By Zero' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_divide_by_zero.rb + subcategory: + - vuln + technology: + - ruby + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: $NUMER / 0 + - pattern: $NUMER + pattern-sources: + - patterns: + - pattern: $VAR + - metavariable-regex: + metavariable: $VAR + regex: ^\d*(?!\.)$ + severity: WARNING + - fix-regex: + regex: =(\s)*true + replacement: = false + id: ruby.lang.security.file-disclosure.file-disclosure + languages: + - ruby + message: Special requests can determine whether a file exists on a filesystem that's outside the Rails app's root directory. To fix this, set config.serve_static_assets = false. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_file_disclosure.rb + - https://groups.google.com/g/rubyonrails-security/c/23fiuwb1NBA/m/MQVM1-5GkPMJ + subcategory: + - audit + technology: + - ruby + pattern: config.serve_static_assets = true + severity: ERROR + - id: ruby.lang.security.filter-skipping.filter-skipping + languages: + - ruby + message: Checks for use of action in Ruby routes. This can cause Rails to render an arbitrary view if an attacker creates an URL accurately. Affects 3.0 applications. Can avoid the vulnerability by providing additional constraints. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-1021: Improper Restriction of Rendered UI Layers or Frames' + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_filter_skipping.rb + - https://groups.google.com/g/rubyonrails-security/c/NCCsca7TEtY + subcategory: + - audit + technology: + - ruby + patterns: + - pattern-not: | + $CALL "=~/.*(/:action.*).*/", $ACTION + - pattern: | + $CALL "=~/.*(/:action.*).*/" + severity: ERROR + - fix-regex: + regex: =\s*false + replacement: = true + id: ruby.lang.security.force-ssl-false.force-ssl-false + languages: + - ruby + message: Checks for configuration setting of force_ssl to false. Force_ssl forces usage of HTTPS, which could lead to network interception of unencrypted application traffic. To fix, set config.force_ssl = true. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_force_ssl.rb + subcategory: + - vuln + technology: + - ruby + pattern: config.force_ssl = false + severity: WARNING + - id: ruby.lang.security.hardcoded-http-auth-in-controller.hardcoded-http-auth-in-controller + languages: + - ruby + message: Detected hardcoded password used in basic authentication in a controller class. Including this password in version control could expose this credential. Consider refactoring to use environment variables or configuration files. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/basic_auth/index.markdown + subcategory: + - audit + technology: + - ruby + - secrets + patterns: + - pattern-inside: | + class $CONTROLLER < ApplicationController + ... + http_basic_authenticate_with ..., :password => "$SECRET", ... + end + - focus-metavariable: $SECRET + severity: WARNING + - id: ruby.lang.security.hardcoded-secret-rsa-passphrase.hardcoded-secret-rsa-passphrase + languages: + - ruby + message: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://cwe.mitre.org/data/definitions/522.html + subcategory: + - vuln + technology: + - ruby + - secrets + patterns: + - pattern-either: + - pattern: OpenSSL::PKey::RSA.new(..., '...') + - pattern: OpenSSL::PKey::RSA.new(...).to_pem(..., '...') + - pattern: OpenSSL::PKey::RSA.new(...).export(..., '...') + - patterns: + - pattern-inside: | + $OPENSSL = OpenSSL::PKey::RSA.new(...) + ... + - pattern-either: + - pattern: | + $OPENSSL.export(...,'...') + - pattern: | + $OPENSSL.to_pem(...,'...') + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $ASSIGN = '...' + ... + - pattern: OpenSSL::PKey::RSA.new(..., $ASSIGN) + - patterns: + - pattern-inside: | + def $METHOD1(...) + ... + $ASSIGN = '...' + ... + end + ... + def $METHOD2(...) + ... + end + - pattern: OpenSSL::PKey::RSA.new(..., $ASSIGN) + - patterns: + - pattern-inside: | + $ASSIGN = '...' + ... + def $METHOD(...) + $OPENSSL = OpenSSL::PKey::RSA.new(...) + ... + end + ... + - pattern-either: + - pattern: $OPENSSL.export(...,$ASSIGN) + - pattern: $OPENSSL.to_pem(...,$ASSIGN) + - patterns: + - pattern-inside: | + def $METHOD1(...) + ... + $OPENSSL = OpenSSL::PKey::RSA.new(...) + ... + $ASSIGN = '...' + ... + end + ... + - pattern-either: + - pattern: $OPENSSL.export(...,$ASSIGN) + - pattern: $OPENSSL.to_pem(...,$ASSIGN) + - patterns: + - pattern-inside: | + def $METHOD1(...) + ... + $ASSIGN = '...' + ... + end + ... + def $METHOD2(...) + ... + $OPENSSL = OpenSSL::PKey::RSA.new(...) + ... + end + ... + - pattern-either: + - pattern: $OPENSSL.export(...,$ASSIGN) + - pattern: $OPENSSL.to_pem(...,$ASSIGN) + severity: WARNING + - id: ruby.lang.security.insufficient-rsa-key-size.insufficient-rsa-key-size + languages: + - ruby + message: The RSA key size $SIZE is insufficent by NIST standards. It is recommended to use a key length of 2048 or higher. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf + subcategory: + - vuln + technology: + - ruby + patterns: + - pattern-either: + - pattern: OpenSSL::PKey::RSA.generate($SIZE,...) + - pattern: OpenSSL::PKey::RSA.new($SIZE, ...) + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $ASSIGN = $SIZE + ... + - pattern-either: + - pattern: OpenSSL::PKey::RSA.new($ASSIGN, ...) + - pattern: OpenSSL::PKey::RSA.generate($ASSIGN, ...) + - patterns: + - pattern-inside: | + def $METHOD1(...) + ... + $ASSIGN = $SIZE + ... + end + ... + - pattern-either: + - pattern: OpenSSL::PKey::RSA.new($ASSIGN, ...) + - pattern: OpenSSL::PKey::RSA.generate($ASSIGN, ...) + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE + severity: WARNING + - id: ruby.lang.security.json-entity-escape.json-entity-escape + languages: + - ruby + message: Checks if HTML escaping is globally disabled for JSON output. This could lead to XSS. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_json_entity_escape.rb + subcategory: + - audit + technology: + - ruby + pattern-either: + - pattern: | + ActiveSupport.escape_html_entities_in_json = false + - pattern: | + config.active_support.escape_html_entities_in_json = false + severity: WARNING + - id: ruby.lang.security.mass-assignment-protection-disabled.mass-assignment-protection-disabled + languages: + - ruby + message: Mass assignment protection disabled for '$MODEL'. This could permit assignment to sensitive model fields without intention. Instead, use 'attr_accessible' for the model or disable mass assigment using 'config.active_record.whitelist_attributes = true'. ':without_protection => true' must be removed for this to take effect. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: HIGH + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/mass_assignment/index.markdown + subcategory: + - audit + technology: + - ruby + pattern: $MODEL.new(params[...], ..., :without_protection => true, ...) + severity: WARNING + - id: ruby.lang.security.md5-used-as-password.md5-used-as-password + languages: + - ruby + message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Instead, use a suitable password hashing function such as bcrypt. You can use the `bcrypt` gem. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html + - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords + - https://github.com/returntocorp/semgrep-rules/issues/1609 + subcategory: + - vuln + technology: + - md5 + mode: taint + pattern-sinks: + - patterns: + - pattern: $FUNCTION(...); + - metavariable-regex: + metavariable: $FUNCTION + regex: (?i)(.*password.*) + pattern-sources: + - pattern: Digest::MD5 + severity: WARNING + - id: ruby.lang.security.missing-csrf-protection.missing-csrf-protection + languages: + - ruby + message: Detected controller which does not enable cross-site request forgery protections using 'protect_from_forgery'. Add 'protect_from_forgery :with => :exception' to your controller class. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/cross-site_request_forgery/index.markdown + subcategory: + - audit + technology: + - ruby + patterns: + - pattern: | + class $CONTROLLER < ActionController::Base + ... + end + - pattern-not: | + class $CONTROLLER < ActionController::Base + ... + protect_from_forgery :with => :exception + end + - pattern-not: | + class $CONTROLLER < ActionController::Base + ... + protect_from_forgery prepend: true, with: :exception + end + severity: ERROR + - id: ruby.lang.security.model-attr-accessible.model-attr-accessible + languages: + - ruby + message: 'Checks for dangerous permitted attributes that can lead to mass assignment vulnerabilities. Query parameters allowed using permit and attr_accessible are checked for allowance of dangerous attributes admin, banned, role, and account_id. Also checks for usages of params.permit!, which allows everything. Fix: don''t allow admin, banned, role, and account_id using permit or attr_accessible.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_model_attr_accessible.rb + subcategory: + - audit + technology: + - ruby + pattern-either: + - pattern: | + ....permit(..., :admin, ...) + - pattern: | + ....permit(..., :role, ...) + - pattern: | + ....permit(..., :banned, ...) + - pattern: | + ....permit(..., :account_id, ...) + - pattern: | + attr_accessible ..., :admin, ... + - pattern: | + attr_accessible ..., :role, ... + - pattern: | + attr_accessible ..., :banned, ... + - pattern: | + attr_accessible ..., :account_id, ... + - pattern: | + params.permit! + severity: ERROR + - id: ruby.lang.security.model-attributes-attr-accessible.model-attributes-attr-accessible + languages: + - ruby + message: Checks for models that do not use attr_accessible. This means there is no limiting of which variables can be manipulated through mass assignment. For newer Rails applications, parameters should be allowlisted using strong parameters. For older Rails versions, they should be allowlisted using strong_attributes. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_model_attributes.rb + subcategory: + - audit + technology: + - rails + patterns: + - pattern-not: | + class $CLASS < $TYPE + ... + attr_accessible :$XXX + ... + end + ... + $CLASS.$FUNC(...) + - pattern: | + class $CLASS < $TYPE + ... + end + ... + $CLASS.$FUNC(...) + - metavariable-pattern: + metavariable: $TYPE + patterns: + - pattern-not-regex: (?i)(Error|Exception) + - focus-metavariable: $CLASS + severity: ERROR + - id: ruby.lang.security.no-eval.ruby-eval + languages: + - ruby + message: Use of eval with user-controllable input detected. This can lead to attackers running arbitrary code. Ensure external data does not reach here, otherwise this is a security vulnerability. Consider other ways to do this without eval. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_evaluation.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $X.eval + - pattern: $X.class_eval + - pattern: $X.instance_eval + - pattern: $X.module_eval + - pattern: $X.eval(...) + - pattern: $X.class_eval(...) + - pattern: $X.instance_eval(...) + - pattern: $X.module_eval(...) + - pattern: eval(...) + - pattern: class_eval(...) + - pattern: module_eval(...) + - pattern: instance_eval(...) + - pattern-not: $M("...",...) + pattern-sources: + - pattern-either: + - pattern: params + - pattern: cookies + - patterns: + - pattern: | + RubyVM::InstructionSequence.compile(...) + - pattern-not: | + RubyVM::InstructionSequence.compile("...") + severity: WARNING + - id: ruby.lang.security.no-send.bad-send + languages: + - ruby + message: Checks for unsafe use of Object#send, try, __send__, and public_send. These only account for unsafe use of a method, not target. This can lead to arbitrary calling of exit, along with arbitrary code execution. Please be sure to sanitize input in order to avoid this. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_send.rb + - https://the.igreque.info/posts/2016/01-object-send-considered-harmful-en.html + subcategory: + - audit + technology: + - ruby + pattern-either: + - pattern: | + $PARAM = params[...] + ... + $RES = $MOD.send($PARAM.$FUNC) + - pattern: | + $PARAM = params[...] + ... + $RES = $MOD.try($PARAM.$FUNC) + - pattern: | + $PARAM = params[...] + ... + $RES = $MOD.__send__($PARAM.$FUNC) + - pattern: | + $PARAM = params[...] + ... + $RES = $MOD.public_send($PARAM.$FUNC) + severity: ERROR + - fix-regex: + regex: VERIFY_NONE + replacement: VERIFY_PEER + id: ruby.lang.security.ssl-mode-no-verify.ssl-mode-no-verify + languages: + - ruby + message: Detected SSL that will accept an unverified connection. This makes the connections susceptible to man-in-the-middle attacks. Use 'OpenSSL::SSL::VERIFY_PEER' instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + subcategory: + - vuln + technology: + - ruby + pattern: OpenSSL::SSL::VERIFY_NONE + severity: WARNING + - id: ruby.lang.security.unprotected-mass-assign.mass-assignment-vuln + languages: + - ruby + message: 'Checks for calls to without_protection during mass assignment (which allows record creation from hash values). This can lead to users bypassing permissions protections. For Rails 4 and higher, mass protection is on by default. Fix: Don''t use :without_protection => true. Instead, configure attr_accessible to control attribute access.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_without_protection.rb + - https://www.acunetix.com/vulnerabilities/web/rails-mass-assignment/ + subcategory: + - audit + technology: + - ruby + patterns: + - pattern-either: + - pattern: | + $MOD.new(params[$CODE]) + - pattern: | + $MOD.new(..., params[$CODE], :without_protection => true, ...) + - pattern-not-inside: | + attr_accessible $VAR + ... + $MOD.new(params[$CODE]) + severity: WARNING + - id: ruby.lang.security.weak-hashes-md5.weak-hashes-md5 + languages: + - ruby + message: Should not use md5 to generate hashes. md5 is proven to be vulnerable through the use of brute-force attacks. Could also result in collisions, leading to potential collision attacks. Use SHA256 or other hashing functions instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-328: Use of Weak Hash' + impact: HIGH + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.ibm.com/support/pages/security-bulletin-vulnerability-md5-signature-and-hash-algorithm-affects-sterling-integrator-and-sterling-file-gateway-cve-2015-7575 + subcategory: + - vuln + technology: + - ruby + pattern-either: + - pattern: Digest::MD5.base64digest $X + - pattern: Digest::MD5.hexdigest $X + - pattern: Digest::MD5.digest $X + - pattern: Digest::MD5.new + - pattern: OpenSSL::Digest::MD5.base64digest $X + - pattern: OpenSSL::Digest::MD5.hexdigest $X + - pattern: OpenSSL::Digest::MD5.digest $X + - pattern: OpenSSL::Digest::MD5.new + severity: WARNING + - id: ruby.lang.security.weak-hashes-sha1.weak-hashes-sha1 + languages: + - ruby + message: Should not use SHA1 to generate hashes. There is a proven SHA1 hash collision by Google, which could lead to vulnerabilities. Use SHA256, SHA3 or other hashing functions instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-328: Use of Weak Hash' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html + - https://shattered.io/ + subcategory: + - vuln + technology: + - ruby + pattern-either: + - pattern: Digest::SHA1.$FUNC + - pattern: OpenSSL::Digest::SHA1.$FUNC + - pattern: OpenSSL::HMAC.$FUNC("sha1",...) + severity: WARNING + - fix: redirect_to $T + id: ruby.rails.correctness.rails-no-render-after-save.rails-no-render-after-save + languages: + - ruby + message: Found a call to `render $T` after calling `$T.save`. Do not call `render` after calling `save` on an ActiveRecord object. Reloading the page will cause the state-changing operation to be repeated which may cause undesirable side effects. Use `redirect_to` instead. + metadata: + category: correctness + references: + - https://guides.rubyonrails.org/getting_started.html#creating-a-new-article + technology: + - rails + - ruby + - activerecord + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + render $T + pattern-sources: + - patterns: + - pattern: $T + - pattern-inside: | + $T.save + ... + severity: WARNING + - id: ruby.rails.performance.ruby-rails-performance-indexes-are-really-beneficial.ruby-rails-performance-indexes-are-beneficial + languages: + - ruby + message: The $COLUMN column appears to be a foreign key. Would it benefit from an index? Having an index can improve performance. + metadata: + category: performance + references: + - https://archive.is/i7SLO + technology: + - rails + patterns: + - pattern-not-inside: | + add_column $TABLE, $COLUMN, $TYPE, ... + ... + add_index $TABLE, $COLUMN, ... + - pattern: | + add_column $TABLE, $COLUMN, $TYPE, ... + - metavariable-regex: + metavariable: $COLUMN + regex: (.*_id$) + - metavariable-regex: + metavariable: $TYPE + regex: :integer|:bigint + severity: INFO + - id: ruby.rails.security.audit.avoid-session-manipulation.avoid-session-manipulation + languages: + - ruby + message: This gets data from session using user inputs. A malicious user may be able to retrieve information from your session that you didn't intend them to. Do not use user input as a session key. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-276: Incorrect Default Permissions' + cwe2021-top25: true + cwe2022-top25: true + help: | + ## Remediation + Session manipulation can occur when an application allows user-input in session keys. Since sessions are typically considered a source of truth (e.g. to check the logged-in user or to match CSRF tokens), allowing an attacker to manipulate the session may lead to unintended behavior. + + ## References + [Session Manipulation](https://brakemanscanner.org/docs/warning_types/session_manipulation/) + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://brakemanscanner.org/docs/warning_types/session_manipulation/ + shortDescription: Allowing an attacker to manipulate the session may lead to unintended behavior. + subcategory: + - vuln + tags: + - security + technology: + - rails + mode: taint + pattern-sinks: + - pattern: session[...] + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + severity: WARNING + - id: ruby.rails.security.audit.avoid-tainted-file-access.avoid-tainted-file-access + languages: + - ruby + message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: Dir.$X(...) + - pattern: File.$X(...) + - pattern: IO.$X(...) + - pattern: Kernel.$X(...) + - pattern: PStore.$X(...) + - pattern: Pathname.$X(...) + - metavariable-pattern: + metavariable: $X + patterns: + - pattern-either: + - pattern: chdir + - pattern: chroot + - pattern: delete + - pattern: entries + - pattern: foreach + - pattern: glob + - pattern: install + - pattern: lchmod + - pattern: lchown + - pattern: link + - pattern: load + - pattern: load_file + - pattern: makedirs + - pattern: move + - pattern: new + - pattern: open + - pattern: read + - pattern: readlines + - pattern: rename + - pattern: rmdir + - pattern: safe_unlink + - pattern: symlink + - pattern: syscopy + - pattern: sysopen + - pattern: truncate + - pattern: unlink + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + severity: WARNING + - id: ruby.rails.security.audit.avoid-tainted-ftp-call.avoid-tainted-ftp-call + languages: + - ruby + message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sinks: + - pattern-either: + - pattern: Net::FTP.$X(...) + - patterns: + - pattern-inside: | + $FTP = Net::FTP.$OPEN(...) + ... + $FTP.$METHOD(...) + - pattern: $FTP.$METHOD(...) + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + severity: WARNING + - id: ruby.rails.security.audit.avoid-tainted-http-request.avoid-tainted-http-request + languages: + - ruby + message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sinks: + - pattern-either: + - patterns: + - pattern: Net::HTTP::$METHOD.new(...) + - metavariable-pattern: + metavariable: $METHOD + patterns: + - pattern-either: + - pattern: Copy + - pattern: Delete + - pattern: Get + - pattern: Head + - pattern: Lock + - pattern: Mkcol + - pattern: Move + - pattern: Options + - pattern: Patch + - pattern: Post + - pattern: Propfind + - pattern: Proppatch + - pattern: Put + - pattern: Trace + - pattern: Unlock + - patterns: + - pattern: Net::HTTP.$X(...) + - metavariable-pattern: + metavariable: $X + patterns: + - pattern-either: + - pattern: get + - pattern: get2 + - pattern: head + - pattern: head2 + - pattern: options + - pattern: patch + - pattern: post + - pattern: post2 + - pattern: post_form + - pattern: put + - pattern: request + - pattern: request_get + - pattern: request_head + - pattern: request_post + - pattern: send_request + - pattern: trace + - pattern: get_print + - pattern: get_response + - pattern: start + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + severity: WARNING + - id: ruby.rails.security.audit.avoid-tainted-shell-call.avoid-tainted-shell-call + languages: + - ruby + message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: Kernel.$X(...) + - patterns: + - pattern-either: + - pattern: Shell.$X(...) + - patterns: + - pattern-inside: | + $SHELL = Shell.$ANY(...) + ... + $SHELL.$X(...) + - pattern: $SHELL.$X(...) + - metavariable-pattern: + metavariable: $X + patterns: + - pattern-either: + - pattern: cat + - pattern: chdir + - pattern: chroot + - pattern: delete + - pattern: entries + - pattern: exec + - pattern: foreach + - pattern: glob + - pattern: install + - pattern: lchmod + - pattern: lchown + - pattern: link + - pattern: load + - pattern: load_file + - pattern: makedirs + - pattern: move + - pattern: new + - pattern: open + - pattern: read + - pattern: readlines + - pattern: rename + - pattern: rmdir + - pattern: safe_unlink + - pattern: symlink + - pattern: syscopy + - pattern: sysopen + - pattern: system + - pattern: truncate + - pattern: unlink + pattern-sources: + - pattern-either: + - pattern: params[...] + - pattern: cookies + - pattern: request.env + severity: ERROR + - id: ruby.rails.security.audit.detailed-exceptions.detailed-exceptions + languages: + - ruby + message: Found that the setting for providing detailed exception reports in Rails is set to true. This can lead to information exposure, where sensitive system or internal information is displayed to the end user. Instead, turn this setting off. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_detailed_exceptions.rb + subcategory: + - audit + technology: + - rails + patterns: + - pattern-either: + - patterns: + - pattern: | + config.consider_all_requests_local = true + - patterns: + - pattern-inside: | + class $CONTROLLER < ApplicationController + ... + end + - pattern: | + def show_detailed_exceptions? (...) + ... + return $RETURN + end + - metavariable-pattern: + metavariable: $RETURN + patterns: + - pattern-not: | + false + severity: WARNING + - id: ruby.rails.security.audit.rails-skip-forgery-protection.rails-skip-forgery-protection + languages: + - ruby + message: This call turns off CSRF protection allowing CSRF attacks against the application + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html#method-i-skip_forgery_protection + subcategory: + - audit + technology: + - rails + pattern: skip_forgery_protection + severity: WARNING + - id: ruby.rails.security.audit.sqli.ruby-pg-sqli.ruby-pg-sqli + languages: + - ruby + message: 'Detected string concatenation with a non-literal variable in a pg Ruby SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized queries like so: `conn.exec_params(''SELECT $1 AS a, $2 AS b, $3 AS c'', [1, 2, nil])` And you can use prepared statements with `exec_prepared`.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://www.rubydoc.info/gems/pg/PG/Connection + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-propagators: + - from: $Y + pattern: $X << $Y + to: $X + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $CON = PG.connect(...) + ... + - pattern-inside: | + $CON = PG::Connection.open(...) + ... + - pattern-inside: | + $CON = PG::Connection.new(...) + ... + - pattern-either: + - pattern: | + $CON.$METHOD($X,...) + - pattern: | + $CON.$METHOD $X, ... + - focus-metavariable: $X + - metavariable-regex: + metavariable: $METHOD + regex: ^(exec|exec_params)$ + pattern-sources: + - pattern-either: + - pattern: | + params + - pattern: | + cookies + severity: WARNING + - id: ruby.rails.security.audit.xss.avoid-content-tag.avoid-content-tag + languages: + - ruby + message: '''content_tag()'' bypasses HTML escaping for some portion of the content. If external data can reach here, this exposes your application to cross-site scripting (XSS) attacks. Ensure no external data reaches here. If you must do this, create your HTML manually and use ''html_safe''. Ensure no external data enters the HTML-safe string!' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/template_injection/index.markdown + - https://www.netsparker.com/blog/web-security/preventing-xss-ruby-on-rails-web-applications/ + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_content_tag.rb + subcategory: + - audit + technology: + - rails + pattern: content_tag(...) + severity: WARNING + - id: ruby.rails.security.audit.xss.avoid-default-routes.avoid-default-routes + languages: + - ruby + message: Default routes are enabled in this routes file. This means any public method on a controller can be called as an action. It is very easy to accidentally expose a method you didn't mean to. Instead, remove this line and explicitly include all routes you intend external users to follow. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-276: Incorrect Default Permissions' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/default_routes/index.markdown + subcategory: + - audit + technology: + - rails + paths: + include: + - '*routes.rb' + patterns: + - pattern-either: + - pattern: map.connect ":controller/:action/:id" + - pattern: match ':controller(/:action(/:id(.:format)))' + severity: WARNING + - id: ruby.rails.security.audit.xss.avoid-html-safe.avoid-html-safe + languages: + - ruby + message: '''html_safe()'' does not make the supplied string safe. ''html_safe()'' bypasses HTML escaping. If external data can reach here, this exposes your application to cross-site scripting (XSS) attacks. Ensure no external data reaches here.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/cross_site_scripting/index.markdown + - https://www.netsparker.com/blog/web-security/preventing-xss-ruby-on-rails-web-applications/ + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_cross_site_scripting.rb + subcategory: + - audit + technology: + - rails + pattern-either: + - pattern: $STR.html_safe + - pattern: $STR.html_safe.$MORE + severity: WARNING + - id: ruby.rails.security.audit.xss.avoid-link-to.avoid-link-to + languages: + - ruby + message: This code includes user input in `link_to`. In Rails 2.x, the body of `link_to` is not escaped. This means that user input which reaches the body will be executed when the HTML is rendered. Even in other versions, values starting with `javascript:` or `data:` are not escaped. It is better to create and use a safer function which checks the body argument. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://brakemanscanner.org/docs/warning_types/link_to/ + - https://brakemanscanner.org/docs/warning_types/link_to_href/ + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_link_to.rb + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sanitizers: + - patterns: + - pattern: | + "...#{...}..." + - pattern-not: | + "#{...}..." + pattern-sinks: + - pattern: link_to(...) + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + - pattern-either: + - pattern: $MODEL.url(...) + - pattern: $MODEL.uri(...) + - pattern: $MODEL.link(...) + - pattern: $MODEL.page(...) + - pattern: $MODEL.site(...) + severity: WARNING + - id: ruby.rails.security.audit.xss.avoid-raw.avoid-raw + languages: + - ruby + message: '''raw()'' bypasses HTML escaping. If external data can reach here, this exposes your application to cross-site scripting (XSS) attacks. If you must do this, construct individual strings and mark them as safe for HTML rendering with `html_safe()`.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://api.rubyonrails.org/classes/ActionView/Helpers/OutputSafetyHelper.html#method-i-raw + - https://www.netsparker.com/blog/web-security/preventing-xss-ruby-on-rails-web-applications/ + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_cross_site_scripting.rb + subcategory: + - audit + technology: + - rails + pattern: raw(...) + severity: WARNING + - id: ruby.rails.security.audit.xss.avoid-redirect.avoid-redirect + languages: + - ruby + message: When a redirect uses user input, a malicious user can spoof a website under a trusted URL or access restricted parts of a site. When using user-supplied values, sanitize the value before using it for the redirect. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://brakemanscanner.org/docs/warning_types/redirect/ + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sanitizers: + - pattern: params.merge(:only_path => true) + - pattern: params.merge(:host => ...) + pattern-sinks: + - pattern: redirect_to(...) + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + - patterns: + - pattern: $MODEL.$X(...) + - pattern-not: $MODEL.$X("...") + - metavariable-pattern: + metavariable: $X + pattern-either: + - pattern: all + - pattern: create + - pattern: create! + - pattern: find + - pattern: find_by_sql + - pattern: first + - pattern: last + - pattern: new + - pattern: from + - pattern: group + - pattern: having + - pattern: joins + - pattern: lock + - pattern: order + - pattern: reorder + - pattern: select + - pattern: where + - pattern: find_by + - pattern: find_by! + - pattern: take + severity: WARNING + - id: ruby.rails.security.audit.xss.avoid-render-dynamic-path.avoid-render-dynamic-path + languages: + - ruby + message: Avoid rendering user input. It may be possible for a malicious user to input a path that lets them access a template they shouldn't. To prevent this, check dynamic template paths against a predefined allowlist to make sure it's an allowed template. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://brakemanscanner.org/docs/warning_types/dynamic_render_paths/ + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: render($X => $INPUT, ...) + - pattern: $INPUT + - metavariable-pattern: + metavariable: $X + pattern-either: + - pattern: action + - pattern: template + - pattern: partial + - pattern: file + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + severity: WARNING + - id: ruby.rails.security.audit.xss.avoid-render-inline.avoid-render-inline + languages: + - ruby + message: '''render inline: ...'' renders an entire ERB template inline and is dangerous. If external data can reach here, this exposes your application to server-side template injection (SSTI) or cross-site scripting (XSS) attacks. Instead, consider using a partial or another safe rendering method.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#inline-renders---even-worse-than-xss + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render_inline.rb + subcategory: + - audit + technology: + - rails + pattern: 'render inline: ...' + severity: WARNING + - fix-regex: + regex: 'text:' + replacement: 'plain:' + id: ruby.rails.security.audit.xss.avoid-render-text.avoid-render-text + languages: + - ruby + message: '''render text: ...'' actually sets the content-type to ''text/html''. If external data can reach here, this exposes your application to cross-site scripting (XSS) attacks. Instead, use ''render plain: ...'' to render non-HTML text.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#inline-renders---even-worse-than-xss + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render_inline.rb + subcategory: + - audit + technology: + - rails + pattern: 'render text: ...' + severity: WARNING + - id: ruby.rails.security.audit.xss.manual-template-creation.manual-template-creation + languages: + - ruby + message: Detected manual creation of an ERB template. Manual creation of templates may expose your application to server-side template injection (SSTI) or cross-site scripting (XSS) attacks if user input is used to create the template. Instead, create a '.erb' template file and use 'render'. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/template_injection/index.markdown + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_template_injection.rb + subcategory: + - audit + technology: + - rails + pattern: ERB.new(...) + severity: WARNING + - id: ruby.rails.security.audit.xss.templates.alias-for-html-safe.alias-for-html-safe + languages: + - generic + message: The syntax `<%== ... %>` is an alias for `html_safe`. This means the content inside these tags will be rendered as raw HTML. This may expose your application to cross-site scripting. If you need raw HTML, prefer using the more explicit `html_safe` and be sure to correctly sanitize variables using a library such as DOMPurify. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://medium.com/sumone-technical-blog/a-pretty-way-to-unescape-html-in-a-ruby-on-rails-application-efc22b850027 + - https://stackoverflow.com/questions/4251284/raw-vs-html-safe-vs-h-to-unescape-html#:~:text=== + subcategory: + - audit + technology: + - rails + paths: + include: + - '*.erb' + patterns: + - pattern: <%== ... %> + - pattern-not: <%== $...A.to_json %> + severity: WARNING + - id: ruby.rails.security.audit.xss.templates.avoid-content-tag.avoid-content-tag + languages: + - generic + message: '''content_tag'' exhibits unintuitive escaping behavior and may accidentally expose your application to cross-site scripting. If using Rails 2, only attribute values are escaped. If using Rails 3, content and attribute values are escaped. Tag and attribute names are never escaped. Because of this, it is recommended to use ''html_safe'' if you must render raw HTML data.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://brakemanscanner.org/docs/warning_types/content_tag/ + source-rule-url: https://brakemanscanner.org/docs/warning_types/content_tag/ + subcategory: + - audit + technology: + - rails + paths: + include: + - '*.erb' + patterns: + - pattern-inside: <%= ... %> + - pattern: content_tag + severity: WARNING + - id: ruby.rails.security.audit.xss.templates.avoid-html-safe.avoid-html-safe + languages: + - generic + message: '''html_safe'' renders raw HTML. This means that normal HTML escaping is bypassed. If user data can be controlled here, this exposes your application to cross-site scripting (XSS). If you need to do this, be sure to correctly sanitize the data using a library such as DOMPurify.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://stackoverflow.com/questions/4251284/raw-vs-html-safe-vs-h-to-unescape-html#:~:text=== + - https://medium.com/sumone-technical-blog/a-pretty-way-to-unescape-html-in-a-ruby-on-rails-application-efc22b850027 + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_cross_site_scripting.rb + subcategory: + - audit + technology: + - rails + paths: + include: + - '*.erb' + patterns: + - pattern-inside: <%= ... %> + - pattern: $SOMETHING.html_safe + severity: WARNING + - id: ruby.rails.security.audit.xss.templates.avoid-raw.avoid-raw + languages: + - generic + message: '''raw'' renders raw HTML, as the name implies. This means that normal HTML escaping is bypassed. If user data can be controlled here, this exposes your application to cross-site scripting (XSS). If you need to do this, be sure to correctly sanitize the data using a library such as DOMPurify.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://stackoverflow.com/questions/4251284/raw-vs-html-safe-vs-h-to-unescape-html#:~:text=== + - https://medium.com/sumone-technical-blog/a-pretty-way-to-unescape-html-in-a-ruby-on-rails-application-efc22b850027 + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_cross_site_scripting.rb + subcategory: + - audit + technology: + - rails + paths: + include: + - '*.erb' + patterns: + - pattern-inside: <%= ... %> + - pattern: raw + severity: WARNING + - id: ruby.rails.security.audit.xss.templates.dangerous-link-to.dangerous-link-to + languages: + - generic + message: 'Detected a template variable used in ''link_to''. This will generate dynamic data in the ''href'' attribute. This allows a malicious actor to input the ''javascript:'' URI and is subject to cross- site scripting (XSS) attacks. If using a relative URL, start with a literal forward slash and concatenate the URL, like this: ''link_to "Here", "/"+@link''. You may also consider setting the Content Security Policy (CSP) header.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Ruby_on_Rails_Cheat_Sheet.html#cross-site-scripting-xss + - https://brakemanscanner.org/docs/warning_types/link_to_href/ + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_link_to.rb + subcategory: + - audit + technology: + - rails + paths: + include: + - '*.erb' + patterns: + - pattern-inside: <%= ... %> + - pattern-not-inside: link_to ... "/" + ... @$VAR + - pattern-not-inside: link_to ... '/' + ... @$VAR + - pattern: link_to ... @$VAR + severity: WARNING + - fix-regex: + regex: <%=(.*?)%> + replacement: '"<%=\1%>"' + id: ruby.rails.security.audit.xss.templates.unquoted-attribute.unquoted-attribute + languages: + - generic + message: 'Detected a unquoted template variable as an attribute. If unquoted, a malicious actor could inject custom JavaScript handlers. To fix this, add quotes around the template expression, like this: "<%= expr %>".' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#unquoted-attributes + - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss + subcategory: + - audit + technology: + - rails + paths: + include: + - '*.erb' + patterns: + - pattern-inside: <$TAG ...> + - pattern-not-inside: ="..." + - pattern-not-inside: ="<%= ... %>" + - pattern-not-inside: ='...' + - pattern-not-inside: ='<%= ... %>' + - pattern: <%= ... %> + severity: WARNING + - id: ruby.rails.security.audit.xss.templates.var-in-href.var-in-href + languages: + - generic + message: 'Detected a template variable used in an anchor tag with the ''href'' attribute. This allows a malicious actor to input the ''javascript:'' URI and is subject to cross- site scripting (XSS) attacks. If using a relative URL, start with a literal forward slash and concatenate the URL, like this: href=''/<%= link =>''. You may also consider setting the Content Security Policy (CSP) header.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss#:~:text=javascript:%20URI + - https://github.com/pugjs/pug/issues/2952 + subcategory: + - audit + technology: + - rails + paths: + include: + - '*.erb' + pattern-either: + - pattern: + - pattern: + severity: WARNING + - id: ruby.rails.security.audit.xss.templates.var-in-script-tag.var-in-script-tag + languages: + - generic + message: Detected a template variable used in a script tag. Although template variables are HTML escaped, HTML escaping does not always prevent cross-site scripting (XSS) attacks when used directly in JavaScript. If you need to do this, use `escape_javascript` or its alias, `j`. However, this will not protect from XSS in all circumstances; see the references for more information. Consider placing this value in the HTML portion (outside of a script tag). + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://www.netsparker.com/blog/web-security/preventing-xss-ruby-on-rails-web-applications/ + - https://www.youtube.com/watch?v=yYTkLUEdIyE + - https://www.veracode.com/blog/secure-development/nodejs-template-engines-why-default-encoders-are-not-enough + subcategory: + - audit + technology: + - rails + paths: + include: + - '*.erb' + patterns: + - pattern-inside: + - pattern-not: <%= j ... > + - pattern-not: <%= escape_javascript ... > + - pattern: <%= ... > + severity: WARNING + - id: ruby.rails.security.audit.xxe.libxml-backend.libxml-backend + languages: + - ruby + message: This application is using LibXML as the XML backend. LibXML can be vulnerable to XML External Entities (XXE) vulnerabilities. Use the built-in Rails XML parser, REXML, instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://www.stackhawk.com/blog/rails-xml-external-entities-xxe-guide-examples-and-prevention/ + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - rails + - libxml + pattern: ActiveSupport::XmlMini.backend = "LibXML" + severity: WARNING + - id: ruby.rails.security.audit.xxe.xml-external-entities-enabled.xml-external-entities-enabled + languages: + - ruby + message: This application is explicitly enabling external entities enabling an attacker to inject malicious XML to exploit an XML External Entities (XXE) vulnerability. This could let the attacker cause a denial-of-service by forcing the parser to parse large files, or at worst, let the attacker download sensitive files or user data. Use the built-in Rails XML parser, REXML, instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://www.stackhawk.com/blog/rails-xml-external-entities-xxe-guide-examples-and-prevention/ + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - rails + - libxml + patterns: + - pattern-either: + - pattern-inside: | + LibXML::XML.class_eval do + ... + end + - pattern-inside: | + XML.class_eval do + ... + end + - pattern: XML.default_substitute_entities = true + severity: ERROR + - id: ruby.rails.security.brakeman.check-before-filter.check-before-filter + languages: + - ruby + message: 'Disabled-by-default Rails controller checks make it much easier to introduce access control mistakes. Prefer an allowlist approach with `:only => [...]` rather than `except: => [...]`' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-284: Improper Access Control' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_skip_before_filter.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: search + patterns: + - pattern-either: + - pattern: | + skip_filter ..., :except => $ARGS + - pattern: | + skip_before_filter ..., :except => $ARGS + - pattern: | + skip_before_action ..., :except => $ARGS + severity: ERROR + - id: ruby.rails.security.brakeman.check-cookie-store-session-security-attributes.check-cookie-store-session-security-attributes + languages: + - ruby + message: Found a Rails `cookie_store` session configuration setting the `$KEY` attribute to `false`. If using a cookie-based session store, the HttpOnly and Secure flags should be set. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_session_settings.rb + subcategory: + - audit + technology: + - ruby + - rails + patterns: + - pattern-either: + - patterns: + - pattern: | + :$KEY => false + - pattern-inside: | + ActionController::Base.session = {...} + - pattern: | + $MODULE::Application.config.session_store :cookie_store, ..., :$KEY => false, ... + - pattern: | + $CLASS.application.config.session_store :cookie_store, ..., $KEY: false, ... + - metavariable-regex: + metavariable: $KEY + regex: ^(session_)?(http_?only|secure)$ + severity: WARNING + - id: ruby.rails.security.brakeman.check-dynamic-render-local-file-include.check-dynamic-render-local-file-include + languages: + - generic + message: Found request parameters in a call to `render` in a dynamic context. This can allow end users to request arbitrary local files which may result in leaking sensitive information persisted on disk. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion + - https://github.com/presidentbeef/brakeman/blob/f74cb53ead47f0af821d98b5b41e16d63100c240/test/apps/rails2/app/views/home/test_render.html.erb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: search + paths: + include: + - '*.erb' + patterns: + - pattern: | + params[...] + - pattern-inside: | + render :file => ... + severity: WARNING + - id: ruby.rails.security.brakeman.check-http-verb-confusion.check-http-verb-confusion + languages: + - ruby + message: Found an improperly constructed control flow block with `request.get?`. Rails will route HEAD requests as GET requests but they will fail the `request.get?` check, potentially causing unexpected behavior unless an `elif` condition is used. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-650: Trusting HTTP Permission Methods on the Server Side' + impact: MEDIUM + likelihood: HIGH + owasp: + - A04:2021 - Insecure Design + references: + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails6/app/controllers/accounts_controller.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_verb_confusion.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: search + patterns: + - pattern: | + if request.get? + ... + else + ... + end + - pattern-not-inside: | + if ... + elsif ... + ... + end + severity: ERROR + - id: ruby.rails.security.brakeman.check-permit-attributes-high.check-permit-attributes-high + languages: + - ruby + message: Calling `permit` on security-critical properties like `$ATTRIBUTE` may leave your application vulnerable to mass assignment. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_permit_attributes.rb + subcategory: + - audit + technology: + - ruby + - rails + patterns: + - pattern: $P.permit($ATTRIBUTE) + - metavariable-regex: + metavariable: $ATTRIBUTE + regex: .*(admin|account_id).* + severity: ERROR + - id: ruby.rails.security.brakeman.check-permit-attributes-medium.check-permit-attributes-medium + languages: + - ruby + message: Calling `permit` on security-critical properties like `$ATTRIBUTE` may leave your application vulnerable to mass assignment. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' + impact: MEDIUM + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_permit_attributes.rb + subcategory: + - audit + technology: + - ruby + - rails + patterns: + - pattern: $P.permit($ATTRIBUTE) + - metavariable-regex: + metavariable: $ATTRIBUTE + regex: .*(role|banned).* + severity: WARNING + - id: ruby.rails.security.brakeman.check-rails-secret-yaml.check-rails-secret-yaml + languages: + - yaml + message: $VALUE Found a string literal assignment to a production Rails session secret in `secrets.yaml`. Do not commit secret values to source control! Any user in possession of this value may falsify arbitrary session data in your application. Read this value from an environment variable, KMS, or file on disk outside of source control. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-540: Inclusion of Sensitive Information in Source Code' + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails4/config/secrets.yml + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_session_settings.rb + subcategory: + - audit + technology: + - ruby + - rails + paths: + include: + - '*secrets.*.yml' + - '*secrets.*.yaml' + patterns: + - pattern: | + secret_key_base: $VALUE + - metavariable-pattern: + language: generic + metavariable: $VALUE + patterns: + - pattern-not: | + <%= ... %> + - pattern-inside: | + production: + ... + severity: WARNING + - id: ruby.rails.security.brakeman.check-rails-session-secret-handling.check-rails-session-secret-handling + languages: + - ruby + message: Found a string literal assignment to a Rails session secret `$KEY`. Do not commit secret values to source control! Any user in possession of this value may falsify arbitrary session data in your application. Read this value from an environment variable, KMS, or file on disk outside of source control. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-540: Inclusion of Sensitive Information in Source Code' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails4_with_engines/config/initializers/secret_token.rb + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3/config/initializers/secret_token.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_session_settings.rb + subcategory: + - vuln + technology: + - ruby + - rails + patterns: + - pattern-either: + - patterns: + - pattern: | + :$KEY => "$LITERAL" + - pattern-inside: | + ActionController::Base.session = {...} + - pattern: | + $RAILS::Application.config.$KEY = "$LITERAL" + - pattern: | + Rails.application.config.$KEY = "$LITERAL" + - metavariable-regex: + metavariable: $KEY + regex: ^secret(_(token|key_base))?$ + severity: WARNING + - id: ruby.rails.security.brakeman.check-redirect-to.check-redirect-to + languages: + - ruby + message: Found potentially unsafe handling of redirect behavior $X. Do not pass `params` to `redirect_to` without the `:only_path => true` hash value. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_redirect.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - patterns: + - pattern: | + $F(...) + - metavariable-pattern: + metavariable: $F + patterns: + - pattern-not-regex: (params|url_for|cookies|request.env|permit|redirect_to) + - pattern: | + params.merge! :only_path => true + ... + - pattern: | + params.slice(...) + ... + - pattern: | + redirect_to [...] + - patterns: + - pattern: | + $MODEL. ... .$M(...) + ... + - metavariable-regex: + metavariable: $MODEL + regex: '[A-Z]\w+' + - metavariable-regex: + metavariable: $M + regex: (all|create|find|find_by|find_by_sql|first|last|new|from|group|having|joins|lock|order|reorder|select|where|take) + - patterns: + - pattern: | + params.$UNSAFE_HASH.merge(...,:only_path => true,...) + ... + - metavariable-regex: + metavariable: $UNSAFE_HASH + regex: to_unsafe_h(ash)? + - patterns: + - pattern: params.permit(...,$X,...) + - metavariable-pattern: + metavariable: $X + patterns: + - pattern-not-regex: (host|port|(sub)?domain) + pattern-sinks: + - patterns: + - pattern: $X + - pattern-inside: | + redirect_to $X, ... + - pattern-not-regex: params\.\w+(? false,...) + severity: WARNING + - id: ruby.rails.security.brakeman.check-regex-dos.check-regex-dos + languages: + - ruby + message: Found a potentially user-controllable argument in the construction of a regular expressions. This may result in excessive resource consumption when applied to certain inputs, or when the user is allowed to control the match target. Avoid allowing users to specify regular expressions processed by the server. If you must support user-controllable input in a regular expression, use an allow-list to restrict the expressions users may supply to limit catastrophic backtracking. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1333: Inefficient Regular Expression Complexity' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_regex_dos.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: $Y + - pattern-inside: | + /...#{...}.../ + - patterns: + - pattern: $Y + - pattern-inside: | + Regexp.new(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + - patterns: + - pattern: $Y + - pattern-either: + - pattern-inside: | + $RECORD.read_attribute($Y) + - pattern-inside: | + $RECORD[$Y] + - metavariable-regex: + metavariable: $RECORD + regex: '[A-Z][a-z]+' + severity: ERROR + - id: ruby.rails.security.brakeman.check-render-local-file-include.check-render-local-file-include + languages: + - ruby + message: Found request parameters in a call to `render`. This can allow end users to request arbitrary local files which may result in leaking sensitive information persisted on disk. Where possible, avoid letting users specify template paths for `render`. If you must allow user input, use an allow-list of known templates or normalize the user-supplied value with `File.basename(...)`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion + - https://github.com/presidentbeef/brakeman/blob/f74cb53/test/apps/rails2/app/controllers/home_controller.rb#L48-L60 + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render.rb + subcategory: + - vuln + technology: + - ruby + - rails + vulnerability_class: + - Path Traversal + mode: taint + pattern-sanitizers: + - patterns: + - pattern: $MAP[...] + - metavariable-pattern: + metavariable: $MAP + patterns: + - pattern-not-regex: params + - pattern: File.basename(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + render ..., file: $X + - pattern: | + render ..., inline: $X + - pattern: | + render ..., template: $X + - pattern: | + render ..., action: $X + - pattern: | + render $X, ... + - focus-metavariable: $X + pattern-sources: + - patterns: + - pattern: params[...] + severity: WARNING + - id: ruby.rails.security.brakeman.check-reverse-tabnabbing.check-reverse-tabnabbing + languages: + - generic + message: Setting an anchor target of `_blank` without the `noopener` or `noreferrer` attribute allows reverse tabnabbing on Internet Explorer, Opera, and Android Webview. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1022: Use of Web Link to Untrusted Target with window.opener Access' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#browser_compatibility + - https://github.com/presidentbeef/brakeman/blob/3f5d5d5/test/apps/rails5/app/views/users/show.html.erb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_reverse_tabnabbing.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: search + paths: + include: + - '*.erb' + patterns: + - pattern: | + _blank + - pattern-inside: | + target: ... + - pattern-not-inside: | + <%= ... rel: 'noopener noreferrer' ...%> + - pattern-either: + - patterns: + - pattern-inside: | + <%= $...INLINERUBYDO do -%> + ... + <% end %> + - metavariable-pattern: + language: ruby + metavariable: $...INLINERUBYDO + patterns: + - pattern: | + link_to ... + - pattern-not: | + link_to "...", "...", ... + - patterns: + - pattern-not-inside: | + <%= ... do - %> + - pattern-inside: | + <%= $...INLINERUBY %> + - metavariable-pattern: + language: ruby + metavariable: $...INLINERUBY + patterns: + - pattern: | + link_to ... + - pattern-not: | + link_to '...', '...', ... + - pattern-not: | + link_to '...', target: ... + severity: WARNING + - id: ruby.rails.security.brakeman.check-secrets.check-secrets + languages: + - ruby + message: Found a Brakeman-style secret - a variable with the name password/secret/api_key/rest_auth_site_key and a non-empty string literal value. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + - https://github.com/presidentbeef/brakeman/blob/3f5d5d5f00864cdf7769c50f5bd26f1769a4ba75/test/apps/rails3.1/app/controllers/users_controller.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_secrets.rb + subcategory: + - vuln + technology: + - ruby + - rails + patterns: + - pattern: $VAR = "$VALUE" + - metavariable-regex: + metavariable: $VAR + regex: (?i)password|secret|(rest_auth_site|api)_key$ + - metavariable-regex: + metavariable: $VALUE + regex: .+ + severity: WARNING + - id: ruby.rails.security.brakeman.check-send-file.check-send-file + languages: + - ruby + message: Allowing user input to `send_file` allows a malicious user to potentially read arbitrary files from the server. Avoid accepting user input in `send_file` or normalize with `File.basename(...)` + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-73: External Control of File Name or Path' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A04:2021 - Insecure Design + references: + - https://owasp.org/www-community/attacks/Path_Traversal + - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_send_file.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern: | + send_file ... + pattern-sources: + - pattern-either: + - pattern: | + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: ERROR + - id: ruby.rails.security.brakeman.check-sql.check-sql + languages: + - ruby + message: Found potential SQL injection due to unsafe SQL query construction via $X. Where possible, prefer parameterized queries. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/SQL_Injection + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/models/product.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_sql.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - patterns: + - pattern: $X + - pattern-either: + - pattern-inside: | + :$KEY => $X + - pattern-inside: | + ["...",$X,...] + - pattern: | + params[...].to_i + - pattern: | + params[...].to_f + - patterns: + - pattern: | + params[...] ? $A : $B + - metavariable-pattern: + metavariable: $A + patterns: + - pattern-not: | + params[...] + - metavariable-pattern: + metavariable: $B + patterns: + - pattern-not: | + params[...] + pattern-sinks: + - patterns: + - pattern: $X + - pattern-not-inside: | + $P.where("...",...) + - pattern-not-inside: | + $P.where(:$KEY => $VAL,...) + - pattern-either: + - pattern-inside: | + $P.$M(...) + - pattern-inside: | + $P.$M("...",...) + - pattern-inside: | + class $P < ActiveRecord::Base + ... + end + - metavariable-regex: + metavariable: $M + regex: (where|find|first|last|select|minimum|maximum|calculate|sum|average) + pattern-sources: + - pattern-either: + - pattern: | + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: ERROR + - id: ruby.rails.security.brakeman.check-unsafe-reflection-methods.check-unsafe-reflection-methods + languages: + - ruby + message: Found user-controllable input to a reflection method. This may allow a user to alter program behavior and potentially execute arbitrary instructions in the context of the process. Do not provide arbitrary user input to `tap`, `method`, or `to_proc` + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails6/app/controllers/groups_controller.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unsafe_reflection_methods.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern: $X + - pattern-either: + - pattern-inside: | + $X. ... .to_proc + - patterns: + - pattern-inside: | + $Y.method($Z) + - focus-metavariable: $Z + - patterns: + - pattern-inside: | + $Y.tap($Z) + - focus-metavariable: $Z + - patterns: + - pattern-inside: | + $Y.tap{ |$ANY| $Z } + - focus-metavariable: $Z + pattern-sources: + - pattern-either: + - pattern: | + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: ERROR + - id: ruby.rails.security.brakeman.check-unsafe-reflection.check-unsafe-reflection + languages: + - ruby + message: Found user-controllable input to Ruby reflection functionality. This allows a remote user to influence runtime behavior, up to and including arbitrary remote code execution. Do not provide user-controllable input to reflection functionality. Do not call symbol conversion on user-controllable input. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails2/app/controllers/application_controller.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unsafe_reflection.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern: $X + - pattern-either: + - pattern-inside: | + $X.constantize + - pattern-inside: | + $X. ... .safe_constantize + - pattern-inside: | + const_get(...) + - pattern-inside: | + qualified_const_get(...) + pattern-sources: + - pattern-either: + - pattern: | + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: ERROR + - id: ruby.rails.security.brakeman.check-unscoped-find.check-unscoped-find + languages: + - ruby + message: Found an unscoped `find(...)` with user-controllable input. If the ActiveRecord model being searched against is sensitive, this may lead to Insecure Direct Object Reference (IDOR) behavior and allow users to read arbitrary records. Scope the find to the current user, e.g. `current_user.accounts.find(params[:id])`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-639: Authorization Bypass Through User-Controlled Key' + impact: HIGH + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://brakemanscanner.org/docs/warning_types/unscoped_find/ + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/controllers/users_controller.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unscoped_find.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $MODEL.find(...) + - pattern: $MODEL.find_by_id(...) + - pattern: $MODEL.find_by_id!(...) + - metavariable-regex: + metavariable: $MODEL + regex: '[A-Z]\S+' + pattern-sources: + - pattern-either: + - pattern: | + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: WARNING + - id: ruby.rails.security.brakeman.check-validation-regex.check-validation-regex + languages: + - ruby + message: $V Found an incorrectly-bounded regex passed to `validates_format_of` or `validate ... format => ...`. Ruby regex behavior is multiline by default and lines should be terminated by `\A` for beginning of line and `\Z` for end of line, respectively. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-185: Incorrect Regular Expression' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://brakemanscanner.org/docs/warning_types/format_validation/ + - https://github.com/presidentbeef/brakeman/blob/aef6253a8b7bcb97116f2af1ed2a561a6ae35bd5/test/apps/rails3/app/models/account.rb + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/models/account.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_validation_regex.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: search + patterns: + - pattern-either: + - pattern: | + validates ..., :format => <... $V ...>,... + - pattern: | + validates_format_of ..., :with => <... $V ...>,... + - metavariable-regex: + metavariable: $V + regex: /(.{2}(? $X,...) + - focus-metavariable: $X + - patterns: + - pattern: | + "$SQLVERB#{$EXPR}..." + - pattern-not-inside: | + $FUNC("...", "...#{$EXPR}...",...) + - focus-metavariable: $SQLVERB + - pattern-regex: (?i)(select|delete|insert|create|update|alter|drop)\b + - patterns: + - pattern-either: + - pattern: Kernel::sprintf("$SQLSTR", $EXPR) + - pattern: | + "$SQLSTR" + $EXPR + - pattern: | + "$SQLSTR" % $EXPR + - pattern-not-inside: | + $FUNC("...", "...#{$EXPR}...",...) + - focus-metavariable: $EXPR + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b + pattern-sources: + - patterns: + - pattern-either: + - pattern: params + - pattern: request + severity: ERROR + - id: ruby.rails.security.injection.tainted-url-host.tainted-url-host + languages: + - ruby + message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Use the `ssrf_filter` gem and guard the url construction with `SsrfFilter(...)`, or create an allowlist for approved hosts. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + - https://github.com/arkadiyt/ssrf_filter + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sanitizers: + - pattern: SsrfFilter + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: | + $URLSTR + - pattern-regex: \w+:\/\/#{.*} + - patterns: + - pattern-either: + - pattern: Kernel::sprintf("$URLSTR", ...) + - pattern: | + "$URLSTR" + $EXPR + - pattern: | + "$URLSTR" % $EXPR + - metavariable-pattern: + language: generic + metavariable: $URLSTR + pattern: $SCHEME:// ... + pattern-sources: + - patterns: + - pattern-either: + - pattern: params + - pattern: request + severity: WARNING + - id: rust.lang.security.args-os.args-os + languages: + - rust + message: 'args_os should not be used for security operations. From the docs: "The first element is traditionally the path of the executable, but it can be set to arbitrary text, and might not even exist. This means this property should not be relied upon for security purposes."' + metadata: + category: security + confidence: HIGH + cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' + impact: LOW + likelihood: LOW + references: + - https://doc.rust-lang.org/stable/std/env/fn.args_os.html + subcategory: audit + technology: + - rust + pattern: std::env::args_os() + severity: INFO + - id: rust.lang.security.args.args + languages: + - rust + message: 'args should not be used for security operations. From the docs: "The first element is traditionally the path of the executable, but it can be set to arbitrary text, and might not even exist. This means this property should not be relied upon for security purposes."' + metadata: + category: security + confidence: HIGH + cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' + impact: LOW + likelihood: LOW + references: + - https://doc.rust-lang.org/stable/std/env/fn.args.html + subcategory: audit + technology: + - rust + pattern: std::env::args() + severity: INFO + - id: rust.lang.security.current-exe.current-exe + languages: + - rust + message: 'current_exe should not be used for security operations. From the docs: "The output of this function should not be trusted for anything that might have security implications. Basically, if users can run the executable, they can change the output arbitrarily."' + metadata: + category: security + confidence: HIGH + cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' + impact: LOW + likelihood: LOW + references: + - https://doc.rust-lang.org/stable/std/env/fn.current_exe.html#security + subcategory: audit + technology: + - rust + pattern: std::env::current_exe() + severity: INFO + - id: rust.lang.security.insecure-hashes.insecure-hashes + languages: + - rust + message: Detected cryptographically insecure hashing function + metadata: + category: security + confidence: HIGH + cwe: 'CWE-328: Use of Weak Hash' + impact: MEDIUM + likelihood: LOW + references: + - https://github.com/RustCrypto/hashes + - https://docs.rs/md2/latest/md2/ + - https://docs.rs/md4/latest/md4/ + - https://docs.rs/md5/latest/md5/ + - https://docs.rs/sha-1/latest/sha1/ + subcategory: audit + technology: + - rust + pattern-either: + - pattern: md2::Md2::new(...) + - pattern: md4::Md4::new(...) + - pattern: md5::Md5::new(...) + - pattern: sha1::Sha1::new(...) + severity: WARNING + - id: rust.lang.security.reqwest-accept-invalid.reqwest-accept-invalid + languages: + - rust + message: Dangerously accepting invalid TLS information + metadata: + category: security + confidence: HIGH + cwe: 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: LOW + references: + - https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.danger_accept_invalid_hostnames + - https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.danger_accept_invalid_certs + subcategory: vuln + technology: + - reqwest + pattern-either: + - pattern: reqwest::Client::builder(). ... .danger_accept_invalid_hostnames(true) + - pattern: reqwest::Client::builder(). ... .danger_accept_invalid_certs(true) + severity: WARNING + - id: rust.lang.security.reqwest-set-sensitive.reqwest-set-sensitive + languages: + - rust + message: Set sensitive flag on security headers with 'set_sensitive' to treat data with special care + metadata: + category: security + confidence: MEDIUM + cwe: 'CWE-921: Storage of Sensitive Data in a Mechanism without Access Control' + impact: LOW + likelihood: LOW + references: + - https://docs.rs/reqwest/latest/reqwest/header/struct.HeaderValue.html#method.set_sensitive + subcategory: audit + technology: + - reqwest + patterns: + - pattern: | + let mut $HEADERS = header::HeaderMap::new(); + ... + let $HEADER_VALUE = <... header::HeaderValue::$FROM_FUNC(...) ...>; + ... + $HEADERS.insert($HEADER, $HEADER_VALUE); + - pattern-not: | + let mut $HEADERS = header::HeaderMap::new(); + ... + let $HEADER_VALUE = <... header::HeaderValue::$FROM_FUNC(...) ...>; + ... + $HEADER_VALUE.set_sensitive(true); + ... + $HEADERS.insert($HEADER, $HEADER_VALUE); + - metavariable-pattern: + metavariable: $FROM_FUNC + pattern-either: + - pattern: from_static + - pattern: from_str + - pattern: from_name + - pattern: from_bytes + - pattern: from_maybe_shared + - metavariable-pattern: + metavariable: $HEADER + pattern-either: + - pattern: header::AUTHORIZATION + - pattern: '"Authorization"' + severity: INFO + - id: rust.lang.security.rustls-dangerous.rustls-dangerous + languages: + - rust + message: Dangerous client config used, ensure SSL verification + metadata: + category: security + confidence: HIGH + cwe: 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: LOW + references: + - https://docs.rs/rustls/latest/rustls/client/struct.DangerousClientConfig.html + - https://docs.rs/rustls/latest/rustls/client/struct.ClientConfig.html#method.dangerous + subcategory: vuln + technology: + - rustls + pattern-either: + - pattern: rustls::client::DangerousClientConfig + - pattern: $CLIENT.dangerous().set_certificate_verifier(...) + - pattern: | + let $CLIENT = rustls::client::ClientConfig::dangerous(...); + ... + $CLIENT.set_certificate_verifier(...); + severity: WARNING + - id: rust.lang.security.ssl-verify-none.ssl-verify-none + languages: + - rust + message: SSL verification disabled, this allows for MitM attacks + metadata: + category: security + confidence: HIGH + cwe: 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: LOW + references: + - https://docs.rs/openssl/latest/openssl/ssl/struct.SslContextBuilder.html#method.set_verify + subcategory: vuln + technology: + - openssl + pattern: $BUILDER.set_verify(openssl::ssl::SSL_VERIFY_NONE) + severity: WARNING + - id: rust.lang.security.temp-dir.temp-dir + languages: + - rust + message: 'temp_dir should not be used for security operations. From the docs: ''The temporary directory may be shared among users, or between processes with different privileges; thus, the creation of any files or directories in the temporary directory must use a secure method to create a uniquely named file. Creating a file or directory with a fixed or predictable name may result in “insecure temporary file” security vulnerabilities.''' + metadata: + category: security + confidence: HIGH + cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' + impact: LOW + likelihood: LOW + references: + - https://doc.rust-lang.org/stable/std/env/fn.temp_dir.html + subcategory: audit + technology: + - rust + pattern: std::env::temp_dir() + severity: INFO + - id: rust.lang.security.unsafe-usage.unsafe-usage + languages: + - rust + message: Detected 'unsafe' usage, please audit for secure usage + metadata: + category: security + confidence: HIGH + cwe: 'CWE-242: Use of Inherently Dangerous Function' + impact: LOW + likelihood: LOW + references: + - https://doc.rust-lang.org/std/keyword.unsafe.html + subcategory: audit + technology: + - rust + pattern: unsafe { ... } + severity: INFO + - id: scala.jwt-scala.security.jwt-scala-hardcode.jwt-scala-hardcode + languages: + - scala + message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://jwt-scala.github.io/jwt-scala/ + subcategory: + - vuln + technology: + - scala + patterns: + - pattern-inside: | + import pdi.jwt.$DEPS + ... + - pattern-either: + - pattern: $JWT.encode($X, "...", ...) + - pattern: $JWT.decode($X, "...", ...) + - pattern: $JWT.decodeRawAll($X, "...", ...) + - pattern: $JWT.decodeRaw($X, "...", ...) + - pattern: $JWT.decodeAll($X, "...", ...) + - pattern: $JWT.validate($X, "...", ...) + - pattern: $JWT.isValid($X, "...", ...) + - pattern: $JWT.decodeJson($X, "...", ...) + - pattern: $JWT.decodeJsonAll($X, "...", ...) + - patterns: + - pattern-either: + - pattern: $JWT.encode($X, $KEY, ...) + - pattern: $JWT.decode($X, $KEY, ...) + - pattern: $JWT.decodeRawAll($X, $KEY, ...) + - pattern: $JWT.decodeRaw($X, $KEY, ...) + - pattern: $JWT.decodeAll($X, $KEY, ...) + - pattern: $JWT.validate($X, $KEY, ...) + - pattern: $JWT.isValid($X, $KEY, ...) + - pattern: $JWT.decodeJson($X, $KEY, ...) + - pattern: $JWT.decodeJsonAll($X, $KEY, ...) + - pattern: $JWT.encode($X, this.$KEY, ...) + - pattern: $JWT.decode($X, this.$KEY, ...) + - pattern: $JWT.decodeRawAll($X, this.$KEY, ...) + - pattern: $JWT.decodeRaw($X, this.$KEY, ...) + - pattern: $JWT.decodeAll($X, this.$KEY, ...) + - pattern: $JWT.validate($X, this.$KEY, ...) + - pattern: $JWT.isValid($X, this.$KEY, ...) + - pattern: $JWT.decodeJson($X, this.$KEY, ...) + - pattern: $JWT.decodeJsonAll($X, this.$KEY, ...) + - pattern-either: + - pattern-inside: | + class $CL { + ... + $KEY = "..." + ... + } + - pattern-inside: | + object $CL { + ... + $KEY = "..." + ... + } + - metavariable-pattern: + metavariable: $JWT + patterns: + - pattern-either: + - pattern: Jwt + - pattern: JwtArgonaut + - pattern: JwtCirce + - pattern: JwtJson4s + - pattern: JwtJson + - pattern: JwtUpickle + severity: WARNING + - id: scala.lang.correctness.positive-number-index-of.positive-number-index-of + languages: + - scala + message: Flags scala code that look for values that are greater than 0. This ignores the first element, which is most likely a bug. Instead, use indexOf with -1. If the intent is to check the inclusion of a value, use the contains method instead. + metadata: + category: correctness + confidence: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + references: + - https://blog.codacy.com/9-scala-security-issues/ + technology: + - scala + patterns: + - pattern-either: + - patterns: + - pattern: | + $OBJ.indexOf(...) > $VALUE + - metavariable-comparison: + comparison: $VALUE >= 0 + metavariable: $VALUE + - patterns: + - pattern: | + $OBJ.indexOf(...) >= $SMALLERVAL + - metavariable-comparison: + comparison: $SMALLERVAL > 0 + metavariable: $SMALLERVAL + severity: WARNING + - id: scala.lang.security.audit.dangerous-seq-run.dangerous-seq-run + languages: + - scala + message: Found dynamic content used for the external process. This is dangerous if arbitrary data can reach this function call because it allows a malicious actor to execute commands. Ensure your variables are not controlled by users or sufficiently sanitized. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - scala + patterns: + - pattern: Seq($CMD, ...) + - pattern-not: Seq("...", ...) + - pattern-inside: | + import sys.process + ... + - pattern-not-inside: | + $CMD = "..." + ... + - pattern-either: + - pattern-inside: Seq(...).! + - pattern-inside: Seq(...).!! + - pattern-inside: Seq(...).lazyLines + severity: ERROR + - id: scala.lang.security.audit.dangerous-shell-run.dangerous-shell-run + languages: + - scala + message: Found dynamic content used for the external process. This is dangerous if arbitrary data can reach this function call because it allows a malicious actor to execute commands. Ensure your variables are not controlled by users or sufficiently sanitized. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - scala + patterns: + - pattern: Seq($SH, "-c", $CMD, ...) + - pattern-not: Seq($SH, "-c", "...", ...) + - pattern-inside: | + import sys.process + ... + - pattern-not-inside: | + $CMD = "..." + ... + - pattern-either: + - pattern-inside: Seq(...).! + - pattern-inside: Seq(...).!! + - pattern-inside: Seq(...).lazyLines + - metavariable-regex: + metavariable: $SH + regex: '"(sh|bash|ksh|csh|tcsh|zsh)"' + severity: ERROR + - id: scala.lang.security.audit.dispatch-ssrf.dispatch-ssrf + languages: + - scala + message: A parameter being passed directly into `url` most likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server running this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + - https://dispatchhttp.org/Dispatch.html + subcategory: + - audit + technology: + - scala + - dispatch + patterns: + - pattern: url($URL) + - pattern-inside: | + import dispatch._ + ... + - pattern-either: + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = $A { + ... + } + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = { + ... + } + severity: WARNING + - id: scala.lang.security.audit.documentbuilder-dtd-enabled.documentbuilder-dtd-enabled + languages: + - scala + message: Document Builder being instantiated without calling the `setFeature` functions that are generally used for disabling entity processing. User controlled data in XML Document builder can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - scala + patterns: + - pattern-either: + - pattern: | + $DF = DocumentBuilderFactory.newInstance(...) + ... + $DB = $DF.newDocumentBuilder(...) + - patterns: + - pattern: $DB = DocumentBuilderFactory.newInstance(...) + - pattern-not-inside: | + ... + $X = $DB.newDocumentBuilder(...) + - pattern: $DB = DocumentBuilderFactory.newInstance(...).newDocumentBuilder(...) + - pattern-not-inside: | + ... + $DB.setXIncludeAware(true) + ... + $DB.setNamespaceAware(true) + ... + $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + - pattern-not-inside: | + ... + $DB.setXIncludeAware(true) + ... + $DB.setNamespaceAware(true) + ... + $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + ... + $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) + - pattern-not-inside: | + ... + $DB.setXIncludeAware(true) + ... + $DB.setNamespaceAware(true) + ... + $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + - pattern-not-inside: | + ... + $DB.setXIncludeAware(true) + ... + $DB.setNamespaceAware(true) + ... + $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + ... + $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + severity: WARNING + - id: scala.lang.security.audit.insecure-random.insecure-random + languages: + - scala + message: Flags the use of a predictable random value from `scala.util.Random`. This can lead to vulnerabilities when used in security contexts, such as in a CSRF token, password reset token, or any other secret value. To fix this, use java.security.SecureRandom instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-330: Use of Insufficiently Random Values' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + resources: + - https://find-sec-bugs.github.io/bugs.htm + subcategory: + - audit + technology: + - scala + - cryptography + patterns: + - pattern: | + import scala.util.Random + severity: WARNING + - id: scala.lang.security.audit.io-source-ssrf.io-source-ssrf + languages: + - scala + message: A parameter being passed directly into `fromURL` most likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server running this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + - https://www.scala-lang.org/api/current/scala/io/Source$.html#fromURL(url:java.net.URL)(implicitcodec:scala.io.Codec):scala.io.BufferedSource + subcategory: + - audit + technology: + - scala + patterns: + - pattern-either: + - pattern: Source.fromURL($URL,...) + - pattern: Source.fromURI($URL,...) + - pattern-inside: | + import scala.io.$SOURCE + ... + - pattern-either: + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = $A { + ... + } + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = { + ... + } + severity: WARNING + - id: scala.lang.security.audit.path-traversal-fromfile.path-traversal-fromfile + languages: + - scala + message: Flags cases of possible path traversal. If an unfiltered parameter is passed into 'fromFile', file from an arbitrary filesystem location could be read. This could lead to sensitive data exposure and other provles. Instead, sanitize the user input instead of performing direct string concatenation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + resources: + - https://find-sec-bugs.github.io/bugs.htm + subcategory: + - audit + technology: + - scala + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $FILENAME = "..." + $VAR + ... + - pattern-inside: | + $FILENAME = $VAR + "..." + ... + - pattern-inside: | + $FILENAME = $STR.concat($VAR) + ... + - pattern-inside: | + $FILENAME = "...".format(..., $VAR, ...) + ... + - pattern: Source.fromFile($FILENAME, ...) + - patterns: + - pattern-either: + - pattern: Source.fromFile("..." + $VAR, ...) + - pattern: Source.fromFile($VAR + "...", ...) + - pattern: Source.fromFile($STR.concat($VAR), ...) + - pattern: Source.fromFile("...".format(..., $VAR, ...), ...) + - pattern-inside: | + def $FUNC(..., $VAR: $TYPE, ...) = Action { + ... + } + severity: WARNING + - id: scala.lang.security.audit.rsa-padding-set.rsa-padding-set + languages: + - scala + message: Usage of RSA without OAEP (Optimal Asymmetric Encryption Padding) may weaken encryption. This could lead to sensitive data exposure. Instead, use RSA with `OAEPWithMD5AndMGF1Padding` instead. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-780: Use of RSA Algorithm without OAEP' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + resources: + - https://blog.codacy.com/9-scala-security-issues/ + subcategory: + - audit + technology: + - scala + - cryptography + patterns: + - pattern: | + $VAR = $CIPHER.getInstance($MODE) + - metavariable-regex: + metavariable: $MODE + regex: .*RSA/.*/NoPadding.* + severity: WARNING + - id: scala.lang.security.audit.sax-dtd-enabled.sax-dtd-enabled + languages: + - scala + message: XML processor being instantiated without calling the `setFeature` functions that are generally used for disabling entity processing. User controlled data in XML Parsers can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - scala + patterns: + - pattern-either: + - pattern: $SR = new SAXReader(...) + - pattern: | + $SF = SAXParserFactory.newInstance(...) + ... + $SR = $SF.newSAXParser(...) + - patterns: + - pattern: $SR = SAXParserFactory.newInstance(...) + - pattern-not-inside: | + ... + $X = $SR.newSAXParser(...) + - pattern: $SR = SAXParserFactory.newInstance(...).newSAXParser(...) + - pattern: $SR = new SAXBuilder(...) + - pattern-not-inside: | + ... + $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + - pattern-not-inside: | + ... + $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + ... + $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) + - pattern-not-inside: | + ... + $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + - pattern-not-inside: | + ... + $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + ... + $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + severity: WARNING + - id: scala.lang.security.audit.scala-dangerous-process-run.scala-dangerous-process-run + languages: + - scala + message: Found dynamic content used for the external process. This is dangerous if arbitrary data can reach this function call because it allows a malicious actor to execute commands. Use `Seq(...)` for dynamically generated commands. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - scala + patterns: + - pattern-either: + - pattern: $X.! + - pattern: $X.!! + - pattern: $X.lazyLines + - pattern-inside: | + import sys.process + ... + - pattern-not: | + "...".! + - pattern-not: | + "...".!! + - pattern-not: | + "...".lazyLines + - pattern-not: | + Seq(...).! + - pattern-not: | + Seq(...).!! + - pattern-not: | + Seq(...).lazyLines + - pattern-not-inside: | + val $X = "..." + ... + - pattern-not-inside: | + val $X = Seq(...) + ... + severity: ERROR + - id: scala.lang.security.audit.scalac-debug.scalac-debug + languages: + - generic + message: Scala applications built with `debug` set to true in production may leak debug information to attackers. Debug mode also affects performance and reliability. Remove it from configuration. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-489: Active Debug Code' + impact: LOW + likelihood: LOW + owasp: A05:2021 - Security Misconfiguration + references: + - https://docs.scala-lang.org/overviews/compiler-options/index.html + subcategory: + - audit + technology: + - scala + - sbt + paths: + include: + - '*.sbt*' + patterns: + - pattern-either: + - pattern: scalacOptions ... "-Vdebug" + - pattern: scalacOptions ... "-Ydebug" + severity: WARNING + - id: scala.lang.security.audit.scalaj-http-ssrf.scalaj-http-ssrf + languages: + - scala + message: A parameter being passed directly into `Http` can likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server running this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + - https://github.com/scalaj/scalaj-http#simplified-http + subcategory: + - audit + technology: + - scala + - scalaj-http + patterns: + - pattern: Http($URL) + - pattern-inside: | + import scalaj.http.$HTTP + ... + - pattern-either: + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = $A { + ... + } + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = { + ... + } + severity: WARNING + - id: scala.lang.security.audit.scalajs-eval.scalajs-eval + languages: + - scala + message: '`eval()` function evaluates JavaScript code represented as a string. Executing JavaScript from a string is an enormous security risk. It is far too easy for a bad actor to run arbitrary code when you use `eval()`. Do not use eval(). Alternatively: Ensure evaluated content is not definable by external sources. If it’s not possible, strip everything except alphanumeric characters from an input provided for the command string and arguments.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A03:2021 - Injection + references: + - https://www.scala-js.org/doc/ + subcategory: + - vuln + technology: + - scala + - scala-js + mode: taint + pattern-sinks: + - patterns: + - pattern: $JS.eval(...) + - pattern-inside: | + import scala.scalajs.$X + ... + pattern-sources: + - patterns: + - pattern: $PARAM + - pattern-either: + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = $A { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = $A(...) { + ... + } + severity: WARNING + - id: scala.lang.security.audit.tainted-sql-string.tainted-sql-string + languages: + - scala + message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html + subcategory: + - vuln + technology: + - scala + mode: taint + pattern-sanitizers: + - pattern-either: + - patterns: + - pattern-either: + - pattern: $LOGGER.$METHOD(...) + - pattern: $LOGGER(...) + - metavariable-regex: + metavariable: $LOGGER + regex: (i?)log.* + - patterns: + - pattern: $LOGGER.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (i?)(trace|info|warn|warning|warnToError|error|debug) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR".format(...) + - patterns: + - pattern-inside: | + $SB = new StringBuilder("$SQLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$SQLSTR" + ... + - pattern: $VAR += ... + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b + - patterns: + - pattern-either: + - pattern: s"..." + - pattern: f"..." + - pattern-regex: | + .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - pattern-not-inside: println(...) + pattern-sources: + - patterns: + - pattern: $PARAM + - pattern-either: + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = $A { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = $A(...) { + ... + } + severity: ERROR + - id: scala.lang.security.audit.xmlinputfactory-dtd-enabled.xmlinputfactory-dtd-enabled + languages: + - scala + message: XMLInputFactory being instantiated without calling the setProperty functions that are generally used for disabling entity processing. User controlled data in XML Document builder can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - scala + patterns: + - pattern-not-inside: | + ... + $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", false) + - pattern-either: + - pattern: $XMLFACTORY = XMLInputFactory.newFactory(...) + - pattern: $XMLFACTORY = XMLInputFactory.newInstance(...) + - pattern: $XMLFACTORY = new XMLInputFactory(...) + severity: WARNING + - id: scala.play.security.conf-csrf-headers-bypass.conf-csrf-headers-bypass + languages: + - generic + message: Possibly bypassable CSRF configuration found. CSRF is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. Make sure that Content-Type black list is configured and CORS filter is turned on. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://www.playframework.com/documentation/2.8.x/Migration25#CSRF-changes + - https://owasp.org/www-community/attacks/csrf + subcategory: + - vuln + technology: + - scala + - play + paths: + include: + - '*.conf' + patterns: + - pattern-either: + - pattern: X-Requested-With = "*" + - pattern: Csrf-Token = "..." + - pattern-inside: | + bypassHeaders {... + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."application/x-www-form-urlencoded"..."multipart/form-data"..."text/plain"...] + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."application/x-www-form-urlencoded"..."text/plain"..."multipart/form-data"...] + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."multipart/form-data"..."application/x-www-form-urlencoded"..."text/plain"...] + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."multipart/form-data"..."text/plain"..."application/x-www-form-urlencoded"...] + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."text/plain"..."application/x-www-form-urlencoded"..."multipart/form-data"...] + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."text/plain"..."multipart/form-data"..."application/x-www-form-urlencoded"...] + ... + ...} + severity: ERROR + - id: scala.play.security.conf-insecure-cookie-settings.conf-insecure-cookie-settings + languages: + - generic + message: Session cookie `Secure` flag is explicitly disabled. The `secure` flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the `Secure` flag by setting `secure` to `true` in configuration file. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#security + - https://www.playframework.com/documentation/2.8.x/SettingsSession#Session-Configuration + subcategory: + - vuln + technology: + - play + - scala + paths: + include: + - '*.conf' + patterns: + - pattern: secure = false + - pattern-inside: | + session = { + ... + } + severity: WARNING + - id: scala.play.security.tainted-html-response.tainted-html-response + languages: + - scala + message: Detected a request with potential user-input going into an `Ok()` response. This bypasses any view or template environments, including HTML escaping, which may expose this application to cross-site scripting (XSS) vulnerabilities. Consider using a view technology such as Twirl which automatically escapes HTML views. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - scala + - play + mode: taint + pattern-sanitizers: + - pattern-either: + - pattern: org.apache.commons.lang3.StringEscapeUtils.escapeHtml4(...) + - pattern: org.owasp.encoder.Encode.forHtml(...) + pattern-sinks: + - pattern-either: + - pattern: Html.apply(...) + - pattern: Ok(...).as(HTML) + - pattern: Ok(...).as(ContentTypes.HTML) + - patterns: + - pattern: Ok(...).as($CTYPE) + - metavariable-regex: + metavariable: $CTYPE + regex: '"[tT][eE][xX][tT]/[hH][tT][mM][lL]"' + - patterns: + - pattern: Ok(...).as($CTYPE) + - pattern-not: Ok(...).as("...") + - pattern-either: + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = $A { + ... + } + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = { + ... + } + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern: $REQ + - pattern-either: + - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - patterns: + - pattern: $PARAM + - pattern-either: + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { + ... + } + severity: WARNING + - id: scala.play.security.tainted-slick-sqli.tainted-slick-sqli + languages: + - scala + message: Detected a tainted SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Avoid using using user input for generating SQL strings. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://scala-slick.org/doc/3.3.3/sql.html#splicing-literal-values + - https://scala-slick.org/doc/3.2.0/sql-to-slick.html#non-optimal-sql-code + subcategory: + - vuln + technology: + - scala + - slick + - play + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $MODEL.overrideSql(...) + - pattern: sql"..." + - pattern-inside: | + import slick.$DEPS + ... + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern: $REQ + - pattern-either: + - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - patterns: + - pattern: $PARAM + - pattern-either: + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { + ... + } + severity: ERROR + - id: scala.play.security.tainted-sql-from-http-request.tainted-sql-from-http-request + languages: + - scala + message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html + subcategory: + - vuln + technology: + - scala + - play + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR".format(...) + - patterns: + - pattern-inside: | + $SB = new StringBuilder("$SQLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$SQLSTR" + ... + - pattern: $VAR += ... + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b + - patterns: + - pattern: s"..." + - pattern-regex: | + .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - pattern-not-inside: println(...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern: $REQ + - pattern-either: + - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - patterns: + - pattern: $PARAM + - pattern-either: + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { + ... + } + severity: ERROR + - id: scala.play.security.twirl-html-var.twirl-html-var + languages: + - generic + message: Raw html content controlled by a variable detected. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. Try to avoid using `Html()` or consider properly sanitizing input data. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://www.playframework.com/documentation/2.8.x/ScalaTemplates#Escaping + subcategory: + - audit + technology: + - scala + - play + - twirl + paths: + include: + - '*.html' + patterns: + - pattern-either: + - pattern: | + @Html($VAL) + - pattern: | + @Html(...$VAL + ...) + - pattern: | + @Html(... + $VAL...) + - metavariable-regex: + metavariable: $VAL + regex: \w* + severity: WARNING + - id: scala.play.security.webservice-ssrf.webservice-ssrf + languages: + - scala + message: A parameter being passed directly into `WSClient` most likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server running this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts hardcode the correct host. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + - https://www.playframework.com/documentation/2.8.x/ScalaWS + subcategory: + - audit + technology: + - scala + - play + patterns: + - pattern: $WS.url($URL) + - pattern-either: + - pattern-inside: | + class $CLASS (..., $WS: WSClient, ...) { + ... + } + - pattern-inside: | + def $FUNC(..., $WS: WSClient, ...) = { + ... + } + - pattern-inside: | + $WS = AhcWSClient(...) + ... + - pattern-either: + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = $A { + ... + } + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = { + ... + } + severity: WARNING + - id: scala.scala-jwt.security.jwt-hardcode.scala-jwt-hardcoded-secret + languages: + - scala + message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + pattern-either: + - pattern: | + com.auth0.jwt.algorithms.Algorithm.HMAC256("..."); + - pattern: | + $SECRET = "..."; + ... + com.auth0.jwt.algorithms.Algorithm.HMAC256($SECRET); + - pattern: | + class $CLASS { + ... + $DECL $SECRET = "..."; + ... + def $FUNC (...): $RETURNTYPE = { + ... + com.auth0.jwt.algorithms.Algorithm.HMAC256($SECRET); + ... + } + ... + } + - pattern: | + com.auth0.jwt.algorithms.Algorithm.HMAC384("..."); + - pattern: | + $SECRET = "..."; + ... + com.auth0.jwt.algorithms.Algorithm.HMAC384($SECRET); + - pattern: | + class $CLASS { + ... + $DECL $SECRET = "..."; + ... + def $FUNC (...): $RETURNTYPE = { + ... + com.auth0.jwt.algorithms.Algorithm.HMAC384($SECRET); + ... + } + ... + } + - pattern: | + com.auth0.jwt.algorithms.Algorithm.HMAC512("..."); + - pattern: | + $SECRET = "..."; + ... + com.auth0.jwt.algorithms.Algorithm.HMAC512($SECRET); + - pattern: | + class $CLASS { + ... + $DECL $SECRET = "..."; + ... + def $FUNC (...): $RETURNTYPE = { + ... + com.auth0.jwt.algorithms.Algorithm.HMAC512($SECRET); + ... + } + ... + } + severity: ERROR + - id: scala.slick.security.scala-slick-overridesql-literal.scala-slick-overridesql-literal + languages: + - scala + message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Avoid using non literal values in `overrideSql(...)`. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - audit + technology: + - scala + - slick + patterns: + - pattern: $MODEL.overrideSql($QUERY,...) + - pattern-not: $MODEL.overrideSql("...",...) + - pattern-not-inside: | + $QUERY = "..." + ... + severity: ERROR + - id: scala.slick.security.scala-slick-sql-non-literal.scala-slick-sql-non-literal + languages: + - scala + message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Avoid using `#$variable` and use `$variable` in `sql"..."` strings instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://scala-slick.org/doc/3.3.3/sql.html#splicing-literal-values + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SCALA_SQL_INJECTION_SLICK + subcategory: + - audit + technology: + - scala + - slick + patterns: + - pattern: sql"..." + - pattern-regex: \#\$ + - pattern-inside: | + import slick.$DEPS + ... + severity: ERROR + - id: swift.lang.crypto.insecure-random.insecure-random + languages: + - swift + message: A random number generator was detected which is **not** *guaranteed* to be Cryptographically secure. If the source of entropy is used for security purposes (e.g. with other Cryptographic operations), make sure to use the `SecCopyRandomBytes` API explicitly. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)' + impact: LOW + likelihood: LOW + masvs: + - 'MSTG-CRYPTO-6: All random values are generated using a sufficiently secure random number generator.' + owasp: + - A02:2021 - Cryptographic Failures + references: + - https://mobile-security.gitbook.io/masvs/security-requirements/0x08-v3-cryptography_verification_requirements + - https://developer.apple.com/documentation/security/1399291-secrandomcopybytes + - https://developer.apple.com/documentation/security/randomization_services?language=swift + - https://github.com/apple/swift-evolution/blob/main/proposals/0202-random-unification.md + subcategory: + - audit + technology: + - ios + - macos + pattern-either: + - pattern: random() + - pattern: Int.random(...) + - pattern: Bool.random(...) + - pattern: Float.random(...) + - pattern: Double.random(...) + - pattern: arc4random() + - pattern: arc4random_buf(...) + - pattern: arc4random_uniform(...) + - pattern: SystemRandomNumberGenerator(...) + - pattern: rand() + severity: WARNING + - id: swift.lang.storage.sensitive-storage-userdefaults.swift-user-defaults + languages: + - swift + message: Potentially sensitive data was observed to be stored in UserDefaults, which is not adequate protection of sensitive information. For data of a sensitive nature, applications should leverage the Keychain. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW + masvs: + - 'MASVS-STORAGE-1: The app securely stores sensitive data' + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html + - https://mas.owasp.org/MASVS/controls/MASVS-STORAGE-1/ + subcategory: + - vuln + technology: + - ios + - macos + options: + symbolic_propagation: true + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $VALUE + regex: (?i).*(passcode|password|pass_word|passphrase|pass_code|pass_word|pass_phrase)$ + - focus-metavariable: $VALUE + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $KEY + regex: (?i).*(passcode|password|pass_word|passphrase|pass_code|pass_word|pass_phrase)$ + - focus-metavariable: $KEY + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $VALUE + regex: (?i).*(api_key|apikey)$ + - focus-metavariable: $VALUE + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $KEY + regex: (?i).*(api_key|apikey)$ + - focus-metavariable: $KEY + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $VALUE + regex: (?i).*(secretkey|secret_key|secrettoken|secret_token|clientsecret|client_secret)$ + - focus-metavariable: $VALUE + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $KEY + regex: (?i).*(secretkey|secret_key|secrettoken|secret_token|clientsecret|client_secret)$ + - focus-metavariable: $KEY + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $VALUE + regex: (?i).*(cryptkey|cryptokey|crypto_key|cryptionkey|symmetrickey|privatekey|symmetric_key|private_key)$ + - focus-metavariable: $VALUE + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $KEY + regex: (?i).*(cryptkey|cryptokey|crypto_key|cryptionkey|symmetrickey|privatekey|symmetric_key|private_key)$ + - focus-metavariable: $KEY + severity: WARNING + - id: swift.sqllite.sqllite-injection-audit.swift-potential-sqlite-injection + languages: + - swift + message: Potential Client-side SQL injection which has different impacts depending on the SQL use-case. The impact may include the circumvention of local authentication mechanisms, obtaining of sensitive data from the app, or manipulation of client-side behavior. It wasn't possible to make certain that the source is untrusted, but the application should avoid concatenating dynamic data into SQL queries and should instead leverage parameterized queries. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + impact: MEDIUM + likelihood: MEDIUM + masvs: + - 'MASVS-CODE-4: The app validates and sanitizes all untrusted inputs.' + references: + - https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html + subcategory: + - vuln + technology: + - ios + - macos + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: sqlite3_exec($DB, $SQL, ...) + - pattern: sqlite3_prepare_v2($DB, $SQL, ...) + - focus-metavariable: + - $SQL + pattern-sources: + - pattern-either: + - pattern: | + "...\($X)..." + - pattern: | + $SQL = "..." + $X + - pattern: | + $SQL = $X + "..." + severity: WARNING + - id: swift.webview.webview-js-window.swift-webview-config-allows-js-open-windows + languages: + - swift + message: Webviews were observed that explictly allow JavaScript in an WKWebview to open windows automatically. Consider disabling this functionality if not required, following the principle of least privelege. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-272: Least Privilege Violation' + impact: LOW + likelihood: LOW + masvs: + - 'MASVS-PLATFORM-2: The app uses WebViews securely' + references: + - https://mas.owasp.org/MASVS/controls/MASVS-PLATFORM-2/ + - https://developer.apple.com/documentation/webkit/wkpreferences/1536573-javascriptcanopenwindowsautomati + subcategory: + - audit + technology: + - ios + - macos + patterns: + - pattern: | + $P = WKPreferences() + ... + - pattern-either: + - patterns: + - pattern-inside: | + $P.JavaScriptCanOpenWindowsAutomatically = $FALSE + ... + $P.JavaScriptCanOpenWindowsAutomatically = $TRUE + - pattern-not-inside: | + ... + $P.JavaScriptCanOpenWindowsAutomatically = $TRUE + ... + $P.JavaScriptCanOpenWindowsAutomatically = $FALSE + - pattern: | + $P.JavaScriptCanOpenWindowsAutomatically = true + - metavariable-regex: + metavariable: $TRUE + regex: ^(true)$ + - metavariable-regex: + metavariable: $TRUE + regex: (.*(?!true)) + - patterns: + - pattern: | + $P.JavaScriptCanOpenWindowsAutomatically = true + - pattern-not-inside: | + ... + $P.JavaScriptCanOpenWindowsAutomatically = ... + ... + $P.JavaScriptCanOpenWindowsAutomatically = ... + severity: WARNING + - id: terraform.aws.best-practice.aws-elasticache-automatic-backup-not-enabled.aws-elasticache-automatic-backup-not-enabled + languages: + - hcl + message: Ensure that Amazon ElastiCache clusters have automatic backup turned on. To fix this, set a `snapshot_retention_limit`. + metadata: + category: best-practice + technology: + - terraform + - aws + patterns: + - pattern-either: + - patterns: + - pattern: | + resource "aws_elasticache_cluster" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_elasticache_cluster" $ANYTHING { + ... + engine = "memcached" + ... + } + - pattern-not-inside: | + resource "aws_elasticache_cluster" $ANYTHING { + ... + snapshot_retention_limit = ... + ... + } + - patterns: + - pattern: | + resource "aws_elasticache_cluster" $ANYTHING { + ... + snapshot_retention_limit = $LIMIT + ... + } + - metavariable-comparison: + comparison: $LIMIT == 0 + metavariable: $LIMIT + severity: WARNING + - id: terraform.aws.best-practice.aws-qldb-inadequate-ledger-permissions-mode.aws-qldb-inadequate-ledger-permissions-mode + languages: + - hcl + message: The AWS QLDB ledger permissions are too permissive. Consider using "'STANDARD'" permissions mode if possible. + metadata: + category: best-practice + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_qldb_ledger" $ANYTHING { + ... + permissions_mode = "ALLOW_ALL" + ... + } + severity: WARNING + - id: terraform.aws.best-practice.aws-rds-cluster-iam-authentication-not-enabled.aws-rds-cluster-iam-authentication-not-enabled + languages: + - hcl + message: The AWS RDS Cluster is not configured to use IAM authentication. Consider using IAM for authentication. + metadata: + category: best-practice + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_rds_cluster" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_rds_cluster" $ANYTHING { + ... + iam_database_authentication_enabled = true + ... + } + severity: WARNING + - id: terraform.aws.best-practice.aws-rds-iam-authentication-not-enabled.aws-rds-iam-authentication-not-enabled + languages: + - hcl + message: The AWS RDS is not configured to use IAM authentication. Consider using IAM for authentication. + metadata: + category: best-practice + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_db_instance" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_db_instance" $ANYTHING { + ... + iam_database_authentication_enabled = true + ... + } + severity: WARNING + - id: terraform.aws.best-practice.aws-rds-multiaz-not-enabled.aws-rds-multiaz-not-enabled + languages: + - hcl + message: The AWS RDS is not configured to use multi-az. Consider using it if possible. + metadata: + category: best-practice + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_db_instance" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_db_instance" $ANYTHING { + ... + multi_az = true + ... + } + severity: WARNING + - id: terraform.aws.best-practice.aws-s3-bucket-versioning-not-enabled.aws-s3-bucket-versioning-not-enabled + languages: + - hcl + message: Ensure that Amazon S3 bucket versioning is not enabled. Consider using versioning if you don't have alternative backup mechanism. + metadata: + category: best-practice + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_s3_bucket" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_s3_bucket" $ANYTHING { + ... + versioning { + ... + enabled = true + ... + } + ... + } + - pattern-not-inside: | + resource "aws_s3_bucket" $ANYTHING { + ... + versioning { + ... + enabled = var.$X + ... + } + ... + } + severity: WARNING + - id: terraform.aws.best-practice.aws-s3-object-lock-not-enabled.aws-s3-object-lock-not-enabled + languages: + - hcl + message: The AWS S3 object lock is not enabled. Consider using it if possible. + metadata: + category: best-practice + technology: + - terraform + - aws + patterns: + - pattern-either: + - pattern: | + resource "aws_s3_bucket" $ANYTHING { + ... + object_lock_configuration = { + object_lock_enabled = "Disabled" + } + ... + } + - pattern: | + resource "aws_s3_bucket" $ANYTHING { + ... + object_lock_configuration { + object_lock_enabled = "Disabled" + } + ... + } + severity: WARNING + - id: terraform.aws.best-practice.missing-alb-drop-http-headers.missing-alb-drop-http-headers + languages: + - hcl + message: Detected a AWS load balancer that is not configured to drop invalid HTTP headers. Add `drop_invalid_header_fields = true` in your resource block. + metadata: + category: best-practice + technology: + - aws + - terraform + patterns: + - pattern-either: + - pattern: | + resource "aws_lb" $ENABLED { + ... + } + - pattern: | + resource "aws_alb" $ENABLED { + ... + } + - pattern-not-inside: | + resource $ANYTHING $ENABLED { + ... + drop_invalid_header_fields = true + ... + } + severity: WARNING + - id: terraform.aws.best-practice.missing-api-gateway-cache-cluster.missing-api-gateway-cache-cluster + languages: + - hcl + message: Found a AWS API Gateway Stage without cache cluster enabled. Enabling the cache cluster feature enhances responsiveness of your API. Add `cache_cluster_enabled = true` to your resource block. + metadata: + category: best-practice + technology: + - aws + - terraform + patterns: + - pattern: | + resource "aws_api_gateway_stage" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_api_gateway_stage" $ANYTHING { + ... + cache_cluster_enabled = true + ... + } + severity: WARNING + - id: terraform.aws.best-practice.missing-autoscaling-group-tags.missing-autoscaling-group-tags + languages: + - hcl + message: |- + There are missing tags for an AWS Auto Scaling group. Tags help track costs, allow for filtering for Auto Scaling groups, help with access control, and aid in organizing AWS resources. Add: `tag { + key = "key" + value = "value" + propagate_at_launch = boolean + }` See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group for more details. + metadata: + category: best-practice + technology: + - aws + - terraform + patterns: + - patterns: + - patterns: + - pattern: resource "aws_autoscaling_group" $ANYTHING {...} + - pattern-not-inside: | + resource "aws_autoscaling_group" $ANYTHING { + ... + tag {...} + ... + } + - patterns: + - pattern: resource "aws_autoscaling_group" $ANYTHING {...} + - pattern-not-inside: | + resource "aws_autoscaling_group" $ANYTHING { + ... + tags = concat(...) + ... + } + severity: WARNING + - id: terraform.aws.best-practice.missing-aws-autoscaling-tags.missing-aws-autoscaling-tags + languages: + - hcl + message: The AWS Autoscaling Group is not tagged. + metadata: + category: best-practice + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_autoscaling_group" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_autoscaling_group" $ANYTHING { + ... + tag { + ... + } + ... + } + - pattern-not-inside: | + resource "aws_autoscaling_group" $ANYTHING { + ... + tags = concat( + ... + ) + ... + } + severity: WARNING + - id: terraform.aws.best-practice.missing-aws-cross-zone-lb.missing-aws-cross-zone-lb + languages: + - hcl + message: The AWS cross zone load balancing is not enabled. + metadata: + category: best-practice + technology: + - terraform + - aws + patterns: + - pattern-either: + - pattern: | + resource "aws_lb" $ANYTHING { + ... + load_balancer_type = ... + ... + } + - pattern: | + resource "aws_alb" $ANYTHING { + ... + load_balancer_type = ... + ... + } + - pattern-not-inside: | + resource $ANYLB $ANYTHING { + ... + enable_cross_zone_load_balancing = true + ... + } + - pattern-not-inside: | + resource $ANYLB $ANYTHING { + ... + load_balancer_type = "application" + ... + } + severity: WARNING + - id: terraform.aws.best-practice.missing-aws-lb-deletion-protection.missing-aws-lb-deletion-protection + languages: + - hcl + message: The AWS LoadBalancer deletion protection is not enabled. + metadata: + category: best-practice + references: + - https://aws.amazon.com/what-is/load-balancing/#seo-faq-pairs#benefits-lb + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb + technology: + - terraform + - aws + patterns: + - pattern-either: + - pattern-inside: | + resource "aws_alb" "..." { + ... + } + - pattern-inside: | + resource "aws_lb" "..." { + ... + } + - pattern-not-inside: | + resource $ANYLB $ANYTHING { + ... + enable_deletion_protection = true + ... + } + severity: WARNING + - id: terraform.aws.best-practice.missing-aws-qldb-deletion-protection.missing-aws-qldb-deletion-protection + languages: + - hcl + message: The AWS QLDB deletion protection is not enabled. + metadata: + category: best-practice + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_qldb_ledger" $ANYTHING { + ... + deletion_protection = false + ... + } + severity: WARNING + - id: terraform.aws.best-practice.missing-cloudwatch-log-group-kms-key.missing-cloudwatch-log-group-kms-key + languages: + - hcl + message: The AWS CloudWatch Log group is missing a KMS key. While Log group data is always encrypted, you can optionally use a KMS key instead. Add `kms_key_id = "yourKey"` to your resource block. + metadata: + category: best-practice + technology: + - aws + - terraform + patterns: + - patterns: + - pattern: resource "aws_cloudwatch_log_group" $ANYTHING {...} + - pattern-not-inside: | + resource "aws_cloudwatch_log_group" $ANYTHING { + ... + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.best-practice.missing-cloudwatch-log-group-retention.missing-cloudwatch-log-group-retention + languages: + - hcl + message: The AWS CloudWatch Log group is missing log retention time. By default, logs are retained indefinitely. Add `retention_in_days = ` to your resource block. + metadata: + category: best-practice + technology: + - aws + - terraform + patterns: + - patterns: + - pattern: resource "aws_cloudwatch_log_group" $ANYTHING {...} + - pattern-not-inside: | + resource "aws_cloudwatch_log_group" $ANYTHING { + ... + retention_in_days = ... + ... + } + severity: WARNING + - id: terraform.aws.correctness.lambda-permission-logs-missing-arn-asterisk.lambda-permission-logs-missing-arn-asterisk + languages: + - hcl + message: 'The `source_arn` field needs to end with an asterisk, like this: `:*` Without this, the `aws_lambda_permission` resource ''$NAME'' will not be created. Add the asterisk to the end of the arn. x $ARN' + metadata: + category: correctness + references: + - https://github.com/hashicorp/terraform-provider-aws/issues/14630 + technology: + - aws + - terraform + - aws-lambda + patterns: + - pattern-inside: | + resource "aws_lambda_permission" "$NAME" { ... } + - pattern: | + source_arn = $ARN + - metavariable-pattern: + metavariable: $ARN + patterns: + - pattern-regex: arn:aws:logs.* + - pattern-not-regex: arn:aws:logs:.*:\* + severity: WARNING + - id: terraform.aws.correctness.lambda-redundant-field-with-image.lambda-redundant-field-with-image + languages: + - hcl + message: When using the AWS Lambda "Image" package_type, `runtime` and `handler` are not necessary for Lambda to understand how to run the code. These are built into the container image. Including `runtime` or `handler` with an "Image" `package_type` will result in an error on `terraform apply`. Remove these redundant fields. + metadata: + category: correctness + references: + - https://stackoverflow.com/questions/72771366/why-do-i-get-error-handler-and-runtime-must-be-set-when-packagetype-is-zip-whe + technology: + - aws + - terraform + - aws-lambda + patterns: + - pattern-inside: "resource \"aws_lambda_function\" $NAME { \n ...\n package_type = \"Image\"\n}\n" + - pattern-either: + - pattern: handler = ... + - pattern: runtime = ... + severity: WARNING + - id: terraform.aws.correctness.reserved-aws-lambda-environment-variable.reserved-aws-lambda-environment-variable + languages: + - hcl + message: '`terraform apply` will fail because the environment variable "$VARIABLE" is a reserved by AWS. Use another name for "$VARIABLE".' + metadata: + category: correctness + references: + - https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime + technology: + - aws + - aws-lambda + - terraform + patterns: + - pattern-inside: | + resource "aws_lambda_function" $FUNCTION { ... } + - pattern-inside: | + environment { ... } + - pattern-inside: | + variables = { ... } + - pattern: | + $VARIABLE = ... + - metavariable-pattern: + metavariable: $VARIABLE + patterns: + - pattern-either: + - pattern: _HANDLER + - pattern: _X_AMZN_TRACE_ID + - pattern: AWS_DEFAULT_REGION + - pattern: AWS_REGION + - pattern: AWS_EXECUTION_ENV + - pattern: AWS_LAMBDA_FUNCTION_NAME + - pattern: AWS_LAMBDA_FUNCTION_MEMORY_SIZE + - pattern: AWS_LAMBDA_FUNCTION_VERSION + - pattern: AWS_LAMBDA_INITIALIZATION_TYPE + - pattern: AWS_LAMBDA_LOG_GROUP_NAME + - pattern: AWS_LAMBDA_LOG_STREAM_NAME + - pattern: AWS_ACCESS_KEY + - pattern: AWS_ACCESS_KEY_ID + - pattern: AWS_SECRET_ACCESS_KEY + - pattern: AWS_LAMBDA_RUNTIME_API + - pattern: LAMBDA_TASK_ROOT + - pattern: LAMBDA_RUNTIME_DIR + severity: WARNING + - id: terraform.aws.correctness.subscription-filter-missing-depends.subscription-filter-missing-depends + languages: + - hcl + message: The `aws_cloudwatch_log_subscription_filter` resource "$NAME" needs a `depends_on` clause on the `aws_lambda_permission`, otherwise Terraform may try to create these out-of-order and fail. + metadata: + category: correctness + confidence: MEDIUM + references: + - https://stackoverflow.com/questions/38407660/terraform-configuring-cloudwatch-log-subscription-delivery-to-lambda/38428834#38428834 + technology: + - aws + - terraform + - aws-lambda + - cloudwatch + patterns: + - pattern: | + resource "aws_cloudwatch_log_subscription_filter" $NAME { + ... + destination_arn = aws_lambda_function.$LAMBDA_NAME.arn + } + - pattern-not-inside: | + resource "aws_cloudwatch_log_subscription_filter" $NAME { + ... + depends_on = [..., aws_lambda_permission.$PERMISSION_NAME, ...] + } + severity: WARNING + - id: terraform.aws.security.aws-athena-client-can-disable-workgroup-encryption.aws-athena-client-can-disable-workgroup-encryption + languages: + - hcl + message: The Athena workgroup configuration can be overriden by client-side settings. The client can make changes to disable encryption settings. Enforce the configuration to prevent client overrides. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_athena_workgroup" $ANYTHING { + ... + configuration { + ... + enforce_workgroup_configuration = false + ... + result_configuration { + ... + encryption_configuration { + ... + } + ... + } + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-athena-database-unencrypted.aws-athena-database-unencrypted + languages: + - hcl + message: The Athena database is unencrypted at rest. These databases are generally derived from data in S3 buckets and should have the same level of at rest protection. The AWS KMS encryption key protects database contents. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_athena_database" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_athena_database" $ANYTHING { + ... + encryption_configuration { + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-athena-workgroup-unencrypted.aws-athena-workgroup-unencrypted + languages: + - hcl + message: The AWS Athena Work Group is unencrypted. The AWS KMS encryption key protects backups in the work group. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_athena_workgroup" $ANYTHING { + ... + configuration { + ... + result_configuration { + ... + } + ... + } + ... + } + - pattern-not-inside: | + resource "aws_athena_workgroup" $ANYTHING { + ... + configuration { + ... + result_configuration { + ... + encryption_configuration { + ... + } + ... + } + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-backup-vault-unencrypted.aws-backup-vault-unencrypted + languages: + - hcl + message: The AWS Backup vault is unencrypted. The AWS KMS encryption key protects backups in the Backup vault. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - aws + - terraform + patterns: + - pattern-not-inside: | + resource "aws_backup_vault" $BACKUP { + ... + kms_key_arn = ... + ... + } + - pattern: resource "aws_backup_vault" $BACKUP {...} + severity: WARNING + - id: terraform.aws.security.aws-cloudfront-insecure-tls.aws-insecure-cloudfront-distribution-tls-version + languages: + - hcl + message: Detected an AWS CloudFront Distribution with an insecure TLS version. TLS versions less than 1.2 are considered insecure because they can be broken. To fix this, set your `minimum_protocol_version` to `"TLSv1.2_2018", "TLSv1.2_2019" or "TLSv1.2_2021"`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_cloudfront_distribution" $ANYTHING { + ... + viewer_certificate { + ... + } + ... + } + - pattern-not-inside: | + resource "aws_cloudfront_distribution" $ANYTHING { + ... + viewer_certificate { + ... + minimum_protocol_version = "TLSv1.2_2018" + ... + } + ... + } + - pattern-not-inside: | + resource "aws_cloudfront_distribution" $ANYTHING { + ... + viewer_certificate { + ... + minimum_protocol_version = "TLSv1.2_2019" + ... + } + ... + } + - pattern-not-inside: | + resource "aws_cloudfront_distribution" $ANYTHING { + ... + viewer_certificate { + ... + minimum_protocol_version = "TLSv1.2_2021" + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-cloudtrail-encrypted-with-cmk.aws-cloudtrail-encrypted-with-cmk + languages: + - hcl + message: Ensure CloudTrail logs are encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_cloudtrail" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_cloudtrail" $ANYTHING { + ... + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-cloudwatch-log-group-no-retention.aws-cloudwatch-log-group-no-retention + languages: + - hcl + message: The AWS CloudWatch Log Group has no retention. Missing retention in log groups can cause losing important event information. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern: | + resource "aws_cloudwatch_log_group" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_cloudwatch_log_group" $ANYTHING { + ... + retention_in_days = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-cloudwatch-log-group-unencrypted.aws-cloudwatch-log-group-unencrypted + languages: + - hcl + message: By default, AWS CloudWatch Log Group is encrypted using AWS-managed keys. However, for added security, it's recommended to configure your own AWS KMS encryption key to protect your log group in CloudWatch. You can either create a new aws_kms_key resource or use the ARN of an existing key in your AWS account to do so. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: LOW + likelihood: LOW + owasp: + - A02:2021 - Cryptographic Failures + references: + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - audit + technology: + - aws + - terraform + patterns: + - pattern: | + resource "aws_cloudwatch_log_group" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_cloudwatch_log_group" $ANYTHING { + ... + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-codebuild-artifacts-unencrypted.aws-codebuild-artifacts-unencrypted + languages: + - hcl + message: The CodeBuild project artifacts are unencrypted. All artifacts produced by your CodeBuild project pipeline should be encrypted to prevent them from being read if compromised. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/codebuild_project#encryption_disabled + - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-artifacts.html + - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codebuild-project.html + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-inside: | + resource "aws_codebuild_project" "$ANYTHING" { + ... + } + - pattern: | + $ARTIFACTS { + ... + type = "$TYPE" + encryption_disabled = true + ... + } + - metavariable-regex: + metavariable: $ARTIFACTS + regex: ^(artifacts|secondary_artifacts)$ + - metavariable-regex: + metavariable: $TYPE + regex: ^(CODEPIPELINE|S3)$ + severity: WARNING + - id: terraform.aws.security.aws-codebuild-project-artifacts-unencrypted.aws-codebuild-project-artifacts-unencrypted + languages: + - hcl + message: The AWS CodeBuild Project Artifacts are unencrypted. The AWS KMS encryption key protects artifacts in the CodeBuild Projects. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - aws + - terraform + patterns: + - pattern: | + resource "aws_codebuild_project" $ANYTHING { + ... + artifacts { + ... + encryption_disabled = true + ... + } + ... + } + - pattern-not-inside: | + resource "aws_codebuild_project" $ANYTHING { + ... + artifacts { + type = "NO_ARTIFACTS" + encryption_disabled = true + } + ... + } + - pattern-not-inside: | + resource "aws_codebuild_project" $ANYTHING { + ... + artifacts { + type = "NO_ARTIFACTS" + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-codebuild-project-unencrypted.aws-codebuild-project-unencrypted + languages: + - hcl + message: The AWS CodeBuild Project is unencrypted. The AWS KMS encryption key protects projects in the CodeBuild. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern: | + resource "aws_codebuild_project" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_codebuild_project" $ANYTHING { + ... + encryption_key = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-config-aggregator-not-all-regions.aws-config-aggregator-not-all-regions + languages: + - hcl + message: The AWS configuration aggregator does not aggregate all AWS Config region. This may result in unmonitored configuration in regions that are thought to be unused. Configure the aggregator with all_regions for the source. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-778: Insufficient Logging' + impact: MEDIUM + likelihood: LOW + owasp: + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ + subcategory: + - audit + technology: + - terraform + - aws + pattern-either: + - pattern: | + resource "aws_config_configuration_aggregator" $ANYTHING { + ... + account_aggregation_source { + ... + regions = ... + ... + } + ... + } + - pattern: | + resource "aws_config_configuration_aggregator" $ANYTHING { + ... + organization_aggregation_source { + ... + regions = ... + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-db-instance-no-logging.aws-db-instance-no-logging + languages: + - hcl + message: Database instance has no logging. Missing logs can cause missing important event information. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: LOW + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern: | + resource "aws_db_instance" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_db_instance" $ANYTHING { + ... + enabled_cloudwatch_logs_exports = [$SOMETHING, ...] + ... + } + severity: WARNING + - id: terraform.aws.security.aws-docdb-encrypted-with-cmk.aws-docdb-encrypted-with-cmk + languages: + - hcl + message: Ensure DocDB is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_docdb_cluster" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_docdb_cluster" $ANYTHING { + ... + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-documentdb-auditing-disabled.aws-documentdb-auditing-disabled + languages: + - hcl + message: Auditing is not enabled for DocumentDB. To ensure that you are able to accurately audit the usage of your DocumentDB cluster, you should enable auditing and export logs to CloudWatch. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + likelihood: LOW + owasp: + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_cluster#enabled_cloudwatch_logs_exports + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_docdb_cluster" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_docdb_cluster" $ANYTHING { + ... + enabled_cloudwatch_logs_exports = [..., "audit", ...] + ... + } + severity: INFO + - id: terraform.aws.security.aws-documentdb-storage-unencrypted.aws-documentdb-storage-unencrypted + languages: + - hcl + message: The AWS DocumentDB cluster is unencrypted. The data could be read if the underlying disks are compromised. You should enable storage encryption. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_cluster#storage_encrypted + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_docdb_cluster" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_docdb_cluster" $ANYTHING { + ... + storage_encrypted = true + ... + } + severity: WARNING + - id: terraform.aws.security.aws-dynamodb-point-in-time-recovery-disabled.aws-dynamodb-point-in-time-recovery-disabled + languages: + - hcl + message: Point-in-time recovery is not enabled for the DynamoDB table. DynamoDB tables should be protected against accidental or malicious write/delete actions. By enabling point-in-time-recovery you can restore to a known point in the event of loss of data. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-221: Information Loss or Omission' + impact: LOW + likelihood: LOW + owasp: + - A09:2021 – Security Logging and Monitoring Failures + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table#point_in_time_recovery + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_dynamodb_table" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_dynamodb_table" $ANYTHING { + ... + point_in_time_recovery { + ... + enabled = true + ... + } + ... + } + severity: INFO + - id: terraform.aws.security.aws-dynamodb-table-unencrypted.aws-dynamodb-table-unencrypted + languages: + - hcl + message: By default, AWS DynamoDB Table is encrypted using AWS-managed keys. However, for added security, it's recommended to configure your own AWS KMS encryption key to protect your data in the DynamoDB table. You can either create a new aws_kms_key resource or use the ARN of an existing key in your AWS account to do so. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern: | + resource "aws_dynamodb_table" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_dynamodb_table" $ANYTHING { + ... + server_side_encryption { + enabled = true + kms_key_arn = ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ebs-snapshot-encrypted-with-cmk.aws-ebs-snapshot-encrypted-with-cmk + languages: + - hcl + message: Ensure EBS Snapshot is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_ebs_snapshot_copy" $ANYTHING { + ... + encrypted = true + ... + } + - pattern-not-inside: | + resource "aws_ebs_snapshot_copy" $ANYTHING { + ... + encrypted = true + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ebs-unencrypted.aws-ebs-unencrypted + languages: + - hcl + message: The AWS EBS is unencrypted. The AWS EBS encryption protects data in the EBS. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern: | + resource "aws_ebs_encryption_by_default" $ANYTHING { + ... + enabled = false + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ebs-volume-encrypted-with-cmk.aws-ebs-volume-encrypted-with-cmk + languages: + - hcl + message: Ensure EBS Volume is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_ebs_volume" $ANYTHING { + ... + encrypted = true + ... + } + - pattern-not-inside: | + resource "aws_ebs_volume" $ANYTHING { + ... + encrypted = true + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ebs-volume-unencrypted.aws-ebs-volume-unencrypted + languages: + - hcl + message: The AWS EBS volume is unencrypted. The volume, the disk I/O and any derived snapshots could be read if compromised. Volumes should be encrypted to ensure sensitive data is stored securely. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume#encrypted + - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_ebs_volume" $ANYTHING { + ... + } + - pattern-not: | + resource "aws_ebs_volume" $ANYTHING { + ... + encrypted = true + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ec2-has-public-ip.aws-ec2-has-public-ip + languages: + - hcl + message: EC2 instances should not have a public IP address attached in order to block public access to the instances. To fix this, set your `associate_public_ip_address` to `"false"`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-284: Improper Access Control' + impact: MEDIUM + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - terraform + - aws + patterns: + - pattern-either: + - pattern: | + resource "aws_instance" $ANYTHING { + ... + associate_public_ip_address = true + ... + } + - pattern: | + resource "aws_launch_template" $ANYTHING { + ... + network_interfaces { + ... + associate_public_ip_address = true + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ec2-launch-configuration-ebs-block-device-unencrypted.aws-ec2-launch-configuration-ebs-block-device-unencrypted + languages: + - hcl + message: The AWS launch configuration EBS block device is unencrypted. The block device could be read if compromised. Block devices should be encrypted to ensure sensitive data is held securely at rest. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration#block-devices + - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html + rule-origin-note: published from /src/aws-ec2-launch-configuration-block-device-unencrypted.yml in None + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-inside: | + resource "aws_launch_configuration" $ANYTHING { + ... + } + - pattern: | + ebs_block_device { + ... + } + - pattern-not: | + ebs_block_device { + ... + encrypted = true + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ec2-launch-configuration-root-block-device-unencrypted.aws-ec2-launch-configuration-root-block-device-unencrypted + languages: + - hcl + message: The AWS launch configuration root block device is unencrypted. The block device could be read if compromised. Block devices should be encrypted to ensure sensitive data is held securely at rest. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration#block-devices + - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html + rule-origin-note: published from /src/aws-ec2-launch-configuration-block-device-unencrypted.yml in None + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_launch_configuration" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_launch_configuration" $ANYTHING { + ... + root_block_device { + ... + encrypted = true + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ec2-launch-template-metadata-service-v1-enabled.aws-ec2-launch-template-metadata-service-v1-enabled + languages: + - hcl + message: The EC2 launch template has Instance Metadata Service Version 1 (IMDSv1) enabled. IMDSv2 introduced session authentication tokens which improve security when talking to IMDS. You should either disable IMDS or require the use of IMDSv2. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1390: Weak Authentication' + impact: HIGH + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration#metadata_options + - https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_launch_template" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_launch_template" $ANYTHING { + ... + metadata_options { + ... + http_endpoint = "disabled" + ... + } + ... + } + - pattern-not-inside: | + resource "aws_launch_template" $ANYTHING { + ... + metadata_options { + ... + http_tokens = "required" + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ec2-security-group-allows-public-ingress.aws-ec2-security-group-allows-public-ingress + languages: + - hcl + message: The security group rule allows ingress from public internet. Opening up ports to the public internet is potentially dangerous. You should restrict access to IP addresses or ranges that explicitly require it where possible. Set a more restrictive CIDR range. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule#cidr_blocks + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule#cidr_ipv4 + - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-rules-reference.html + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: + - pattern: | + resource "aws_security_group_rule" $ANYTHING { + ... + type = "ingress" + cidr_blocks = [..., "$PUBLIC_IPV4_CIDR", ...] + ... + } + - pattern: | + resource "aws_vpc_security_group_ingress_rule" $ANYTHING { + ... + cidr_ipv4 = "$PUBLIC_IPV4_CIDR" + ... + } + - patterns: + - pattern-inside: | + resource "aws_security_group" $ANYTHING { + ... + } + - pattern: | + ingress { + ... + cidr_blocks = [..., "$PUBLIC_IPV4_CIDR", ...] + ... + } + - metavariable-pattern: + language: generic + metavariable: $PUBLIC_IPV4_CIDR + patterns: + - pattern-not-regex: ^127\.\d{1,3}\.\d{1,3}\.\d{1,3}/(8|9|[1-3][0-9])$ + - pattern-not-regex: ^10\.\d{1,3}\.\d{1,3}\.\d{1,3}/(8|9|[1-3][0-9])$ + - pattern-not-regex: ^172\.(1[6-9]|2[0-9]|3[01])\.\d{1,3}\.\d{1,3}/(1[2-9]|[23][0-9])$ + - pattern-not-regex: ^192\.168\.\d{1,3}\.\d{1,3}/(1[6-9]|[23][0-9])$ + - pattern-not-regex: ^169\.254\.\d{1,3}\.\d{1,3}/(1[6-9]|[23][0-9])$ + - pattern-not-regex: ^100\.(6[4-9]|[7-9][0-9]|1[01][0-9]|12[0-7])\.\d{1,3}\.\d{1,3}/[1-3][0-9]$ + - pattern-not-regex: ^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/32$ + severity: WARNING + - id: terraform.aws.security.aws-ec2-security-group-rule-missing-description.aws-ec2-security-group-rule-missing-description + languages: + - hcl + message: The AWS security group rule is missing a description, or its description is empty or the default value. Security groups rules should include a meaningful description in order to simplify auditing, debugging, and managing security groups. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-223: Omission of Security-relevant Information' + impact: LOW + likelihood: LOW + owasp: + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://shisho.dev/dojo/providers/aws/Amazon_EC2/aws-security-group/#:~:text=Ensure%20to%20keep%20the%20description%20of%20your%20security%20group%20up%2Dto%2Ddate + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group#description + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + resource "aws_security_group" $ANYTHING { + ... + $INGRESS { + ... + description = $DESCR + ... + } + ... + } + - metavariable-regex: + metavariable: $INGRESS + regex: ^(ingress|egress)$ + - patterns: + - pattern-inside: | + resource "$SECGROUP" $ANYTHING { + ... + description = $DESCR + ... + } + - metavariable-regex: + metavariable: $SECGROUP + regex: ^(aws_security_group_rule|aws_security_group)$ + - metavariable-regex: + metavariable: $DESCR + regex: ^(['\"]['\"]|['\"]Managed by Terraform['\"])$ + - focus-metavariable: $DESCR + - patterns: + - metavariable-regex: + metavariable: $INGRESS + regex: ^(ingress|egress)$ + - pattern: | + resource "aws_security_group" $ANYTHING { + ... + $INGRESS { + ... + } + ... + } + - pattern-not: | + resource "aws_security_group" $ANYTHING { + ... + $INGRESS { + ... + description = ... + ... + } + ... + } + - patterns: + - metavariable-regex: + metavariable: $SECGROUP + regex: ^(aws_security_group_rule|aws_security_group)$ + - pattern: | + resource "$SECGROUP" $ANYTHING { + ... + } + - pattern-not: | + resource "$SECGROUP" $ANYTHING { + ... + description = ... + ... + } + severity: INFO + - id: terraform.aws.security.aws-ecr-image-scanning-disabled.aws-ecr-image-scanning-disabled + languages: + - hcl + message: The ECR repository has image scans disabled. Repository image scans should be enabled to ensure vulnerable software can be discovered and remediated as soon as possible. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-223: Omission of Security-relevant Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository#image_scanning_configuration + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_ecr_repository" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_ecr_repository" $ANYTHING { + ... + image_scanning_configuration { + ... + scan_on_push = true + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ecr-mutable-image-tags.aws-ecr-mutable-image-tags + languages: + - hcl + message: The ECR repository allows tag mutability. Image tags could be overwritten with compromised images. ECR images should be set to IMMUTABLE to prevent code injection through image mutation. This can be done by setting `image_tag_mutability` to IMMUTABLE. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-345: Insufficient Verification of Data Authenticity' + impact: HIGH + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository#image_tag_mutability + - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/ + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_ecr_repository" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_ecr_repository" $ANYTHING { + ... + image_tag_mutability = "IMMUTABLE" + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ecr-repository-wildcard-principal.aws-ecr-repository-wildcard-principal + languages: + - hcl + message: Detected wildcard access granted in your ECR repository policy principal. This grants access to all users, including anonymous users (public access). Instead, limit principals, actions and resources to what you need according to least privilege. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository_policy + - https://docs.aws.amazon.com/lambda/latest/operatorguide/wildcard-permissions-iam.html + - https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/monitor-amazon-ecr-repositories-for-wildcard-permissions-using-aws-cloudformation-and-aws-config.html + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern-inside: | + resource "aws_ecr_repository_policy" $ANYTHING { + ... + } + - pattern-either: + - patterns: + - pattern: policy = "$JSONPOLICY" + - metavariable-pattern: + language: json + metavariable: $JSONPOLICY + patterns: + - pattern-not-inside: | + {..., "Effect": "Deny", ...} + - pattern-either: + - pattern: | + {..., "Principal": "*", ...} + - pattern: | + {..., "Principal": [..., "*", ...], ...} + - pattern: | + {..., "Principal": { "AWS": "*" }, ...} + - pattern: | + {..., "Principal": { "AWS": [..., "*", ...] }, ...} + - patterns: + - pattern-inside: policy = jsonencode(...) + - pattern-not-inside: | + {..., Effect = "Deny", ...} + - pattern-either: + - pattern: | + {..., Principal = "*", ...} + - pattern: | + {..., Principal = [..., "*", ...], ...} + - pattern: | + {..., Principal = { AWS = "*" }, ...} + - pattern: | + {..., Principal = { AWS = [..., "*", ...] }, ...} + severity: WARNING + - id: terraform.aws.security.aws-efs-filesystem-encrypted-with-cmk.aws-efs-filesystem-encrypted-with-cmk + languages: + - hcl + message: Ensure EFS filesystem is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_efs_file_system" $ANYTHING { + ... + encrypted = true + ... + } + - pattern-not-inside: | + resource "aws_efs_file_system" $ANYTHING { + ... + encrypted = true + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-elasticsearch-insecure-tls-version.aws-elasticsearch-insecure-tls-version + languages: + - terraform + message: Detected an AWS Elasticsearch domain using an insecure version of TLS. To fix this, set "tls_security_policy" equal to "Policy-Min-TLS-1-2-2019-07". + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform + pattern: | + resource "aws_elasticsearch_domain" $ANYTHING { + ... + domain_endpoint_options { + ... + enforce_https = true + tls_security_policy = "Policy-Min-TLS-1-0-2019-07" + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-elasticsearch-nodetonode-encryption.aws-elasticsearch-nodetonode-encryption-not-enabled + languages: + - hcl + message: "Ensure all Elasticsearch has node-to-node encryption enabled.\t" + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - aws + patterns: + - pattern-either: + - pattern: | + resource "aws_elasticsearch_domain" $ANYTHING { + ... + node_to_node_encryption { + ... + enabled = false + ... + } + ... + } + - pattern: | + resource "aws_elasticsearch_domain" $ANYTHING { + ... + cluster_config { + ... + instance_count = $COUNT + ... + } + } + - pattern-not-inside: | + resource "aws_elasticsearch_domain" $ANYTHING { + ... + cluster_config { + ... + instance_count = $COUNT + ... + } + node_to_node_encryption { + ... + enabled = true + ... + } + } + - metavariable-comparison: + comparison: $COUNT > 1 + metavariable: $COUNT + severity: WARNING + - id: terraform.aws.security.aws-elb-access-logs-not-enabled.aws-elb-access-logs-not-enabled + languages: + - hcl + message: ELB has no logging. Missing logs can cause missing important event information. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - aws + - terraform + patterns: + - pattern-either: + - pattern: | + resource "aws_lb" $ANYTHING { + ... + } + - pattern: | + resource "aws_alb" $ANYTHING { + ... + } + - pattern-not-inside: | + resource $ANYLB $ANYTHING { + ... + access_logs { + ... + enabled = true + ... + } + ... + } + - pattern-not-inside: "resource $ANYLB $ANYTHING {\n ...\n subnet_mapping {\n ...\n }\n ...\n} \n" + severity: WARNING + - id: terraform.aws.security.aws-emr-encrypted-with-cmk.aws-emr-encrypted-with-cmk + languages: + - hcl + message: Ensure EMR is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-inside: | + resource "aws_emr_security_configuration" $ANYTHING { + ... + } + - pattern: configuration = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-not-inside: | + "AwsKmsKey": ... + severity: WARNING + - id: terraform.aws.security.aws-fsx-lustre-files-ystem.aws-fsx-lustre-filesystem-encrypted-with-cmk + languages: + - hcl + message: Ensure FSX Lustre file system is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_fsx_lustre_file_system" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_fsx_lustre_file_system" $ANYTHING { + ... + kms_key_id = ... + ... + } + - pattern-regex: (^aws_kms_key\.(.*)) + severity: WARNING + - id: terraform.aws.security.aws-fsx-lustre-filesystem-encrypted-with-cmk.aws-fsx-lustre-filesystem-encrypted-with-cmk + languages: + - hcl + message: Ensure FSX Lustre file system is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_fsx_lustre_file_system" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_fsx_lustre_file_system" $ANYTHING { + ... + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-fsx-ontapfs-encrypted-with-cmk.aws-fsx-ontapfs-encrypted-with-cmk + languages: + - hcl + message: Ensure FSX ONTAP file system is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_fsx_ontap_file_system" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_fsx_ontap_file_system" $ANYTHING { + ... + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-fsx-windows-encrypted-with-cmk.aws-fsx-windows-encrypted-with-cmk + languages: + - hcl + message: Ensure FSX Windows file system is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_fsx_windows_file_system" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_fsx_windows_file_system" $ANYTHING { + ... + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-glacier-vault-any-principal.aws-glacier-vault-any-principal + languages: + - hcl + message: 'Detected wildcard access granted to Glacier Vault. This means anyone within your AWS account ID can perform actions on Glacier resources. Instead, limit to a specific identity in your account, like this: `arn:aws:iam:::`.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - vuln + technology: + - aws + patterns: + - pattern-inside: | + resource "aws_glacier_vault" $ANYTHING { + ... + } + - pattern: access_policy = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-inside: | + {..., "Effect": "Allow", ...} + - pattern-either: + - pattern: | + "Principal": "*" + - pattern: | + "Principal": {..., "AWS": "*", ...} + - pattern-inside: | + "Principal": {..., "AWS": ..., ...} + - pattern-regex: | + (^\"arn:aws:iam::\*:(.*)\"$) + severity: ERROR + - id: terraform.aws.security.aws-iam-admin-policy-ssoadmin.aws-iam-admin-policy-ssoadmin + languages: + - hcl + message: Detected admin access granted in your policy. This means anyone with this policy can perform administrative actions. Instead, limit actions and resources to what you need according to least privilege. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - vuln + technology: + - aws + patterns: + - pattern-inside: | + resource "aws_ssoadmin_permission_set_inline_policy" $ANYTHING { + ... + } + - pattern: inline_policy = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-not-inside: | + {..., "Effect": "Deny", ...} + - pattern-either: + - pattern: | + {..., "Action": [..., "*", ...], "Resource": [..., "*", ...], ...} + - pattern: | + {..., "Action": "*", "Resource": "*", ...} + - pattern: | + {..., "Action": "*", "Resource": [...], ...} + - pattern: | + {..., "Action": [...], "Resource": "*", ...} + severity: ERROR + - id: terraform.aws.security.aws-iam-admin-policy.aws-iam-admin-policy + languages: + - hcl + message: Detected admin access granted in your policy. This means anyone with this policy can perform administrative actions. Instead, limit actions and resources to what you need according to least privilege. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern-inside: | + resource "aws_iam_policy" $ANYTHING { + ... + } + - pattern: policy = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-not-inside: | + {..., "Effect": "Deny", ...} + - pattern-either: + - pattern: | + {..., "Action": [..., "*", ...], "Resource": [..., "*", ...], ...} + - pattern: | + {..., "Action": "*", "Resource": "*", ...} + - pattern: | + {..., "Action": "*", "Resource": [...], ...} + - pattern: | + {..., "Action": [...], "Resource": "*", ...} + severity: ERROR + - id: terraform.aws.security.aws-imagebuilder-component-encrypted-with-cmk.aws-imagebuilder-component-encrypted-with-cmk + languages: + - hcl + message: Ensure ImageBuilder component is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_imagebuilder_component" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_imagebuilder_component" $ANYTHING { + ... + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-insecure-api-gateway-tls-version.aws-insecure-api-gateway-tls-version + languages: + - terraform + message: Detected AWS API Gateway to be using an insecure version of TLS. To fix this issue make sure to set "security_policy" equal to "TLS_1_2". + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern-either: + - pattern: | + resource "aws_api_gateway_domain_name" $ANYTHING { + ... + security_policy = "..." + ... + } + - pattern: | + resource "aws_apigatewayv2_domain_name" $ANYTHING { + ... + domain_name_configuration {...} + ... + } + - pattern-not: | + resource "aws_api_gateway_domain_name" $ANYTHING { + ... + security_policy = "TLS_1_2" + ... + } + - pattern-not: | + resource "aws_apigatewayv2_domain_name" $ANYTHING { + ... + domain_name_configuration { + ... + security_policy = "TLS_1_2" + ... + } + } + severity: WARNING + - id: terraform.aws.security.aws-insecure-redshift-ssl-configuration.aws-insecure-redshift-ssl-configuration + languages: + - hcl + message: Detected an AWS Redshift configuration with a SSL disabled. To fix this, set your `require_ssl` to `"true"`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_redshift_parameter_group" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_redshift_parameter_group" $ANYTHING { + ... + parameter { + name = "require_ssl" + value = "true" + } + ... + } + - pattern-not-inside: | + resource "aws_redshift_parameter_group" $ANYTHING { + ... + parameter { + name = "require_ssl" + value = true + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-kinesis-stream-encrypted-with-cmk.aws-kinesis-stream-encrypted-with-cmk + languages: + - hcl + message: Ensure Kinesis stream is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_kinesis_stream" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_kinesis_stream" $ANYTHING { + ... + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-kinesis-stream-unencrypted.aws-kinesis-stream-unencrypted + languages: + - hcl + message: The AWS Kinesis stream does not encrypt data at rest. The data could be read if the Kinesis stream storage layer is compromised. Enable Kinesis stream server-side encryption. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kinesis_stream#encryption_type + - https://docs.aws.amazon.com/streams/latest/dev/server-side-encryption.html + rule-origin-note: published from /src/aws-kinesis-stream-unencrypted.yml in None + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_kinesis_stream" $ANYTHING { + ... + } + - pattern-not: | + resource "aws_kinesis_stream" $ANYTHING { + ... + encryption_type = "KMS" + ... + } + severity: WARNING + - id: terraform.aws.security.aws-kinesis-video-stream-encrypted-with-cmk.aws-kinesis-video-stream-encrypted-with-cmk + languages: + - hcl + message: Ensure Kinesis video stream is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource "aws_kinesis_video_stream" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_kinesis_video_stream" $ANYTHING { + ... + kms_key_id = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-kms-key-wildcard-principal.aws-kms-key-wildcard-principal + languages: + - hcl + message: Detected wildcard access granted in your KMS key. This means anyone with this policy can perform administrative actions over the keys. Instead, limit principals, actions and resources to what you need according to least privilege. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern-inside: | + resource "aws_kms_key" $ANYTHING { + ... + } + - pattern: policy = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-not-inside: | + {..., "Effect": "Deny", ...} + - pattern-either: + - pattern: | + {..., "Principal": "*", "Action": "kms:*", "Resource": "*", ...} + - pattern: | + {..., "Principal": [..., "*", ...], "Action": "kms:*", "Resource": "*", ...} + - pattern: | + {..., "Principal": { "AWS": "*" }, "Action": "kms:*", "Resource": "*", ...} + - pattern: | + {..., "Principal": { "AWS": [..., "*", ...] }, "Action": "kms:*", "Resource": "*", ...} + severity: ERROR + - id: terraform.aws.security.aws-kms-no-rotation.aws-kms-no-rotation + languages: + - hcl + message: The AWS KMS has no rotation. Missing rotation can cause leaked key to be used by attackers. To fix this, set a `enable_key_rotation`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern-either: + - pattern: | + resource "aws_kms_key" $ANYTHING { + ... + enable_key_rotation = false + ... + } + - pattern: | + resource "aws_kms_key" $ANYTHING { + ... + customer_master_key_spec = "SYMMETRIC_DEFAULT" + enable_key_rotation = false + ... + } + - pattern: | + resource "aws_kms_key" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_kms_key" $ANYTHING { + ... + enable_key_rotation = true + ... + } + - pattern-not-inside: | + resource "aws_kms_key" $ANYTHING { + ... + customer_master_key_spec = "RSA_2096" + ... + } + severity: WARNING + - id: terraform.aws.security.aws-lambda-environment-credentials.aws-lambda-environment-credentials + languages: + - hcl + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: HIGH + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + subcategory: + - vuln + technology: + - aws + - terraform + - secrets + patterns: + - pattern-inside: | + resource "$ANYTING" $ANYTHING { + ... + environment { + variables = { + ... + } + } + ... + } + - pattern-either: + - pattern-inside: | + AWS_ACCESS_KEY_ID = "$Y" + - pattern-regex: | + (?:root`.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A06:2017 - Security Misconfiguration + - A05:2021 - Security Misconfiguration + references: + - https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/ + subcategory: + - vuln + technology: + - aws + patterns: + - pattern-inside: | + resource "aws_iam_role" $NAME { + ... + } + - pattern: assume_role_policy = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-inside: | + {..., "Effect": "Allow", ..., "Action": "sts:AssumeRole", ...} + - pattern: | + "Principal": {..., "AWS": "*", ...} + severity: ERROR + - id: terraform.azure.best-practice.azure-ad-used-auth-service-fabric.azure-ad-used-auth-service-fabric + languages: + - hcl + message: "Ensures that Active Directory is used for authentication for Service Fabric\t" + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_service_fabric_cluster" "..." { + ... + azure_active_directory { + tenant_id = "..." + } + ... + } + - pattern-inside: | + resource "azurerm_service_fabric_cluster" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-aks-uses-azure-policies-addon.azure-aks-uses-azure-policies-addon + languages: + - hcl + message: Ensure that AKS uses Azure Policies Add-on + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_kubernetes_cluster" "..." { + ... + addon_profile { + azure_policy { + enabled = true + } + } + ... + } + - pattern-inside: | + resource "azurerm_kubernetes_cluster" "..." { + ... + } + severity: INFO + - id: terraform.azure.best-practice.azure-appgateway-enables-waf.azure-appgateway-enables-waf + languages: + - hcl + message: Ensure that Application Gateway enables WAF + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_application_gateway" "..." { + ... + waf_configuration { + enabled = true + } + ... + } + - pattern-inside: | + resource "azurerm_application_gateway" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-appservice-dotnet-framework-version.azure-appservice-dotnet-framework-version + languages: + - hcl + message: Ensure that Net Framework version is the latest, if used as a part of the web app + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + site_config { + ... + dotnet_framework_version = "v6.0" + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: INFO + - id: terraform.azure.best-practice.azure-appservice-ftps-state.azure-appservice-ftps-state + languages: + - hcl + message: Ensure FTP deployments are disabled + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + site_config { + ftps_state = "FtpsOnly" + } + ... + } + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + site_config { + ftps_state = "Disabled" + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-appservice-https-20-enabled.azure-appservice-https-20-enabled + languages: + - hcl + message: Ensure that HTTP Version is the latest if used to run the web app + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + site_config { + http2_enabled = true + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-appservice-java-version.azure-appservice-java-version + languages: + - hcl + message: Ensure that Java version is the latest, if used to run the web app + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + site_config { + ... + java_version = "11" + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: INFO + - id: terraform.azure.best-practice.azure-appservice-php-version.azure-appservice-php-version + languages: + - hcl + message: Ensure that PHP version is the latest, if used to run the web app + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + site_config { + ... + php_version = "7.4" + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: INFO + - id: terraform.azure.best-practice.azure-appservice-python-version.azure-appservice-python-version + languages: + - hcl + message: Ensure that Python version is the latest, if used to run the web app + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + site_config { + ... + python_version = "3.10" + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: INFO + - id: terraform.azure.best-practice.azure-appservice-used-azure-files.azure-appservice-used-azure-files + languages: + - hcl + message: Ensure that app services use Azure Files + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + storage_account { + ... + type = "AzureFiles" + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: INFO + - id: terraform.azure.best-practice.azure-defenderon-appservices.azure-defenderon-appservices + languages: + - hcl + message: Ensure that Azure Defender is set to On for App Service + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Standard" + resource_type = "AppServices" + ... + } + - pattern-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Free" + resource_type = "AppServices" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-defenderon-container-registry.azure-defenderon-container-registry + languages: + - hcl + message: Ensure that Azure Defender is set to On for Container + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Standard" + resource_type = "ContainerRegistry" + ... + } + - pattern-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Free" + resource_type = "ContainerRegistry" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-defenderon-keyvaults.azure-defenderon-keyvaults + languages: + - hcl + message: Ensure that Azure Defender is set to On for Key Vault + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Standard" + resource_type = "KeyVaults" + ... + } + - pattern-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Free" + resource_type = "KeyVaults" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-defenderon-kubernetes.azure-defenderon-kubernetes + languages: + - hcl + message: Ensure that Azure Defender is set to On for Kubernetes + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Standard" + resource_type = "KubernetesService" + ... + } + - pattern-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Free" + resource_type = "KubernetesService" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-defenderon-servers.azure-defenderon-servers + languages: + - hcl + message: Ensure that Azure Defender is set to On for Servers + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Standard" + resource_type = "VirtualMachines" + ... + } + - pattern-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Free" + resource_type = "VirtualMachines" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-defenderon-sqlservers-vms.azure-defenderon-sqlservers-vms + languages: + - hcl + message: Ensure that Azure Defender is set to On for SQL servers on machines + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Standard" + resource_type = "SqlServerVirtualMachines" + ... + } + - pattern-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Free" + resource_type = "SqlServerVirtualMachines" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-defenderon-sqlservers.azure-defenderon-sqlservers + languages: + - hcl + message: Ensure that Azure Defender is set to On for SQL servers + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Standard" + resource_type = "SqlServers" + ... + } + - pattern-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Free" + resource_type = "SqlServers" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-defenderon-storage.azure-defenderon-storage + languages: + - hcl + message: Ensure that Azure Defender is set to On for Storage + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Standard" + resource_type = "StorageAccounts" + ... + } + - pattern-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Free" + resource_type = "StorageAccounts" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-frontdoor-enables-waf.azure-frontdoor-enables-waf + languages: + - hcl + message: Ensure that Azure Front Door enables WAF + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_frontdoor" "..." { + ... + web_application_firewall_policy_link_id = "..." + ... + } + - pattern-inside: | + resource "azurerm_frontdoor" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-frontdoor-use-wafmode.azure-frontdoor-use-wafmode + languages: + - hcl + message: Ensure that Azure Front Door uses WAF and configured in “Detection” or “Prevention” modes + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_frontdoor_firewall_policy" "..." { + ... + policy_settings { + ... + enabled = false + ... + } + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-functionapp-http-version-latest.azure-functionapp-http-version-latest + languages: + - hcl + message: Ensure that HTTP Version is the latest if used to run the Function app + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_function_app" "..." { + ... + site_config { + ... + http2_enabled = true + ... + } + ... + } + - pattern-inside: | + resource "azurerm_function_app" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-functionapps-accessible-over-https.azure-functionapps-accessible-over-https + languages: + - hcl + message: Ensure that HTTP Version is the latest if used to run the Function app + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + https_only = true + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-keyvault-enables-firewall-rules-settings.azure-keyvault-enables-firewall-rules-settings + languages: + - hcl + message: Ensure that key vault allows firewall rules settings + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault" "..." { + ... + network_acls { + ... + default_action = "Deny" + ... + } + ... + } + - pattern-inside: | + resource "azurerm_key_vault" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-keyvault-enables-purge-protection.azure-keyvault-enables-purge-protection + languages: + - hcl + message: Ensure that key vault enables purge protection + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault" "..." { + ... + purge_protection_enabled = true + } + - pattern-inside: | + resource "azurerm_key_vault" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-keyvault-enables-soft-delete.azure-keyvault-enables-soft-delete + languages: + - hcl + message: Ensure that key vault enables soft delete + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_key_vault" "..." { + ... + soft_delete_enabled = false + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-keyvault-recovery-enabled.azure-keyvault-recovery-enabled + languages: + - hcl + message: Ensure the key vault is recoverable https://docs.bridgecrew.io/docs/ensure-the-key-vault-is-recoverable + metadata: + category: best-practice + references: + - https://docs.bridgecrew.io/docs/ensure-the-key-vault-is-recoverable + technology: + - terraform + - azure + patterns: + - pattern: | + resource "azurerm_key_vault" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_key_vault" "..." { + ... + purge_protection_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-mariadb-geo-backup-enabled.azure-mariadb-geo-backup-enabled + languages: + - hcl + message: Ensure that MariaDB server enables geo-redundant backups + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_mariadb_server" "..." { + ... + geo_redundant_backup_enabled = true + ... + } + - pattern-inside: | + resource "azurerm_mariadb_server" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-mariadb-sslenforcement-enabled.azure-mariadb-sslenforcement-enabled + languages: + - hcl + message: Ensure Enforce SSL connection is set to Enabled for MariaDB servers + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_mariadb_server" "..." { + ... + ssl_enforcement_enabled = true + ... + } + - pattern-inside: | + resource "azurerm_mariadb_server" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-monitor-log-profile-categories.azure-monitor-log-profile-categories + languages: + - hcl + message: Ensure audit profile captures all the activities + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_monitor_log_profile" "..." { + ... + categories = [ + "Action", + "Delete", + "Write", + ] + ... + } + - pattern-inside: | + resource "azurerm_monitor_log_profile" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-monitor-log-profile-retention-days.azure-monitor-log-profile-retention-days + languages: + - hcl + message: Ensure that Activity Log Retention is set 365 days or greater + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_monitor_log_profile" "..." { + ... + retention_policy { + ... + enabled = true + days = 365 + ... + } + ... + } + - pattern-not-inside: | + resource "azurerm_monitor_log_profile" "..." { + ... + retention_policy { + ... + enabled = false + days = 0 + ... + } + ... + } + - pattern-inside: | + resource "azurerm_monitor_log_profile" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-mysql-geo-backup-enabled.azure-mysql-geo-backup-enabled + languages: + - hcl + message: Ensure that MySQL server enables geo-redundant backups + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mysql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mysql_server" "..." { + ... + geo_redundant_backup_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-mysql-server-tlsenforcement-enabled.azure-mysql-server-tlsenforcement-enabled + languages: + - hcl + message: Ensure Enforce SSL connection is set to Enabled for MySQL servers + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mysql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mysql_server" "..." { + ... + ssl_enforcement_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-mysql-threat-detection-enabled.azure-mysql-threat-detection-enabled + languages: + - hcl + message: Ensure that MySQL server enables Threat detection policy + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mysql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mysql_server" "..." { + ... + threat_detection_policy { + ... + enabled = true + ... + } + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-networkinterface-enable-ip-forwarding.azure-networkinterface-enable-ip-forwarding + languages: + - hcl + message: Ensure that Network Interfaces disable IP forwarding + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_network_interface" "..." { + ... + enable_ip_forwarding = true + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-postgresql-flexi-server-geo-backup-enabled.azure-postgresql-flexi-server-geo-backup-enabled + languages: + - hcl + message: Ensure that PostgreSQL Flexible server enables geo-redundant backups + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_postgresql_flexible_server" "..." { + ... + geo_redundant_backup_enabled = true + ... + } + - pattern-inside: | + resource "azurerm_postgresql_flexible_server" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-postgresql-geo-backup-enabled.azure-postgresql-geo-backup-enabled + languages: + - hcl + message: Ensure that PostgreSQL server enables geo-redundant backups + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_postgresql_server" "..." { + ... + geo_redundant_backup_enabled = true + ... + } + - pattern-inside: | + resource "azurerm_postgresql_server" "..." { + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-postgresql-server-connection-throttling-enabled.azure-postgresql-server-connection-throttling-enabled + languages: + - hcl + message: Ensure server parameter connection_throttling is set to ON for PostgreSQL Database Server + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_postgresql_configuration" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_postgresql_configuration" "..." { + ... + name = "connection_throttling" + value = "on" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-postgresql-server-log-checkpoint-enabled.azure-postgresql-server-log-checkpoint-enabled + languages: + - hcl + message: Ensure server parameter log_checkpoints is set to ON for PostgreSQL Database Server + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_postgresql_configuration" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_postgresql_configuration" "..." { + ... + name = "log_checkpoints" + value = "on" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-postgresql-server-log-connections-enabled.azure-postgresql-server-log-connections-enabled + languages: + - hcl + message: Ensure server parameter log_connections is set to ON for PostgreSQL Database Server + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_postgresql_configuration" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_postgresql_configuration" "..." { + ... + name = "log_connections" + value = "on" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-postgresql-ssl-enforcement-enabled.azure-postgresql-ssl-enforcement-enabled + languages: + - hcl + message: Ensure Enforce SSL connection is set to Enabled for PostgreSQL servers + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_postgresql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_postgresql_server" "..." { + ... + ssl_enforcement_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-postgresql-threat-detection-enabled.azure-postgresql-threat-detection-enabled + languages: + - hcl + message: Ensure that PostgreSQL server enables Threat detection policy + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_postgresql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_postgresql_server" "..." { + ... + threat_detection_policy { + ... + enabled = true + ... + } + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-secret-content-type.azure-secret-content-type + languages: + - hcl + message: Ensure that key vault secrets have “content_type” set + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_key_vault_secret" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_key_vault_secret" "..." { + ... + content_type = "..." + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-secret-expiration-date.azure-secret-expiration-date + languages: + - hcl + message: Ensure that the expiration date is set on all secrets + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_key_vault_secret" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_key_vault_secret" "..." { + ... + expiration_date = "..." + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-securitcenter-email-alert.azure-securitcenter-email-alert + languages: + - hcl + message: Ensure that Send email notification for high severity alerts is set to On + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_security_center_contact" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_security_center_contact" "..." { + ... + alert_notifications = true + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-securitycenter-contact-emails.azure-securitycenter-contact-emails + languages: + - hcl + message: Ensure that Security contact emails is set + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_security_center_contact" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_security_center_contact" "..." { + ... + email = "..." + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-securitycenter-contact-phone.azure-securitycenter-contact-phone + languages: + - hcl + message: Ensure that Security contact Phone number is set + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_security_center_contact" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_security_center_contact" "..." { + ... + phone = "..." + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-securitycenter-email-alert-admins.azure-securitycenter-email-alert-admins + languages: + - hcl + message: Ensure that Send email notification for high severity alerts is set to On + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_security_center_contact" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_security_center_contact" "..." { + ... + alerts_to_admins = true + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-securitycenter-standard-pricing.azure-securitycenter-standard-pricing + languages: + - hcl + message: Ensure that standard pricing tier is selected + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_security_center_subscription_pricing" "..." { + ... + tier = "Standard" + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-sqlserver-email-alerts-enabled.azure-sqlserver-email-alerts-enabled + languages: + - hcl + message: Ensure that Send Alerts To is enabled for MSSQL servers + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mssql_server_security_alert_policy" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mssql_server_security_alert_policy" "..." { + ... + state = "Enabled" + email_addresses = ["...", ...] + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-sqlserver-email-alerts-toadmins-enabled.azure-sqlserver-email-alerts-toadmins-enabled + languages: + - hcl + message: Ensure that Email service and co-administrators is Enabled for MSSQL servers + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mssql_server_security_alert_policy" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mssql_server_security_alert_policy" "..." { + ... + state = "Enabled" + email_account_admins = true + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-sqlserver-threat-detection-types.azure-sqlserver-threat-detection-types + languages: + - hcl + message: Ensure that Threat Detection types is set to All + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mssql_server_security_alert_policy" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mssql_server_security_alert_policy" "..." { + ... + state = "Enabled" + disabled_alerts = [] + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-storage-account-enables-secure-transfer.azure-storage-account-enables-secure-transfer + languages: + - hcl + message: Ensure that storage account enables secure transfer + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + enable_https_traffic_only = false + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-synapse-workscape-enables-managed-virtual-network.azure-synapse-workscape-enables-managed-virtual-network + languages: + - hcl + message: Ensure that Azure Synapse workspaces enables managed virtual networks + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_synapse_workspace" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_synapse_workspace" "..." { + ... + managed_virtual_network_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-vmscale-sets-auto-os-image-patching-enabled.azure-vmscale-sets-auto-os-image-patching-enabled + languages: + - hcl + message: Ensure that automatic OS image patching is enabled for Virtual Machine Scale Sets + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_virtual_machine_scale_set" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_virtual_machine_scale_set" "..." { + ... + automatic_os_upgrade = true + os_profile_windows_config { + ... + enable_automatic_upgrades = true + ... + } + ... + } + severity: WARNING + - id: terraform.azure.best-practice.azure-waf-specificed-mode-app-gw.azure-waf-specificed-mode-app-gw + languages: + - hcl + message: Ensure that Application Gateway uses WAF in “Detection” or “Prevention” modes + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_web_application_firewall_policy" "..." { + ... + policy_settings { + enabled = false + } + ... + } + severity: WARNING + - id: terraform.azure.security.aks.azure-aks-apiserver-auth-ip-ranges.azure-aks-apiserver-auth-ip-ranges + languages: + - hcl + message: "Ensure AKS has an API Server Authorized IP Ranges enabled\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_kubernetes_cluster" "..." { + ... + api_server_authorized_ip_ranges = ["..."] + ... + } + - pattern-inside: | + resource "azurerm_kubernetes_cluster" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.aks.azure-aks-private-clusters-enabled.azure-aks-private-clusters-enabled + languages: + - hcl + message: "Ensure that AKS enables private clusters\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_kubernetes_cluster" "..." { + ... + private_cluster_enabled = true + ... + } + - pattern-inside: | + resource "azurerm_kubernetes_cluster" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.aks.azure-aks-uses-disk-encryptionset.azure-aks-uses-disk-encryptionset + languages: + - hcl + message: Ensure that AKS uses disk encryption set + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_kubernetes_cluster" "..." { + ... + disk_encryption_set_id = "..." + ... + } + - pattern-inside: | + resource "azurerm_kubernetes_cluster" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.apiservice.azure-apiservices-use-virtualnetwork.azure-apiservices-use-virtualnetwork + languages: + - hcl + message: Ensure that API management services use virtual networks + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_api_management" "..." { + ... + virtual_network_configuration { + subnet_id = ... + } + ... + } + - pattern-inside: | + resource "azurerm_api_management" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.appservice.appservice-account-identity-registered.appservice-account-identity-registered + languages: + - hcl + message: Registering the identity used by an App with AD allows it to interact with other services without using username and password. Set the `identity` block in your appservice. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-287: Improper Authentication' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A07:2021 - Identification and Authentication Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#identity + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + identity { + type = "..." + identity_ids = "..." + } + ... + } + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + identity { + type = "SystemAssigned" + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: INFO + - id: terraform.azure.security.appservice.appservice-authentication-enabled.appservice-authentication-enabled + languages: + - hcl + message: Enabling authentication ensures that all communications in the application are authenticated. The `auth_settings` block needs to be filled out with the appropriate auth backend settings + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-287: Improper Authentication' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A02:2017 - Broken Authentication + - A07:2021 - Identification and Authentication Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#auth_settings + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + auth_settings { + ... + enabled = true + ... + } + ... + } + - pattern-either: + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + auth_settings { + ... + enabled = false + ... + } + ... + } + severity: ERROR + - id: terraform.azure.security.appservice.appservice-enable-http2.appservice-enable-http2 + languages: + - hcl + message: Use the latest version of HTTP to ensure you are benefiting from security fixes. Add `http2_enabled = true` to your appservice resource block + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-444: Inconsistent Interpretation of HTTP Requests (''HTTP Request/Response Smuggling'')' + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#http2_enabled + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + site_config { + ... + http2_enabled = true + ... + } + ... + } + - pattern-either: + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + site_config { + ... + http2_enabled = false + ... + } + ... + } + severity: INFO + - id: terraform.azure.security.appservice.appservice-enable-https-only.appservice-enable-https-only + languages: + - hcl + message: By default, clients can connect to App Service by using both HTTP or HTTPS. HTTP should be disabled enabling the HTTPS Only setting. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#https_only + - https://docs.microsoft.com/en-us/azure/app-service/configure-ssl-bindings#enforce-https + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + https_only = true + ... + } + - pattern-either: + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + https_only = false + ... + } + severity: ERROR + - id: terraform.azure.security.appservice.appservice-require-client-cert.appservice-require-client-cert + languages: + - hcl + message: Detected an AppService that was not configured to use a client certificate. Add `client_cert_enabled = true` in your resource block. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#client_cert_enabled + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + client_cert_enabled = true + ... + } + - pattern-either: + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + client_cert_enabled = false + ... + } + severity: INFO + - id: terraform.azure.security.appservice.appservice-use-secure-tls-policy.appservice-use-secure-tls-policy + languages: + - hcl + message: Detected an AppService that was not configured to use TLS 1.2. Add `site_config.min_tls_version = "1.2"` in your resource block. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#min_tls_version + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: min_tls_version = $ANYTHING + - pattern-inside: | + resource "azurerm_app_service" "$NAME" { + ... + } + - pattern-not-inside: min_tls_version = "1.2" + severity: ERROR + - id: terraform.azure.security.appservice.azure-appservice-auth.azure-appservice-auth + languages: + - hcl + message: Ensure App Service Authentication is set on Azure App Service + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + auth_settings { + ... + enabled = true + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.appservice.azure-appservice-client-certificate.azure-appservice-client-certificate + languages: + - hcl + message: Ensure the web app has Client Certificates + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + client_cert_enabled = true + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.appservice.azure-appservice-detailed-errormessages-enabled.azure-appservice-detailed-errormessages-enabled + languages: + - hcl + message: Ensure that App service enables detailed error messages + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + likelihood: LOW + owasp: + - A10:2017 - Insufficient Logging & Monitoring + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + logs { + ... + detailed_error_messages_enabled = true + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.appservice.azure-appservice-disallowed-cors.azure-appservice-disallowed-cors + languages: + - hcl + message: Ensure that CORS disallows every resource to access app services + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-942: Permissive Cross-domain Policy with Untrusted Domains' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: | + ["*"] + - pattern-inside: allowed_origins = ... + - pattern-inside: | + $RESOURCE "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.appservice.azure-appservice-enabled-failed-request.azure-appservice-enabled-failed-request + languages: + - hcl + message: Ensure that App service enables failed request tracing + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + likelihood: LOW + owasp: + - A10:2017 - Insufficient Logging & Monitoring + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + logs { + ... + failed_request_tracing_enabled = true + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.appservice.azure-appservice-http-logging-enabled.azure-appservice-http-logging-enabled + languages: + - hcl + message: Ensure that App service enables HTTP logging + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + likelihood: LOW + owasp: + - A10:2017 - Insufficient Logging & Monitoring + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + logs { + ... + http_logs { + ... + } + } + ... + } + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + logs { + ... + dynamic "http_logs" { + ... + } + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.appservice.azure-appservice-https-only.azure-appservice-https-only + languages: + - hcl + message: Ensure web app redirects all HTTP traffic to HTTPS in Azure App Service Slot + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + https_only = true + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.appservice.azure-appservice-identity.azure-appservice-identity + languages: + - hcl + message: Ensure App Service Authentication is set on Azure App Service + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + client_cert_enabled = true + identity { + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.appservice.azure-appservice-identityprovider-enabled.azure-appservice-identityprovider-enabled + languages: + - hcl + message: Ensure that Managed identity provider is enabled for app services + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + identity { + ... + type = "SystemAssigned" + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.appservice.azure-appservice-min-tls-version.azure-appservice-min-tls-version + languages: + - hcl + message: Ensure web app is using the latest version of TLS encryption + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern-either: + - pattern: | + "1.0" + - pattern: | + "1.1" + - pattern-inside: min_tls_version = ... + - pattern-inside: | + $RESOURCE "azurerm_app_service" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-automation-encrypted.azure-automation-encrypted + languages: + - hcl + message: Ensure that Automation account variables are encrypted + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern-either: + - pattern-inside: | + resource "azurerm_automation_variable_string" "..." { + ... + } + - pattern-inside: | + resource "azurerm_automation_variable_datetime" "..." { + ... + } + - pattern-inside: | + resource "azurerm_automation_variable_int" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_automation_variable_string" "..." { + ... + encrypted = true + ... + } + - pattern-not-inside: | + resource "azurerm_automation_variable_datetime" "..." { + ... + encrypted = true + ... + } + - pattern-not-inside: | + resource "azurerm_automation_variable_int" "..." { + ... + encrypted = true + ... + } + severity: WARNING + - id: terraform.azure.security.azure-batchaccount-uses-keyvault-encrpytion.azure-batchaccount-uses-keyvault-encrpytion + languages: + - hcl + message: Ensure that Azure Batch account uses key vault to encrypt data + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_batch_account" "..." { + ... + key_vault_reference { + ... + } + ... + } + - pattern-inside: | + resource "azurerm_batch_account" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-cognitiveservices-disables-public-network.azure-cognitiveservices-disables-public-network + languages: + - hcl + message: Ensure that Cognitive Services accounts disable public network access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_cognitive_account" "..." { + ... + public_network_access_enabled = false + ... + } + - pattern-inside: | + resource "azurerm_cognitive_account" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-containergroup-deployed-into-virtualnetwork.azure-containergroup-deployed-into-virtualnetwork + languages: + - hcl + message: Ensure that Azure Container group is deployed into virtual network + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: "resource \"azurerm_container_group\" \"...\" {\n...\ncontainer {\n ...\n}\nnetwork_profile_id = \"...\" \n...\n}\n" + - pattern-inside: | + resource "azurerm_container_group" "..." { + ... + container { + ... + } + ... + } + severity: WARNING + - id: terraform.azure.security.azure-cosmosdb-accounts-restricted-access.azure-cosmosdb-accounts-restricted-access + languages: + - hcl + message: Ensure Cosmos DB accounts have restricted access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_cosmosdb_account" "..." { + ... + public_network_access_enabled = false + ... + } + - pattern-not-inside: | + resource "azurerm_cosmosdb_account" "..." { + ... + is_virtual_network_filter_enabled = true + virtual_network_rule = ... + ... + } + - pattern-not-inside: | + resource "azurerm_cosmosdb_account" "..." { + ... + is_virtual_network_filter_enabled = true + ip_range_filter = [...] + ... + } + - pattern-inside: | + resource "azurerm_cosmosdb_account" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-cosmosdb-disable-access-key-write.azure-cosmosdb-disable-access-key-write + languages: + - hcl + message: Ensure that Cosmos DB accounts have access key write capability disabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_cosmosdb_account" "..." { + ... + access_key_metadata_writes_enabled = false + ... + } + - pattern-inside: | + resource "azurerm_cosmosdb_account" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-cosmosdb-disables-public-network.azure-cosmosdb-disables-public-network + languages: + - hcl + message: Ensure that Azure Cosmos DB disables public network access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_cosmosdb_account" "..." { + ... + public_network_access_enabled = false + ... + } + - pattern-inside: | + resource "azurerm_cosmosdb_account" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-cosmosdb-have-cmk.azure-cosmosdb-have-cmk + languages: + - hcl + message: Ensure that Cosmos DB accounts have customer-managed keys to encrypt data at rest + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_cosmosdb_account" "..." { + ... + key_vault_key_id = ... + ... + } + - pattern-inside: | + resource "azurerm_cosmosdb_account" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-customrole-definition-subscription-owner.azure-customrole-definition-subscription-owner + languages: + - hcl + message: Ensure that no custom subscription owner roles are created + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: | + ["*"] + - pattern-inside: | + resource "azurerm_role_definition" "..." { + permissions { + ... + } + } + - pattern-inside: actions = ... + severity: WARNING + - id: terraform.azure.security.azure-dataexplorer-double-encryption-enabled.azure-dataexplorer-double-encryption-enabled + languages: + - hcl + message: Ensure that Azure Data Explorer uses double encryption + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_kusto_cluster" "..." { + ... + double_encryption_enabled = true + ... + } + - pattern-inside: | + resource "azurerm_kusto_cluster" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-dataexplorer-uses-disk-encryption.azure-dataexplorer-uses-disk-encryption + languages: + - hcl + message: Ensure that Azure Data Explorer uses disk encryption + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_kusto_cluster" "..." { + ... + enable_disk_encryption = true + ... + } + - pattern-inside: | + resource "azurerm_kusto_cluster" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-datafactory-no-public-network-access.azure-datafactory-no-public-network-access + languages: + - hcl + message: Ensure that Azure Data factory public network access is disabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_data_factory" "..." { + ... + public_network_enabled = false + ... + } + - pattern-inside: | + resource "azurerm_data_factory" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-datafactory-uses-git-repository.azure-datafactory-uses-git-repository + languages: + - hcl + message: Ensure that Azure Data Factory uses Git repository for source control + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_data_factory" "..." { + ... + github_configuration { + ... + } + ... + } + - pattern-not-inside: | + resource "azurerm_data_factory" "..." { + ... + vsts_configuration { + ... + } + ... + } + - pattern-inside: | + resource "azurerm_data_factory" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-datalake-store-encryption.azure-datalake-store-encryption + languages: + - hcl + message: Ensure that Data Lake Store accounts enables encryption + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_data_lake_store" "..." { + ... + encryption_state = "Enabled" + ... + } + - pattern-inside: | + resource "azurerm_data_lake_store" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-eventgrid-domain-network-access.azure-eventgrid-domain-network-access + languages: + - hcl + message: Ensure that Azure Event Grid Domain public network access is disabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_eventgrid_domain" "..." { + ... + public_network_access_enabled = false + ... + } + - pattern-inside: | + resource "azurerm_eventgrid_domain" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-functionapp-disallow-cors.azure-functionapp-disallow-cors + languages: + - hcl + message: ensure that CORS disallows all resources to access Function app + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-942: Permissive Cross-domain Policy with Untrusted Domains' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: | + ["*"] + - pattern-inside: allowed_origins = ... + - pattern-inside: | + $RESOURCE "azurerm_function_app" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-functionapps-enable-auth.azure-functionapps-enable-auth + languages: + - hcl + message: Ensure that function apps enables Authentication + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_function_app" "..." { + ... + auth_settings { + ... + enabled = true + ... + } + ... + } + - pattern-inside: | + resource "azurerm_function_app" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-instance-extensions.azure-instance-extensions + languages: + - hcl + message: Ensure Virtual Machine Extensions are not Installed + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "azurerm_linux_virtual_machine" "..." { + ... + } + - pattern-inside: | + resource "azurerm_windows_virtual_machine" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_linux_virtual_machine" "..." { + ... + allow_extension_operations = false + ... + } + - pattern-not-inside: | + resource "azurerm_windows_virtual_machine" "..." { + ... + allow_extension_operations = false + ... + } + severity: WARNING + - id: terraform.azure.security.azure-iot-no-public-network-access.azure-iot-no-public-network-access + languages: + - hcl + message: Ensure that Azure IoT Hub disables public network access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_iothub" "..." { + ... + public_network_access_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.security.azure-key-backedby-hsm.azure-key-backedby-hsm + languages: + - hcl + message: Ensure that key vault key is backed by HSM + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault_key" "..." { + ... + key_type = "EC-HSM" + ... + } + - pattern-not-inside: | + resource "azurerm_key_vault_key" "..." { + ... + key_type = "RSA-HSM" + ... + } + - pattern-inside: | + resource "azurerm_key_vault_key" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-key-no-expiration-date.azure-key-no-expiration-date + languages: + - hcl + message: Ensure that the expiration date is set on all keys + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault_key" "..." { + ... + expiration_date = "..." + ... + } + - pattern-inside: | + resource "azurerm_key_vault_key" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-managed-disk-encryption-set.azure-managed-disk-encryption-set + languages: + - hcl + message: Ensure that managed disks use a specific set of disk encryption sets for the customer-managed key encryption + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_managed_disk" "..." { + ... + disk_encryption_set_id = ... + ... + } + - pattern-inside: | + resource "azurerm_managed_disk" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-managed-disk-encryption.azure-managed-disk-encryption + languages: + - hcl + message: Ensure Azure managed disk has encryption enabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_managed_disk" "..." { + ... + encryption_settings { + ... + enabled = false + ... + } + ... + } + severity: WARNING + - id: terraform.azure.security.azure-mariadb-public-access-disabled.azure-mariadb-public-access-disabled + languages: + - hcl + message: Ensure public network access enabled is set to False for MariaDB servers + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mariadb_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mariadb_server" "..." { + ... + public_network_access_enabled = false + ... + } + severity: WARNING + - id: terraform.azure.security.azure-monitor-log-profile-retention-days.azure-monitor-log-profile-retention-days + languages: + - hcl + message: Ensure that Activity Log Retention is set 365 days or greater + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "azurerm_monitor_log_profile" "..." { + ... + retention_policy { + ... + enabled = true + days = $DAYS + ... + } + ... + } + - pattern-not-inside: | + resource "azurerm_monitor_log_profile" "..." { + ... + retention_policy { + ... + enabled = false + days = 0 + ... + } + ... + } + - metavariable-comparison: + comparison: $DAYS < 365 + metavariable: $DAYS + severity: WARNING + - id: terraform.azure.security.azure-mssql-service-mintls-version.azure-mssql-service-mintls-version + languages: + - hcl + message: Ensure MSSQL is using the latest version of TLS encryption + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern-either: + - pattern: | + "1.0" + - pattern: | + "1.1" + - pattern-inside: minimum_tls_version = ... + - pattern-inside: | + $RESOURCE "azurerm_mssql_server" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-mysql-encryption-enabled.azure-mysql-encryption-enabled + languages: + - hcl + message: Ensure that MySQL server enables infrastructure encryption + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mysql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mysql_server" "..." { + ... + infrastructure_encryption_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.security.azure-mysql-mintls-version.azure-mysql-mintls-version + languages: + - hcl + message: Ensure MySQL is using the latest version of TLS encryption + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern-either: + - pattern: | + "TLS1_0" + - pattern: | + "TLS1_1" + - pattern-inside: ssl_minimal_tls_version_enforced = ... + - pattern-inside: | + $RESOURCE "azurerm_mysql_server" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.azure-mysql-public-access-disabled.azure-mysql-public-access-disabled + languages: + - hcl + message: Ensure public network access enabled is set to False for MySQL servers + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mysql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mysql_server" "..." { + ... + public_network_access_enabled = false + ... + } + severity: WARNING + - id: terraform.azure.security.azure-network-watcher-flowlog-period.azure-network-watcher-flowlog-period + languages: + - hcl + message: Ensure that Network Security Group Flow Log retention period is 90 days or greater + metadata: + category: best-practice + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_network_watcher_flow_log" "..." { + ... + retention_policy { + ... + enabled = true + days = $DAYS + ... + } + ... + } + - pattern-not-inside: | + resource "azurerm_network_watcher_flow_log" "..." { + ... + retention_policy { + ... + enabled = true + days = 0 + ... + } + ... + } + - metavariable-comparison: + comparison: $DAYS < 90 + metavariable: $DAYS + severity: WARNING + - id: terraform.azure.security.azure-postgresql-encryption-enabled.azure-postgresql-encryption-enabled + languages: + - hcl + message: Ensure that PostgreSQL server enables infrastructure encryption + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_postgresql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_postgresql_server" "..." { + ... + infrastructure_encryption_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.security.azure-postgresql-min-tls-version.azure-postgresql-min-tls-version + languages: + - hcl + message: Ensure PostgreSQL is using the latest version of TLS encryption + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern-either: + - pattern: | + "TLS1_2" + - pattern: | + "TLS1_1" + - pattern: | + "TLS1_0" + - pattern-inside: ssl_minimal_tls_version_enforced = ... + - pattern-inside: | + $RESOURCE "azurerm_postgresql_server" "..." { + ... + } + - pattern-not-inside: | + $RESOURCE "azurerm_postgresql_server" "..." { + ... + ssl_enforcement_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.security.azure-postgresql-server-public-access-disabled.azure-postgresql-server-public-access-disabled + languages: + - hcl + message: Ensure public network access enabled is set to False for PostgreSQL servers + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_postgresql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_postgresql_server" "..." { + ... + public_network_access_enabled = false + ... + } + severity: WARNING + - id: terraform.azure.security.azure-redis-cache-enable-non-ssl-port.azure-redis-cache-enable-non-ssl-port + languages: + - hcl + message: Ensure that only SSL are enabled for Cache for Redis + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_redis_cache" "..." { + ... + enable_non_ssl_port = true + ... + } + severity: WARNING + - id: terraform.azure.security.azure-redis-cache-public-network-access-enabled.azure-redis-cache-public-network-access-enabled + languages: + - hcl + message: Ensure that Azure Cache for Redis disables public network access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_redis_cache" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_redis_cache" "..." { + ... + public_network_access_enabled = false + ... + } + severity: WARNING + - id: terraform.azure.security.azure-remote-debugging-not-enabled.azure-remote-debugging-not-enabled + languages: + - hcl + message: Ensure that remote debugging is not enabled for app services + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + remote_debugging_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.security.azure-scale-set-password.azure-scale-set-password + languages: + - hcl + message: Ensure that Virtual machine does not enable password authentication + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_linux_virtual_machine_scale_set" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_linux_virtual_machine_scale_set" "..." { + ... + disable_password_authentication = true + ... + } + severity: WARNING + - id: terraform.azure.security.azure-search-publicnetwork-access-disabled.azure-search-publicnetwork-access-disabled + languages: + - hcl + message: Ensure that Azure Cognitive Search disables public network access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_search_service" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_search_service" "..." { + ... + public_network_access_enabled = false + ... + } + severity: WARNING + - id: terraform.azure.security.azure-service-fabric-cluster-protection-level.azure-service-fabric-cluster-protection-level + languages: + - hcl + message: Ensure that Service Fabric use three levels of protection available + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_service_fabric_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_service_fabric_cluster" "..." { + ... + fabric_settings { + name = "Security" + parameters = { + ... + name = "ClusterProtectionLevel" + value = "EncryptAndSign" + ... + } + ... + } + ... + } + severity: WARNING + - id: terraform.azure.security.azure-sqlserver-no-public-access.azure-sqlserver-no-public-access + languages: + - hcl + message: Ensure no SQL Databases allow ingress from 0.0.0.0/0 (ANY IP) + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mysql_firewall_rule" "..." { + ... + start_ip_address = "0.0.0.0" + end_ip_address = "255.255.255.255" + ... + } + severity: WARNING + - id: terraform.azure.security.azure-sqlserver-public-access-disabled.azure-sqlserver-public-access-disabled + languages: + - hcl + message: Ensure that SQL server disables public network access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mssql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mssql_server" "..." { + ... + public_network_access_enabled = false + ... + } + severity: WARNING + - id: terraform.azure.security.azure-storage-account-disable-public-access.azure-storage-account-disable-public-access + languages: + - hcl + message: Ensure default network access rule for Storage Accounts is set to deny + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + allow_blob_public_access = true + ... + } + severity: WARNING + - id: terraform.azure.security.azure-storage-account-minimum-tlsversion.azure-storage-account-minimum-tlsversion + languages: + - hcl + message: Ensure Storage Account is using the latest version of TLS encryption + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_storage_account" "..." { + ... + min_tls_version = "TLS1_2" + ... + } + - pattern-not-inside: | + resource "azurerm_storage_account" "..." { + ... + min_tls_version = "TLS1_3" + ... + } + severity: WARNING + - id: terraform.azure.security.azure-storage-blob-service-container-private-access.azure-storage-blob-service-container-private-access + languages: + - hcl + message: Ensure that Public access level is set to Private for blob containers + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_storage_container" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_storage_container" "..." { + ... + container_access_type = "private" + ... + } + severity: WARNING + - id: terraform.azure.security.azure-storage-sync-public-access-disabled.azure-storage-sync-public-access-disabled + languages: + - hcl + message: Ensure that Azure File Sync disables public network access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_storage_sync" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_storage_sync" "..." { + ... + incoming_traffic_policy = AllowVirtualNetworksOnly + ... + } + severity: WARNING + - id: terraform.azure.security.azure-vmencryption-at-host-enabled.azure-vmencryption-at-host-enabled + languages: + - hcl + message: Ensure that Virtual machine scale sets have encryption at host enabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "azurerm_windows_virtual_machine_scale_set" "..." { + ... + } + - pattern-inside: | + resource "azurerm_linux_virtual_machine_scale_set" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_windows_virtual_machine_scale_set" "..." { + ... + encryption_at_host_enabled = true + ... + } + - pattern-not-inside: | + resource "azurerm_linux_virtual_machine_scale_set" "..." { + ... + encryption_at_host_enabled = true + ... + } + severity: WARNING + - id: terraform.azure.security.functionapp.functionapp-authentication-enabled.functionapp-authentication-enabled + languages: + - hcl + message: Enabling authentication ensures that all communications in the application are authenticated. The `auth_settings` block needs to be filled out with the appropriate auth backend settings + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-287: Improper Authentication' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A02:2017 - Broken Authentication + - A07:2021 - Identification and Authentication Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/function_app#enabled + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_function_app" "..." { + ... + auth_settings { + ... + enabled = true + ... + } + ... + } + - pattern-either: + - pattern-inside: | + resource "azurerm_function_app" "..." { + ... + } + - pattern-inside: | + resource "azurerm_function_app" "..." { + ... + auth_settings { + ... + enabled = false + ... + } + ... + } + severity: INFO + - id: terraform.azure.security.functionapp.functionapp-enable-http2.functionapp-enable-http2 + languages: + - hcl + message: Use the latest version of HTTP to ensure you are benefiting from security fixes. Add `http2_enabled = true` to your function app resource block + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-444: Inconsistent Interpretation of HTTP Requests (''HTTP Request/Response Smuggling'')' + impact: LOW + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/function_app#http2_enabled + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_function_app" "..." { + ... + site_config { + ... + http2_enabled = true + ... + } + ... + } + - pattern-either: + - pattern-inside: | + resource "azurerm_function_app" "..." { + ... + } + - pattern-inside: | + resource "azurerm_function_app" "..." { + ... + site_config { + ... + http2_enabled = false + ... + } + ... + } + severity: INFO + - id: terraform.azure.security.keyvault.keyvault-content-type-for-secret.keyvault-content-type-for-secret + languages: + - hcl + message: Key vault Secret should have a content type set + metadata: + category: correctness + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret#content_type + - https://docs.microsoft.com/en-us/azure/key-vault/secrets/about-secrets + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault_secret" "..." { + ... + content_type = "..." + ... + } + - pattern-inside: | + resource "azurerm_key_vault_secret" "..." { + ... + } + severity: INFO + - id: terraform.azure.security.keyvault.keyvault-ensure-key-expires.keyvault-ensure-key-expires + languages: + - hcl + message: Ensure that the expiration date is set on all keys + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-262: Not Using Password Aging' + impact: MEDIUM + likelihood: LOW + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key#expiration_date + - https://docs.microsoft.com/en-us/powershell/module/az.keyvault/update-azkeyvaultkey?view=azps-5.8.0#example-1--modify-a-key-to-enable-it--and-set-the-expiration-date-and-tags + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault_key" "..." { + ... + expiration_date = "..." + ... + } + - pattern-inside: | + resource "azurerm_key_vault_key" "..." { + ... + } + severity: INFO + - id: terraform.azure.security.keyvault.keyvault-ensure-secret-expires.keyvault-ensure-secret-expires + languages: + - hcl + message: Ensure that the expiration date is set on all secrets + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-262: Not Using Password Aging' + impact: MEDIUM + likelihood: LOW + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret#expiration_date + - https://docs.microsoft.com/en-us/azure/key-vault/secrets/about-secrets + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault_secret" "..." { + ... + expiration_date = "..." + ... + } + - pattern-inside: | + resource "azurerm_key_vault_secret" "..." { + ... + } + severity: INFO + - id: terraform.azure.security.keyvault.keyvault-purge-enabled.keyvault-purge-enabled + languages: + - hcl + message: Key vault should have purge protection enabled + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-693: Protection Mechanism Failure' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault#purge_protection_enabled + - https://docs.microsoft.com/en-us/azure/key-vault/general/soft-delete-overview#purge-protection + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault" "..." { + ... + purge_protection_enabled = true + ... + } + - pattern-either: + - pattern-inside: | + resource "azurerm_key_vault" "..." { + ... + } + - pattern-inside: | + resource "azurerm_key_vault" "..." { + ... + purge_protection_enabled = false + ... + } + severity: WARNING + - id: terraform.azure.security.keyvault.keyvault-specify-network-acl.keyvault-specify-network-acl + languages: + - hcl + message: Network ACLs allow you to reduce your exposure to risk by limiting what can access your key vault. The default action of the Network ACL should be set to deny for when IPs are not matched. Azure services can be allowed to bypass. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault#network_acls + - https://docs.microsoft.com/en-us/azure/key-vault/general/network-security + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault" "..." { + ... + network_acls { + ... + default_action = "Deny" + ... + } + ... + } + - pattern-either: + - pattern-inside: | + resource "azurerm_key_vault" "..." { + ... + } + - pattern-inside: | + resource "azurerm_key_vault" "..." { + ... + network_acls { + ... + default_action = "Allow" + ... + } + ... + } + severity: ERROR + - id: terraform.azure.security.storage.storage-allow-microsoft-service-bypass.storage-allow-microsoft-service-bypass + languages: + - hcl + message: Some Microsoft services that interact with storage accounts operate from networks that can't be granted access through network rules. To help this type of service work as intended, allow the set of trusted Microsoft services to bypass the network rules + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#bypass + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account_network_rules#bypass + - https://docs.microsoft.com/en-us/azure/storage/common/storage-network-security#trusted-microsoft-services + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern-not-inside: | + resource "azurerm_storage_account" "..." { + ... + network_rules { + ... + bypass = ["...", "AzureServices"] + ... + } + ... + } + - pattern-not-inside: | + resource "azurerm_storage_account_network_rules" "..." { + ... + bypass = ["...", "AzureServices"] + ... + } + - pattern-either: + - pattern-inside: | + resource "azurerm_storage_account_network_rules" "..." { + ... + bypass = [$ANYTHING] + ... + } + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + network_rules { + ... + bypass = [$ANYTHING] + ... + } + ... + } + severity: WARNING + - id: terraform.azure.security.storage.storage-default-action-deny.storage-default-action-deny + languages: + - hcl + message: Detected a Storage that was not configured to deny action by default. Add `default_action = "Deny"` in your resource block. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-16: CWE CATEGORY: Configuration' + impact: LOW + likelihood: LOW + owasp: + - A06:2017 - Security Misconfiguration + - A05:2021 - Security Misconfiguration + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account_network_rules#default_action + - https://docs.microsoft.com/en-us/azure/firewall/rule-processing + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_storage_account_network_rules" "..." { + ... + default_action = "Deny" + ... + } + - pattern-inside: | + resource "azurerm_storage_account_network_rules" "..." { + ... + default_action = "Allow" + ... + } + severity: ERROR + - id: terraform.azure.security.storage.storage-enforce-https.storage-enforce-https + languages: + - hcl + message: Detected a Storage that was not configured to deny action by default. Add `enable_https_traffic_only = true` in your resource block. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#enable_https_traffic_only + - https://docs.microsoft.com/en-us/azure/storage/common/storage-require-secure-transfer + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern-not-inside: | + resource "azurerm_storage_account" "..." { + ... + enable_https_traffic_only = true + ... + } + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + enable_https_traffic_only = false + ... + } + severity: WARNING + - id: terraform.azure.security.storage.storage-queue-services-logging.storage-queue-services-logging + languages: + - hcl + message: Storage Analytics logs detailed information about successful and failed requests to a storage service. This information can be used to monitor individual requests and to diagnose issues with a storage service. Requests are logged on a best-effort basis. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + likelihood: LOW + owasp: + - A10:2017 - Insufficient Logging & Monitoring + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging + - https://docs.microsoft.com/en-us/azure/storage/common/storage-analytics-logging?tabs=dotnet + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern-either: + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + queue_properties { + ... + } + ... + } + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_storage_account" "..." { + ... + queue_properties { + ... + logging { + ... + } + ... + } + ... + } + severity: WARNING + - id: terraform.azure.security.storage.storage-use-secure-tls-policy.storage-use-secure-tls-policy + languages: + - hcl + message: 'Azure Storage currently supports three versions of the TLS protocol: 1.0, 1.1, and 1.2. Azure Storage uses TLS 1.2 on public HTTPS endpoints, but TLS 1.0 and TLS 1.1 are still supported for backward compatibility. This check will warn if the minimum TLS is not set to TLS1_2.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#min_tls_version + - https://docs.microsoft.com/en-us/azure/storage/common/transport-layer-security-configure-minimum-version + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern-either: + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + min_tls_version = "$ANYTHING" + ... + } + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_storage_account" "..." { + ... + min_tls_version = "TLS1_2" + ... + } + severity: ERROR + - id: terraform.gcp.best-practice.gcp-compute-shielded-vm.gcp-compute-shielded-vm + languages: + - hcl + message: Ensure Compute instances are launched with Shielded VM enabled + metadata: + category: best-practice + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_compute_instance" "..." { + ... + } + - pattern-inside: | + resource "google_compute_instance" "..." { + ... + shielded_instance_config { + ... + enable_integrity_monitoring = false + ... + } + ... + } + - pattern-not-inside: | + resource "google_compute_instance" "..." { + ... + shielded_instance_config { + ... + enable_integrity_monitoring = true + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-compute-template-shielded-vm.gcp-compute-template-shielded-vm + languages: + - hcl + message: Ensure Compute instances are launched with Shielded VM enabled + metadata: + category: best-practice + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_compute_instance_template" "..." { + ... + shielded_instance_config { + ... + enable_integrity_monitoring = false + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-dnssec-enabled.gcp-dnssec-enabled + languages: + - hcl + message: "Ensure that RSASHA1 is not used for the zone-signing and key-signing keys in Cloud DNS DNSSEC\t" + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_dns_managed_zone" "..." { + ... + } + - pattern-not-inside: | + resource "google_dns_managed_zone" "..." { + ... + dnssec_config { + state = on + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-alias-ip-enabled.gcp-gke-alias-ip-enabled + languages: + - hcl + message: Ensure Kubernetes Cluster is created with Alias IP ranges enabled + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + ip_allocation_policy { + ... + use_ip_aliases = "false" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-binary-authorization.gcp-gke-binary-authorization + languages: + - hcl + message: "Ensure use of Binary Authorization\t" + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + enable_binary_authorization = true + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-enable-shielded-nodes.gcp-gke-enable-shielded-nodes + languages: + - hcl + message: Ensure Shielded GKE Nodes are Enabled + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + enable_shielded_nodes = false + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-has-labels.gcp-gke-has-labels + languages: + - hcl + message: Ensure Kubernetes Clusters are configured with Labels + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + resource_labels = { + "..." = "..." + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-metadata-server-enabled.gcp-gke-metadata-server-enabled + languages: + - hcl + message: "Ensure the GKE Metadata Server is Enabled\t" + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + node_config { + ... + workload_metadata_config { + ... + node_metadata = "GKE_METADATA_SERVER" + ... + } + ... + } + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + node_config { + ... + workload_metadata_config { + ... + mode = "GKE_METADATA" + ... + } + ... + } + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + node_config { + ... + workload_metadata_config = ... + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-nodepool-auto-repair-enabled.gcp-gke-nodepool-auto-repair-enabled + languages: + - hcl + message: Ensure 'Automatic node repair' is enabled for Kubernetes Clusters + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_node_pool" "..." { + ... + management { + ... + auto_repair = false + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-nodepool-auto-upgrade-enabled.gcp-gke-nodepool-auto-upgrade-enabled + languages: + - hcl + message: Ensure 'Automatic node upgrade' is enabled for Kubernetes Clusters + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_node_pool" "..." { + ... + management { + ... + auto_upgrade = false + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-nodepool-metadata-server-enabled.gcp-gke-nodepool-metadata-server-enabled + languages: + - hcl + message: "Ensure the GKE Metadata Server is Enabled\t" + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_node_pool" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_node_pool" "..." { + ... + node_config { + ... + workload_metadata_config { + ... + node_metadata = "GKE_METADATA_SERVER" + ... + } + ... + } + ... + } + - pattern-not-inside: | + resource "google_container_node_pool" "..." { + ... + node_config { + ... + workload_metadata_config { + ... + mode = "GKE_METADATA" + ... + } + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-nodepool-secure-boot-for-shielded-nodes.gcp-gke-nodepool-secure-boot-for-shielded-nodes + languages: + - hcl + message: "Ensure Secure Boot for Shielded GKE Nodes is Enabled\t" + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_node_pool" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_node_pool" "..." { + ... + shielded_instance_config { + ... + enable_secure_boot = true + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-sql-backup-configuration-enabled.gcp-gke-sql-backup-configuration-enabled + languages: + - hcl + message: Ensure all Cloud SQL database instance have backup configuration enabled + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + } + - pattern-not-inside: | + resource "google_sql_database_instance" "..." { + ... + settings { + ... + backup_configuration { + ... + enabled = true + ... + } + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-gke-use-cos-image.gcp-gke-use-cos-image + languages: + - hcl + message: Ensure Container-Optimized OS (cos) is used for Kubernetes Engine Clusters Node image + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_node_pool" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_node_pool" "..." { + ... + node_config { + ... + image_type = "COS" + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-ipv6-private-google-enabled.gcp-ipv6-private-google-enabled + languages: + - hcl + message: Ensure that Private google access is enabled for IPV6 + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_compute_subnetwork" "..." { + ... + } + - pattern-not-inside: | + resource "google_compute_subnetwork" "..." { + ... + private_ipv6_google_access = "ENABLE_OUTBOUND_VM_ACCESS_TO_GOOGLE" + ... + } + - pattern-not-inside: | + resource "google_compute_subnetwork" "..." { + ... + private_ipv6_google_access = "ENABLE_BIDIRECTIONAL_ACCESS_TO_GOOGLE" + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-mysql-local-in-file-off.gcp-mysql-local-in-file-off + languages: + - hcl + message: Ensure MySQL database 'local_infile' flag is set to 'off' + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + database_flags { + ... + name = "local_infile" + value = "on" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-postgresql-log-checkpoints.gcp-postgresql-log-checkpoints + languages: + - hcl + message: Ensure PostgreSQL database 'log_checkpoints' flag is set to 'on' + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + database_flags { + ... + name = "log_checkpoints" + value = "off" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-postgresql-log-connection.gcp-postgresql-log-connection + languages: + - hcl + message: Ensure PostgreSQL database 'log_connections' flag is set to 'on' + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + database_flags { + ... + name = "log_connections" + value = "off" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-postgresql-log-disconnection.gcp-postgresql-log-disconnection + languages: + - hcl + message: Ensure PostgreSQL database 'log_disconnections' flag is set to 'on' + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + database_flags { + ... + name = "log_disconnections" + value = "off" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-postgresql-log-lock-waits.gcp-postgresql-log-lock-waits + languages: + - hcl + message: Ensure PostgreSQL database 'log_lock_waits' flag is set to 'on' + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + database_flags { + ... + name = "log_lock_waits" + value = "off" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-postgresql-log-min-duration.gcp-postgresql-log-min-duration + languages: + - hcl + message: Ensure PostgreSQL database 'log_min_duration_statement' flag is set to '-1' + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + database_flags { + ... + } + ... + } + - pattern-not-inside: | + resource "google_sql_database_instance" "..." { + ... + database_flags { + ... + name = "log_min_duration_statement" + value = "-1" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-postgresql-log-min-message.gcp-postgresql-log-min-message + languages: + - hcl + message: Ensure PostgreSQL database 'log_min_messages' flag is set to a valid value + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + database_flags { + ... + name = "log_min_messages" + value = "$VALUE" + ... + } + ... + } + - metavariable-pattern: + language: generic + metavariable: $VALUE + patterns: + - pattern-not-regex: (?i)(DEBUG5|DEBUG4|DEBUG3|DEBUG2|DEBUG1|INFO|NOTICE|WARNING|ERROR|LOG|FATAL|PANIC) + severity: WARNING + - id: terraform.gcp.best-practice.gcp-postgresql-log-temp.gcp-postgresql-log-temp + languages: + - hcl + message: Ensure PostgreSQL database 'log_temp_files' flag is set to '0' + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + database_flags { + ... + } + ... + } + - pattern-not-inside: | + resource "google_sql_database_instance" "..." { + ... + database_flags { + ... + name = "log_temp_files" + value = "0" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.best-practice.gcp-storage-versioning-enabled.gcp-storage-versioning-enabled + languages: + - hcl + message: Ensure Cloud storage has versioning enabled + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_storage_bucket" "..." { + ... + } + - pattern-not-inside: | + resource "google_storage_bucket" "..." { + ... + versioning = { + enabled = true + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-artifact-registry-encrypted-with-cmk.gcp-artifact-registry-encrypted-with-cmk + languages: + - hcl + message: Ensure Artifact Registry Repositories are encrypted with Customer Supplied Encryption Keys (CSEK) + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_artifact_registry_repository" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_artifact_registry_repository" $ANYTHING { + ... + kms_key_name = ... + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-artifact-registry-private-repo-iam-binding.gcp-artifact-registry-private-repo-iam-binding + languages: + - hcl + message: "Ensure that Artifact Registry repositories are not anonymously or publicly accessible\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_artifact_registry_repository_iam_binding" "..." { + ... + members = [ ..., "allAuthenticatedUsers", ...] + ... + } + - pattern-inside: | + resource "google_artifact_registry_repository_iam_binding" "..." { + ... + members = [ ..., "allUsers", ...] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-artifact-registry-private-repo-iam-member.gcp-artifact-registry-private-repo-iam-member + languages: + - hcl + message: "Ensure that Artifact Registry repositories are not anonymously or publicly accessible\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_artifact_registry_repository_iam_member" "..." { + ... + member = "allUsers" + ... + } + - pattern-inside: | + resource "google_artifact_registry_repository_iam_member" "..." { + ... + member = "allAuthenticatedUsers" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-bigquery-dataset-encrypted-with-cmk.gcp-bigquery-dataset-encrypted-with-cmk + languages: + - hcl + message: "Ensure that BigQuery datasets are not anonymously or publicly accessible\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_bigquery_dataset" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_bigquery_dataset" $ANYTHING { + ... + default_encryption_configuration { + ... + kms_key_name = ... + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-bigquery-private-table-iam-binding.gcp-bigquery-private-table-iam-binding + languages: + - hcl + message: "Ensure that BigQuery Tables are not anonymously or publicly accessible\t\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_bigquery_table_iam_binding" "..." { + ... + members = [ ..., "allAuthenticatedUsers", ...] + ... + } + - pattern-inside: | + resource "google_bigquery_table_iam_binding" "..." { + ... + members = [ ..., "allUsers", ...] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-bigquery-private-table-iam-member.gcp-bigquery-private-table-iam-member + languages: + - hcl + message: "Ensure that BigQuery Tables are not anonymously or publicly accessible\t\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_bigquery_table_iam_member" "..." { + ... + member = "allAuthenticatedUsers" + ... + } + - pattern-inside: | + resource "google_bigquery_table_iam_member" "..." { + ... + member = "allUsers" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-bigquery-table-encrypted-with-cmk.gcp-bigquery-table-encrypted-with-cmk + languages: + - hcl + message: "Ensure Big Query Tables are encrypted with Customer Supplied Encryption Keys (CSEK)\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_bigquery_table" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_bigquery_table" $ANYTHING { + ... + encryption_configuration { + ... + kms_key_name = ... + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-bigtable-instance-encrypted-with-cmk.gcp-bigtable-instance-encrypted-with-cmk + languages: + - hcl + message: "Ensure Big Table Instances are encrypted with Customer Supplied Encryption Keys (CSEK)\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_bigtable_instance" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_bigtable_instance" $ANYTHING { + ... + cluster { + ... + kms_key_name = ... + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-build-workers-private.gcp-build-workers-private + languages: + - hcl + message: "Ensure Cloud build workers are private\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_cloudbuild_worker_pool" "..." { + ... + } + - pattern-not-inside: | + resource "google_cloudbuild_worker_pool" "..." { + ... + worker_config { + ... + no_external_ip = true + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-cloud-storage-logging.gcp-cloud-storage-logging + languages: + - hcl + message: Ensure bucket logs access. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + likelihood: LOW + owasp: + - A10:2017 - Insufficient Logging & Monitoring + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - vuln + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_storage_bucket" $ANYTHING { + ... + } + - pattern-not-inside: "resource \"google_storage_bucket\" $ANYTHING {\n ...\n logging {\n log_bucket = ...\n } \n ...\n}\n" + severity: WARNING + - id: terraform.gcp.security.gcp-compute-boot-disk-encryption.gcp-compute-boot-disk-encryption + languages: + - hcl + message: Ensure VM disks for critical VMs are encrypted with Customer Supplied Encryption Keys (CSEK) + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_compute_instance" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_compute_instance" $ANYTHING { + ... + boot_disk { + disk_encryption_key_raw = ... + } + ... + } + - pattern-not-inside: | + resource "google_compute_instance" $ANYTHING { + ... + boot_disk { + kms_key_self_link = ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-disk-encryption.gcp-compute-disk-encryption + languages: + - hcl + message: Ensure VM disks for critical VMs are encrypted with Customer Supplied Encryption Keys (CSEK) + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_compute_disk" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_compute_disk" $ANYTHING { + ... + disk_encryption_key { + raw_key = ... + } + ... + } + - pattern-not-inside: | + resource "google_compute_disk" $ANYTHING { + ... + disk_encryption_key { + kms_key_self_link = ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-20.gcp-compute-firewall-unrestricted-ingress-20 + languages: + - hcl + message: Ensure Google compute firewall ingress does not allow unrestricted FTP access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [20] + } + source_ranges = ["0.0.0.0/0"] + ... + } + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [..., "20", ...] + } + source_ranges = ["0.0.0.0/0"] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-21.gcp-compute-firewall-unrestricted-ingress-21 + languages: + - hcl + message: Ensure Google compute firewall ingress does not allow unrestricted FTP access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [21] + } + source_ranges = ["0.0.0.0/0"] + ... + } + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [..., "21", ...] + } + source_ranges = ["0.0.0.0/0"] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-22.gcp-compute-firewall-unrestricted-ingress-22 + languages: + - hcl + message: Ensure Google compute firewall ingress does not allow unrestricted SSH access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [22] + } + source_ranges = ["0.0.0.0/0"] + ... + } + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [..., "22", ...] + } + source_ranges = ["0.0.0.0/0"] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-3306.gcp-compute-firewall-unrestricted-ingress-3306 + languages: + - hcl + message: Ensure Google compute firewall ingress does not allow unrestricted MySQL access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [3306] + } + source_ranges = ["0.0.0.0/0"] + ... + } + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [..., "3306", ...] + } + source_ranges = ["0.0.0.0/0"] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-3389.gcp-compute-firewall-unrestricted-ingress-3389 + languages: + - hcl + message: Ensure Google compute firewall ingress does not allow unrestricted RDP access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [3389] + } + source_ranges = ["0.0.0.0/0"] + ... + } + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [..., "3389", ...] + } + source_ranges = ["0.0.0.0/0"] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-80.gcp-compute-firewall-unrestricted-ingress-80 + languages: + - hcl + message: Ensure Google compute firewall ingress does not allow unrestricted HTTP access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [80] + } + source_ranges = ["0.0.0.0/0"] + ... + } + - pattern-inside: | + resource "google_compute_firewall" "..." { + ... + allow { + protocol = "tcp" + ports = [..., "80", ...] + } + source_ranges = ["0.0.0.0/0"] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-ip-forward.gcp-compute-ip-forward + languages: + - hcl + message: "Ensure that IP forwarding is not enabled on Instances. This lets the instance act as a traffic router and receive traffic not intended for it, which may route traffic through unintended passages.\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_compute_instance" "..." { + ... + can_ip_forward = true + ... + } + severity: INFO + - id: terraform.gcp.security.gcp-compute-os-login.gcp-compute-os-login + languages: + - hcl + message: "Ensure that no instance in the project overrides the project setting for enabling OSLogin (OSLogin needs to be enabled in project metadata for all instances)\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_compute_instance" "..." { + ... + metadata = { + enable-oslogin = false + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-project-os-login.gcp-compute-project-os-login + languages: + - hcl + message: "Ensure oslogin is enabled for a Project\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_compute_project_metadata" "..." { + ... + } + - pattern-not-inside: | + resource "google_compute_project_metadata" "..." { + ... + metadata = { + enable-oslogin = "True" + } + ... + } + - pattern-not-inside: | + resource "google_compute_project_metadata" "..." { + ... + metadata = { + enable-oslogin = True + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-public-ip.gcp-compute-public-ip + languages: + - hcl + message: "Ensure that Compute instances do not have public IP addresses\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_compute_instance" "..." { + ... + network_interface { + ... + network = "default" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-serial-ports.gcp-compute-serial-ports + languages: + - hcl + message: "Ensure 'Enable connecting to serial ports' is not enabled for VM Instance\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_compute_instance" "..." { + ... + metadata = { + serial-port-enable = true + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-ssl-policy.gcp-compute-ssl-policy + languages: + - hcl + message: Ensure no HTTPS or SSL proxy load balancers permit SSL policies with weak cipher suites + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_compute_ssl_policy" "..." { + ... + profile = "MODERN" + ... + } + - pattern-inside: | + resource "google_compute_ssl_policy" "..." { + ... + profile = "CUSTOM" + custom_features = [..., "TLS_RSA_WITH_AES_256_GCM_SHA384", ...] + ... + } + - pattern-not-inside: | + resource "google_compute_ssl_policy" "..." { + ... + profile = "MODERN" + min_tls_version = "TLS_1_2" + ... + } + - pattern-not-inside: | + resource "google_compute_ssl_policy" "..." { + ... + profile = "CUSTOM" + custom_features = ["TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-compute-template-ip-forward.gcp-compute-template-ip-forward + languages: + - hcl + message: Ensure that IP forwarding is not enabled on Instances. This lets the instance act as a traffic router and receive traffic not intended for it, which may route traffic through unintended passages. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/disable-ip-forwarding.html + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_compute_instance_template" "..." { + ... + can_ip_forward = true + ... + } + severity: INFO + - id: terraform.gcp.security.gcp-compute-template-public-ip.gcp-compute-template-public-ip + languages: + - hcl + message: "Ensure that Compute instances do not have public IP addresses\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_compute_instance_template" "..." { + ... + network_interface { + ... + network = "default" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-dataflow-job-encrypted-with-cmk.gcp-dataflow-job-encrypted-with-cmk + languages: + - hcl + message: Ensure data flow jobs are encrypted with Customer Supplied Encryption Keys (CSEK) + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_dataflow_job" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_dataflow_job" $ANYTHING { + ... + kms_key_name = ... + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-dataflow-private-job.gcp-dataflow-private-job + languages: + - hcl + message: Ensure Dataflow jobs are private + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_dataflow_job" "..." { + ... + } + - pattern-not-inside: | + resource "google_dataflow_job" "..." { + ... + ip_configuration = "WORKER_IP_PRIVATE" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-datafusion-private-instance.gcp-datafusion-private-instance + languages: + - hcl + message: Ensure Data fusion instances are private + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_data_fusion_instance" "..." { + ... + } + - pattern-not-inside: | + resource "google_data_fusion_instance" "..." { + ... + private_instance = true + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-datafusion-stack-driver-logging.gcp-datafusion-stack-driver-logging + languages: + - hcl + message: Ensure Datafusion has stack driver logging enabled. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern-inside: | + resource "google_data_fusion_instance" $ANYTHING { + ... + } + - pattern-not-inside: "resource \"google_data_fusion_instance\" $ANYTHING {\n ...\n enable_stackdriver_logging = true \n ...\n}\n" + severity: WARNING + - id: terraform.gcp.security.gcp-datafusion-stack-driver-monitoring.gcp-datafusion-stack-driver-monitoring + languages: + - hcl + message: Ensure Datafusion has stack driver monitoring enabled. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern-inside: | + resource "google_data_fusion_instance" $ANYTHING { + ... + } + - pattern-not-inside: "resource \"google_data_fusion_instance\" $ANYTHING {\n ...\n enable_stackdriver_monitoring = true \n ...\n}\n" + severity: WARNING + - id: terraform.gcp.security.gcp-dataproc-cluster-encrypted-with-cmk.gcp-dataproc-cluster-encrypted-with-cmk + languages: + - hcl + message: "Ensure Dataproc cluster is encrypted with Customer Supplied Encryption Keys (CSEK)\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_dataproc_cluster" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_dataproc_cluster" $ANYTHING { + ... + cluster_config { + encryption_config { + ... + kms_key_name = ... + ... + } + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-dataproc-cluster-public-ip.gcp-dataproc-cluster-public-ip + languages: + - hcl + message: Ensure Dataproc Clusters do not have public IPs + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_dataproc_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_dataproc_cluster" "..." { + ... + cluster_config { + gce_cluster_config { + ... + internal_ip_only = true + ... + } + ... + } + } + severity: WARNING + - id: terraform.gcp.security.gcp-dataproc-private-cluster-iam-binding.gcp-dataproc-private-cluster-iam-binding + languages: + - hcl + message: Ensure that Dataproc clusters are not anonymously or publicly accessible + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_dataproc_cluster_iam_binding" "..." { + ... + members = [ ..., "allAuthenticatedUsers", ...] + ... + } + - pattern-inside: | + resource "google_dataproc_cluster_iam_binding" "..." { + ... + members = [ ..., "allUsers", ...] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-dataproc-private-cluster-iam-member.gcp-dataproc-private-cluster-iam-member + languages: + - hcl + message: Ensure that Dataproc clusters are not anonymously or publicly accessible + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_dataproc_cluster_iam_member" "..." { + ... + member = "allUsers" + ... + } + - pattern-inside: | + resource "google_dataproc_cluster_iam_member" "..." { + ... + member = "allAuthenticatedUsers" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-dns-key-specs-rsasha1.gcp-dns-key-specs-rsasha1 + languages: + - hcl + message: "Ensure that RSASHA1 is not used for the zone-signing and key-signing keys in Cloud DNS DNSSEC\t" + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_dns_managed_zone" "..." { + ... + dnssec_config { + ... + default_key_specs { + ... + algorithm = "rsasha1" + key_type = "zoneSigning" + ... + } + ... + } + ... + } + - pattern-inside: | + resource "google_dns_managed_zone" "..." { + ... + dnssec_config { + ... + default_key_specs { + ... + algorithm = "rsasha1" + key_type = "keySigning" + ... + } + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-folder-impersonation-roles-iam-binding.gcp-folder-impersonation-roles-iam-binding + languages: + - hcl + message: "Ensure no roles that enable to impersonate and manage all service accounts are used at a folder level\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_folder_iam_binding" "..." { + ... + role = "roles/editor" + members = [ ... ] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-folder-impersonation-roles-iam-member.gcp-folder-impersonation-roles-iam-member + languages: + - hcl + message: "Ensure no roles that enable to impersonate and manage all service accounts are used at a folder level\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_folder_iam_member" "..." { + ... + role = "roles/editor" + member = ... + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-folder-member-default-service-account-iam-binding.gcp-folder-member-default-service-account-iam-binding + languages: + - hcl + message: Ensure Default Service account is not used at a folder level + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_folder_iam_binding" "..." { + ... + members = [..., $MEMBER, ...] + ... + } + - metavariable-regex: + metavariable: $MEMBER + regex: ((.*)-compute@appspot.gserviceaccount.com) + severity: WARNING + - id: terraform.gcp.security.gcp-folder-member-default-service-account-iam-member.gcp-folder-member-default-service-account-iam-member + languages: + - hcl + message: Ensure Default Service account is not used at a folder level + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_folder_iam_member" "..." { + ... + member = $MEMBER + ... + } + - metavariable-regex: + metavariable: $MEMBER + regex: ((.*)-compute@developer.gserviceaccount.com) + severity: WARNING + - id: terraform.gcp.security.gcp-gke-basic-auth.gcp-gke-basic-auth + languages: + - hcl + message: "Ensure GKE basic auth is disabled\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + master_auth { + client_certificate_config { + ... + } + } + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + master_auth { + ... + username = "" + password = "" + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-client-certificate-disabled.gcp-gke-client-certificate-disabled + languages: + - hcl + message: Ensure client certificate authentication to Kubernetes Engine Clusters is disabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + master_auth { + ... + client_certificate_config { + ... + issue_client_certificate = false + ... + } + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-cluster-logging.gcp-gke-cluster-logging + languages: + - hcl + message: Ensure logging is set to Enabled on Kubernetes Engine Clusters + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_container_cluster" $ANYTHING { + ... + logging_service = "none" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-enabled-vpc-flow-logs.gcp-gke-enabled-vpc-flow-logs + languages: + - hcl + message: Enable VPC Flow Logs and Intranode Visibility + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern-inside: | + resource "google_container_cluster" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" $ANYTHING { + ... + enable_intranode_visibility = true + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-ensure-integrity-monitoring.gcp-gke-ensure-integrity-monitoring + languages: + - hcl + message: Ensure Integrity Monitoring for Shielded GKE Nodes is Enabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern-inside: "resource \"google_container_cluster\" $ANYTHING {\n ...\n node_config {\n ...\n shielded_instance_config {\n enable_integrity_monitoring = false\n }\n ...\n } \n ...\n}\n" + severity: WARNING + - id: terraform.gcp.security.gcp-gke-kubernetes-rbac-google-groups.gcp-gke-kubernetes-rbac-google-groups + languages: + - hcl + message: Manage Kubernetes RBAC users with Google Groups for GKE + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + authenticator_groups_config { + ... + security_group = "..." + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-legacy-auth-enabled.gcp-gke-legacy-auth-enabled + languages: + - hcl + message: Ensure Legacy Authorization is set to Disabled on Kubernetes Engine Clusters + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + enable_legacy_abac = true + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-legacy-instance-metadata-disabled.gcp-gke-legacy-instance-metadata-disabled + languages: + - hcl + message: Ensure legacy Compute Engine instance metadata APIs are Disabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + min_master_version = 1.12 + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + min_master_version = 1.13 + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-master-authz-networks-enabled.gcp-gke-master-authz-networks-enabled + languages: + - hcl + message: Ensure master authorized networks is set to enabled in GKE clusters + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + master_authorized_networks_config { + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-monitoring-enabled.gcp-gke-monitoring-enabled + languages: + - hcl + message: Ensure monitoring is set to Enabled on Kubernetes Engine Clusters + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern-inside: "resource \"google_container_cluster\" $ANYTHING {\n ...\n monitoring_service = \"none\" \n ...\n}\n" + severity: WARNING + - id: terraform.gcp.security.gcp-gke-network-policy-enabled.gcp-gke-network-policy-enabled + languages: + - hcl + message: Ensure Network Policy is enabled on Kubernetes Engine Clusters + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + network_policy { + ... + enabled = false + ... + } + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + datapath_provider = "ADVANCED_DATAPATH" + network_policy { + ... + enabled = false + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-nodepool-integrity-monitoring.gcp-gke-nodepool-integrity-monitoring + languages: + - hcl + message: Ensure Integrity Monitoring for Shielded GKE Nodes is Enabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern-inside: "resource \"google_container_node_pool\" $ANYTHING {\n ...\n node_config {\n ...\n shielded_instance_config {\n enable_integrity_monitoring = false\n }\n ...\n } \n ...\n}\n" + severity: WARNING + - id: terraform.gcp.security.gcp-gke-pod-security-policy-enabled.gcp-gke-pod-security-policy-enabled + languages: + - hcl + message: Ensure PodSecurityPolicy controller is enabled on the Kubernetes Engine Clusters + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + pod_security_policy_config { + ... + enabled = true + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-private-cluster-config.gcp-gke-private-cluster-config + languages: + - hcl + message: Ensure Kubernetes Cluster is created with Private cluster enabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + private_cluster_config { + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-public-control-plane.gcp-gke-public-control-plane + languages: + - hcl + message: Ensure GKE Control Plane is not public + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + master_authorized_networks_config { + ... + cidr_blocks { + ... + } + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-gke-secure-boot-for-shielded-nodes.gcp-gke-secure-boot-for-shielded-nodes + languages: + - hcl + message: "Ensure Secure Boot for Shielded GKE Nodes is Enabled\t" + metadata: + category: best-practice + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_container_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "google_container_cluster" "..." { + ... + shielded_instance_config { + ... + enable_secure_boot = true + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-insecure-load-balancer-tls-version.gcp-insecure-load-balancer-tls-version + languages: + - terraform + message: Detected GCP Load Balancer to be using an insecure version of TLS. To fix this set your "min_tls_version" to "TLS_1_2" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - audit + technology: + - gcp + - terraform + patterns: + - pattern: | + resource "google_compute_ssl_policy" $ANYTHING { + ... + min_tls_version = "..." + ... + } + - pattern-not: | + resource "google_compute_ssl_policy" $ANYTHING { + ... + min_tls_version = "TLS_1_2" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-kms-prevent-destroy.gcp-kms-prevent-destroy + languages: + - hcl + message: Ensure KMS keys are protected from deletion + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_kms_crypto_key" "..." { + ... + } + - pattern-not-inside: | + resource "google_kms_crypto_key" "..." { + ... + lifecycle { + prevent_destroy = true + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-memory-store-for-redis-auth-enabled.gcp-memory-store-for-redis-auth-enabled + languages: + - hcl + message: Ensure Memorystore for Redis has AUTH enabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_redis_instance" "..." { + ... + } + - pattern-not-inside: | + resource "google_redis_instance" "..." { + ... + auth_enabled = true + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-memory-store-for-redis-intransit-encryption.gcp-memory-store-for-redis-intransit-encryption + languages: + - hcl + message: Ensure Memorystore for Redis uses intransit encryption + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_redis_instance" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_redis_instance" $ANYTHING { + ... + transit_encryption_mode = "SERVER_AUTHENTICATION" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-org-impersonation-roles-iam-binding.gcp-org-impersonation-roles-iam-binding + languages: + - hcl + message: "Ensure no roles that enable to impersonate and manage all service accounts are used at an organization level\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_organization_iam_binding" "..." { + ... + role = "roles/editor" + members = [ ... ] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-org-impersonation-roles-iam-member.gcp-org-impersonation-roles-iam-member + languages: + - hcl + message: "Ensure no roles that enable to impersonate and manage all service accounts are used at an organization level\t" + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_organization_iam_member" "..." { + ... + role = "roles/editor" + member = ... + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-org-member-default-service-account-iam-binding.gcp-org-member-default-service-account-iam-binding + languages: + - hcl + message: Ensure default service account is not used at an organization level + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_organization_iam_binding" "..." { + ... + members = [..., $MEMBER, ...] + ... + } + - metavariable-regex: + metavariable: $MEMBER + regex: ((.*)-compute@developer.gserviceaccount.com) + severity: WARNING + - id: terraform.gcp.security.gcp-org-member-default-service-account-iam-member.gcp-org-member-default-service-account-iam-member + languages: + - hcl + message: Ensure default service account is not used at an organization level + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_organization_iam_member" "..." { + ... + member = $MEMBER + ... + } + - metavariable-regex: + metavariable: $MEMBER + regex: ((.*)-compute@developer.gserviceaccount.com) + severity: WARNING + - id: terraform.gcp.security.gcp-project-default-network.gcp-project-default-network + languages: + - hcl + message: Ensure that the default network does not exist in a project. Set auto_create_network to `false`. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_project" "..." { + ... + } + - pattern-not-inside: | + resource "google_project" "..." { + ... + auto_create_network = false + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-project-member-default-service-account-iam-binding.gcp-project-member-default-service-account-iam-binding + languages: + - hcl + message: Ensure Default Service account is not used at a project level + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_project_iam_binding" "..." { + ... + members = [..., $MEMBER, ...] + ... + } + - metavariable-regex: + metavariable: $MEMBER + regex: ((.*)-compute@developer.gserviceaccount.com) + severity: WARNING + - id: terraform.gcp.security.gcp-project-member-default-service-account-iam-member.gcp-project-member-default-service-account-iam-member + languages: + - hcl + message: Ensure Default Service account is not used at a project level + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_project_iam_member" "..." { + ... + member = $MEMBER + ... + } + - metavariable-regex: + metavariable: $MEMBER + regex: ((.*)-compute@developer.gserviceaccount.com) + severity: WARNING + - id: terraform.gcp.security.gcp-project-service-account-user-iam-binding.gcp-project-service-account-user-iam-binding + languages: + - hcl + message: Ensure that IAM users are not assigned the Service Account User or Service Account Token Creator roles at project level + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_project_iam_binding" "..." { + ... + role = "roles/iam.serviceAccountTokenCreator" + ... + } + - pattern-inside: | + resource "google_project_iam_binding" "..." { + ... + role = "roles/iam.serviceAccountUser" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-project-service-account-user-iam-member.gcp-project-service-account-user-iam-member + languages: + - hcl + message: Ensure that IAM users are not assigned the Service Account User or Service Account Token Creator roles at project level + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_project_iam_member" "..." { + ... + role = "roles/iam.serviceAccountTokenCreator" + ... + } + - pattern-inside: | + resource "google_project_iam_member" "..." { + ... + role = "roles/iam.serviceAccountUser" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-pubsub-encrypted-with-cmk.gcp-pubsub-encrypted-with-cmk + languages: + - hcl + message: Ensure PubSub Topics are encrypted with Customer Supplied Encryption Keys (CSEK) + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_pubsub_topic" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_pubsub_topic" $ANYTHING { + ... + kms_key_name = ... + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-pubsub-private-topic-iam-binding.gcp-pubsub-private-topic-iam-binding + languages: + - hcl + message: Ensure that Pub/Sub Topics are not anonymously or publicly accessible + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_pubsub_topic_iam_binding" "..." { + ... + members = [ ..., "allAuthenticatedUsers", ...] + ... + } + - pattern-inside: | + resource "google_pubsub_topic_iam_binding" "..." { + ... + members = [ ..., "allUsers", ...] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-pubsub-private-topic-iam-member.gcp-pubsub-private-topic-iam-member + languages: + - hcl + message: Ensure that Pub/Sub Topics are not anonymously or publicly accessible + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_pubsub_topic_iam_member" "..." { + ... + member = "allUsers" + ... + } + - pattern-inside: | + resource "google_pubsub_topic_iam_member" "..." { + ... + member = "allAuthenticatedUsers" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-run-private-service-iam-binding.gcp-run-private-service-iam-binding + languages: + - hcl + message: Ensure that GCP Cloud Run services are not anonymously or publicly accessible + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_cloud_run_service_iam_binding" "..." { + ... + members = [ ..., "allAuthenticatedUsers", ...] + ... + } + - pattern-inside: | + resource "google_cloud_run_service_iam_binding" "..." { + ... + members = [ ..., "allUsers", ...] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-run-private-service-iam-member.gcp-run-private-service-iam-member + languages: + - hcl + message: Ensure that GCP Cloud Run services are not anonymously or publicly accessible + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_cloud_run_service_iam_member" "..." { + ... + member = "allAuthenticatedUsers" + ... + } + - pattern-inside: | + resource "google_cloud_run_service_iam_member" "..." { + ... + member = "allUsers" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-spanner-database-encrypted-with-cmk.gcp-spanner-database-encrypted-with-cmk + languages: + - hcl + message: Ensure Spanner Database is encrypted with Customer Supplied Encryption Keys (CSEK) + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_spanner_database" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_spanner_database" $ANYTHING { + ... + encryption_config { + ... + kms_key_name = ... + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-sql-database-require-ssl.gcp-sql-database-require-ssl + languages: + - hcl + message: Ensure all Cloud SQL database instance requires all incoming connections to use SSL + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + } + - pattern-not-inside: | + resource "google_sql_database_instance" "..." { + ... + ip_configuration { + ... + require_ssl = true + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-sql-public-database.gcp-sql-public-database + languages: + - hcl + message: Ensure that Cloud SQL database Instances are not open to the world + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-284: Improper Access Control' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-either: + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + ip_configuration { + ... + authorized_networks { + ... + value = "0.0.0.0/0" + ... + } + ... + } + ... + } + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + ip_configuration { + ... + dynamic "authorized_networks" { + ... + content { + ... + value = "0.0.0.0/0" + ... + } + ... + } + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-sqlserver-no-public-ip.gcp-sqlserver-no-public-ip + languages: + - hcl + message: Ensure Cloud SQL database does not have public IP + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + ip_configuration { + ... + ipv4_enabled = true + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-storage-bucket-not-public-iam-binding.gcp-storage-bucket-not-public-iam-binding + languages: + - hcl + message: Ensure that Container Registry repositories are not anonymously or publicly accessible + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_storage_bucket_iam_binding" "..." { + ... + members = [ ..., "allAuthenticatedUsers", ...] + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-storage-bucket-not-public-iam-member.gcp-storage-bucket-not-public-iam-member + languages: + - hcl + message: Ensure that Container Registry repositories are not anonymously or publicly accessible + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_storage_bucket_iam_member" "..." { + ... + member = "allUsers" + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-storage-bucket-uniform-access.gcp-storage-bucket-uniform-access + languages: + - hcl + message: Ensure that Cloud Storage buckets have uniform bucket-level access enabled + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_storage_bucket" "..." { + ... + } + - pattern-not-inside: | + resource "google_storage_bucket" "..." { + ... + uniform_bucket_level_access = true + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-sub-network-logging-enabled.gcp-sub-network-logging-enabled + languages: + - hcl + message: Ensure that VPC Flow Logs is enabled for every subnet in a VPC Network + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_compute_subnetwork" $ANYTHING { + ... + } + - pattern-not-inside: "resource \"google_compute_subnetwork\" $ANYTHING {\n ...\n log_config {\n ...\n } \n ...\n}\n" + severity: WARNING + - id: terraform.gcp.security.gcp-sub-network-private-google-enabled.gcp-sub-network-private-google-enabled + languages: + - hcl + message: Ensure that private_ip_google_access is enabled for Subnet + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_compute_subnetwork" "..." { + ... + } + - pattern-not-inside: | + resource "google_compute_subnetwork" "..." { + ... + private_ip_google_access = true + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-vertexai-dataset-encrypted-with-cmk.gcp-vertexai-dataset-encrypted-with-cmk + languages: + - hcl + message: Ensure Vertex AI datasets uses a CMK (Customer Manager Key) + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_vertex_ai_dataset" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_vertex_ai_dataset" $ANYTHING { + ... + encryption_spec { + ... + kms_key_name = ... + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-vertexai-metadata-store-encrypted-with-cmk.gcp-vertexai-metadata-store-encrypted-with-cmk + languages: + - hcl + message: Ensure Vertex AI Metadata Store uses a CMK (Customer Manager Key) + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: | + resource "google_vertex_ai_metadata_store" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "google_vertex_ai_metadata_store" $ANYTHING { + ... + encryption_spec { + ... + kms_key_name = ... + ... + } + ... + } + severity: WARNING + - id: terraform.gcp.security.gcp-vertexai-private-instance.gcp-vertexai-private-instance + languages: + - hcl + message: Ensure Vertex AI instances are private + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_notebooks_instance" "..." { + ... + } + - pattern-not-inside: | + resource "google_notebooks_instance" "..." { + ... + no_public_ip = true + ... + } + severity: WARNING + - id: terraform.lang.security.ec2-imdsv1-optional.ec2-imdsv1-optional + languages: + - hcl + message: AWS EC2 Instance allowing use of the IMDSv1 + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#metadata-options + subcategory: + - vuln + technology: + - terraform + - aws + pattern-either: + - patterns: + - pattern: http_tokens = "optional" + - pattern-inside: | + metadata_options { ... } + - patterns: + - pattern: | + resource "aws_instance" "$NAME" { + ... + } + - pattern-not: | + resource "aws_instance" "$NAME" { + ... + metadata_options { + ... + http_tokens = "required" + ... + } + ... + } + - pattern-not: | + resource "aws_instance" "$NAME" { + ... + metadata_options { + ... + http_tokens = "optional" + ... + } + ... + } + - pattern-not: | + resource "aws_instance" "$NAME" { + ... + metadata_options { + ... + http_endpoint = "disabled" + ... + } + ... + } + severity: ERROR + - id: terraform.lang.security.ecr-image-scan-on-push.ecr-image-scan-on-push + languages: + - hcl + message: The ECR Repository isn't configured to scan images on push + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-1104: Use of Unmaintained Third Party Components' + impact: LOW + likelihood: LOW + owasp: + - A06:2021 - Vulnerable and Outdated Components + references: + - https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: resource + - pattern-not-inside: | + resource "aws_ecr_repository" "..." { + ... + image_scanning_configuration { + ... + scan_on_push=true + ... + } + ... + } + - pattern-inside: | + resource "aws_ecr_repository" "..." { + ... + } + severity: WARNING + - id: terraform.lang.security.eks-insufficient-control-plane-logging.eks-insufficient-control-plane-logging + languages: + - hcl + message: Missing EKS control plane logging. It is recommended to enable at least Kubernetes API server component logs ("api") and audit logs ("audit") of the EKS control plane through the enabled_cluster_log_types attribute. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A10:2017 - Insufficient Logging & Monitoring + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_cluster#enabling-control-plane-logging + - https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + name = ... + - pattern-inside: | + resource "aws_eks_cluster" "..." { + ... + } + - pattern-not-inside: | + resource "aws_eks_cluster" "..." { + ... + enabled_cluster_log_types = [..., "api", ..., "audit", ...] + ... + } + - pattern-not-inside: | + resource "aws_eks_cluster" "..." { + ... + enabled_cluster_log_types = [..., "audit", ..., "api", ...] + ... + } + severity: WARNING + - id: terraform.lang.security.eks-public-endpoint-enabled.eks-public-endpoint-enabled + languages: + - hcl + message: The vpc_config resource inside the eks cluster has not explicitly disabled public endpoint access + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource + - pattern-inside: | + resource "aws_eks_cluster" "..." {...} + - pattern-not-inside: | + resource "aws_eks_cluster" "..."{ + ... + vpc_config{ + ... + endpoint_public_access = false + ... + } + ... + } + severity: WARNING + - id: terraform.lang.security.elastic-search-encryption-at-rest.elastic-search-encryption-at-rest + languages: + - hcl + message: Encryption at rest is not enabled for the elastic search domain resource + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: | + resource + - pattern-not-inside: | + resource "aws_elasticsearch_domain" "..."{ + ... + encrypt_at_rest{ + ... + enabled = true + ... + } + ... + } + - pattern-inside: | + resource "aws_elasticsearch_domain" "..." {...} + severity: WARNING + - id: terraform.lang.security.iam.no-iam-admin-privileges.no-iam-admin-privileges + languages: + - hcl + message: IAM policies that allow full "*-*" admin privileges violates the principle of least privilege. This allows an attacker to take full control over all AWS account resources. Instead, give each user more fine-grained control with only the privileges they need. $TYPE + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-269: Improper Privilege Management' + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://github.com/bridgecrewio/checkov/blob/master/checkov/terraform/checks/data/aws/AdminPolicyDocument.py + subcategory: + - audit + technology: + - terraform + - aws + pattern-either: + - patterns: + - pattern-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ... + ] + ... + }) + ... + } + - pattern-not-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ..., + {... Effect = "Deny" ...}, + ... + ] + ... + }) + ... + } + - patterns: + - pattern: | + {..., Action = "*", ...} + - pattern: | + {..., Resource = "*", ...} + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: | + "aws_iam_role_policy" + - pattern: | + "aws_iam_policy" + - pattern: | + "aws_iam_user_policy" + - pattern: | + "aws_iam_group_policy" + - patterns: + - pattern-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + } + ... + } + - pattern-not-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + effect = "Deny" + ... + } + ... + } + - patterns: + - pattern: | + {..., resources = ["*"], ...} + - pattern: | + {..., actions = ["*"], ...} + severity: WARNING + - id: terraform.lang.security.iam.no-iam-creds-exposure.no-iam-creds-exposure + languages: + - hcl + message: Ensure IAM policies don't allow credentials exposure. Credentials exposure actions return credentials as part of the API response, and can possibly lead to leaking important credentials. Instead, use another action that doesn't return sensitive data as part of the API response. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://cloudsplaining.readthedocs.io/en/latest/glossary/credentials-exposure/ + - https://github.com/bridgecrewio/checkov/blob/ca830e14745c2c8e1b941985f305abe985d7f1f9/checkov/terraform/checks/data/aws/IAMCredentialsExposure.py + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ... + ] + ... + }) + ... + } + - pattern-not-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ..., + {... Effect = "Deny" ...}, + ... + ] + ... + }) + ... + } + - pattern: | + Action = $ACTION + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: | + "aws_iam_role_policy" + - pattern: | + "aws_iam_policy" + - pattern: | + "aws_iam_user_policy" + - pattern: | + "aws_iam_group_policy" + - patterns: + - pattern-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + } + ... + } + - pattern-not-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + effect = "Deny" + ... + } + ... + } + - pattern: | + actions = [..., $ACTION, ...] + - metavariable-pattern: + metavariable: $ACTION + pattern-either: + - pattern: | + "chime:CreateApiKey" + - pattern: | + "codepipeline:PollForJobs" + - pattern: | + "cognito-identity:GetOpenIdToken" + - pattern: | + "cognito-identity:GetOpenIdTokenForDeveloperEdentity" + - pattern: | + "cognito-identity:GetCredentialsForIdentity" + - pattern: | + "connect:GetFederationToken" + - pattern: | + "connect:GetFederationTokens" + - pattern: | + "ec2:GetPasswordData" + - pattern: | + "ecr:GetAuthorizationToken" + - pattern: | + "gamelift:RequestUploadCredentials" + - pattern: | + "iam:CreateAccessKey" + - pattern: | + "iam:CreateLoginProfile" + - pattern: | + "iam:CreateServiceSpecificCredential" + - pattern: | + "iam:ResetServiceSpecificCredential" + - pattern: | + "iam:UpdateAccessKey" + - pattern: | + "lightsail:GetInstanceAccessDetails" + - pattern: | + "lightsail:GetRelationalDatabaseMasterUserPassword" + - pattern: | + "rds-db:Connect" + - pattern: | + "redshift:GetClusterCredentials" + - pattern: | + "sso:GetRoleCredentials" + - pattern: | + "mediapackage:RotateChannelCredentials" + - pattern: | + "mediapackage:RotateIngestEndpointCredentials" + - pattern: | + "sts:AssumeRole" + - pattern: | + "sts:AssumeRoleWithSaml" + - pattern: | + "sts:AssumeRoleWithWebIdentity" + - pattern: | + "sts:GetFederationToken" + - pattern: | + "sts:GetSessionToken" + - pattern: | + "ec2:*" + - pattern: | + "codepipeline:*" + - pattern: | + "rds-db:*" + - pattern: | + "connect:*" + - pattern: | + "iam:*" + - pattern: | + "ecr:*" + - pattern: | + "sts:*" + - pattern: | + "chime:*" + - pattern: | + "mediapackage:*" + - pattern: | + "redshift:*" + - pattern: | + "gamelift:*" + - pattern: | + "cognito-identity:*" + - pattern: | + "lightsail:*" + - pattern: | + "sso:*" + severity: WARNING + - id: terraform.lang.security.iam.no-iam-data-exfiltration.no-iam-data-exfiltration + languages: + - hcl + message: Ensure that IAM policies don't allow data exfiltration actions that are not resource-constrained. This can allow the user to read sensitive data they don't need to read. Instead, make sure that the user granted these privileges are given these permissions on specific resources. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://github.com/bridgecrewio/checkov/blob/ca830e14745c2c8e1b941985f305abe985d7f1f9/checkov/terraform/checks/data/aws/IAMDataExfiltration.py + - https://cloudsplaining.readthedocs.io/en/latest/glossary/data-exfiltration/ + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ..., + {... Resource = "*" ...}, + ... + ] + ... + }) + ... + } + - pattern-not-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ..., + {... Effect = "Deny" ...}, + ... + ] + ... + }) + ... + } + - pattern: | + Action = $ACTION + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: | + "aws_iam_role_policy" + - pattern: | + "aws_iam_policy" + - pattern: | + "aws_iam_user_policy" + - pattern: | + "aws_iam_group_policy" + - patterns: + - pattern-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + resources = ["*"] + ... + } + ... + } + - pattern-not-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + effect = "Deny" + ... + } + ... + } + - pattern: | + actions = [..., $ACTION, ...] + - metavariable-pattern: + metavariable: $ACTION + pattern-either: + - pattern: | + "s3:GetObject" + - pattern: | + "ssm:GetParameter*" + - pattern: | + "secretsmanager:GetSecretValue" + - pattern: | + "rds:CopyDBSnapshot" + - pattern: | + "rds:CreateDBSnapshot" + - pattern: | + "ssm:*" + - pattern: | + "s3:*" + - pattern: | + "rds:*" + - pattern: | + "rn: secretsmanager:*" + severity: WARNING + - id: terraform.lang.security.iam.no-iam-priv-esc-funcs.no-iam-priv-esc-funcs + languages: + - hcl + message: Ensure that actions that can result in privilege escalation are not used. These actions could potentially result in an attacker gaining full administrator access of an AWS account. Try not to use these actions. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + references: + - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/ + - https://cloudsplaining.readthedocs.io/en/latest/glossary/privilege-escalation/ + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ... + ] + ... + }) + ... + } + - pattern-not-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ..., + {... Effect = "Deny" ...}, + ... + ] + ... + }) + ... + } + - pattern: Action = $ACTION + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: | + "aws_iam_role_policy" + - pattern: | + "aws_iam_policy" + - pattern: | + "aws_iam_user_policy" + - pattern: | + "aws_iam_group_policy" + - patterns: + - pattern-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + } + ... + } + - pattern-not-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + effect = "Deny" + ... + } + ... + } + - pattern: | + actions = [..., $ACTION, ...] + - metavariable-pattern: + metavariable: $ACTION + pattern-either: + - pattern: | + "iam:AddUserToGroup" + - pattern: | + "iam:CreatePolicyVersion" + - pattern: | + "iam:SetDefaultPolicyVersion" + - pattern: | + "iam:AttachUserPolicy" + - pattern: | + "iam:AttachGroupPolicy" + - pattern: | + "iam:AttachRolePolicy" + - pattern: | + "iam:PutUserPolicy" + - pattern: | + "iam:PutGroupPolicy" + - pattern: | + "iam:PutRolePolicy" + - pattern: | + "glue:UpdateDevEndpoint" + - pattern: | + "iam:*" + - pattern: | + "glue:*" + severity: WARNING + - id: terraform.lang.security.iam.no-iam-priv-esc-other-users.no-iam-priv-esc-other-users + languages: + - hcl + message: Ensure that IAM policies with permissions on other users don't allow for privilege escalation. This can lead to an attacker gaining full administrator access of AWS accounts. Instead, specify which user the permission should be used on or do not use the listed actions. $RESOURCE + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-269: Improper Privilege Management' + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://cloudsplaining.readthedocs.io/en/latest/glossary/privilege-escalation/ + - https://github.com/bridgecrewio/checkov/blob/ca830e14745c2c8e1b941985f305abe985d7f1f9/checkov/terraform/checks/data/aws/IAMPrivilegeEscalation.py + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ..., + {... Resource = $RESOURCE ...}, + ... + ] + ... + }) + ... + } + - pattern-not-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ..., + {... Effect = "Deny" ...}, + ... + ] + ... + }) + ... + } + - pattern: | + Action = $ACTION + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: | + "aws_iam_role_policy" + - pattern: | + "aws_iam_policy" + - pattern: | + "aws_iam_user_policy" + - pattern: | + "aws_iam_group_policy" + - patterns: + - pattern-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + resources = $RESOURCE + ... + } + ... + } + - pattern-not-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + effect = "Deny" + ... + } + ... + } + - pattern: | + actions = [..., $ACTION, ...] + - metavariable-pattern: + metavariable: $RESOURCE + pattern-either: + - pattern-regex: .*\*.* + - metavariable-pattern: + metavariable: $ACTION + pattern-either: + - pattern: | + "iam:CreateAccessKey" + - pattern: | + "iam:CreateLoginProfile" + - pattern: | + "iam:UpdateLoginProfile" + - pattern: | + "iam:*" + severity: WARNING + - id: terraform.lang.security.iam.no-iam-priv-esc-roles.no-iam-priv-esc-roles + languages: + - hcl + message: Ensure that groups of actions that include iam:PassRole and could result in privilege escalation are not all allowed for the same user. These actions could result in an attacker gaining full admin access of an AWS account. Try not to use these actions in conjuction. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-269: Improper Privilege Management' + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://cloudsplaining.readthedocs.io/en/latest/glossary/privilege-escalation/ + - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/ + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ... + ] + ... + }) + ... + } + - pattern-not-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ..., + {... Effect = "Deny" ...}, + ... + ] + ... + }) + ... + } + - pattern: | + Action = $ACTION + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: | + "aws_iam_role_policy" + - pattern: | + "aws_iam_policy" + - pattern: | + "aws_iam_user_policy" + - pattern: | + "aws_iam_group_policy" + - patterns: + - pattern-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + } + ... + } + - pattern-not-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + effect = "Deny" + ... + } + ... + } + - pattern: | + actions = $ACTION + - metavariable-pattern: + metavariable: $ACTION + pattern-either: + - patterns: + - pattern: | + [..., "sts:AssumeRole", ...] + - pattern: | + [..., "iam:UpdateAssumeRolePolicy", ...] + - patterns: + - pattern: | + [..., "iam:PassRole", ...] + - pattern: | + [..., "lambda:CreateFunction", ...] + - pattern: | + [..., "lambda:InvokeFunction", ...] + - patterns: + - pattern: | + [..., "iam:PassRole", ...] + - pattern: | + [..., "lambda:CreateFunction", ...] + - pattern: | + [..., "lambda:CreateEventSourceMapping", ...] + - pattern: | + "lambda:UpdateFunctionCode" + - patterns: + - pattern: | + [..., "iam:PassRole", ...] + - pattern: | + [..., "glue:CreateDevEndpoint", ...] + - patterns: + - pattern: | + [..., "iam:PassRole", ...] + - pattern: | + [..., "cloudformation:CreateStack", ...] + - patterns: + - pattern: | + [..., "iam:PassRole", ...] + - pattern: | + [..., "datapipeline:CreatePipeline", ...] + - pattern: | + [..., "datapipeline:PutPipelineDefinition", ...] + severity: WARNING + - id: terraform.lang.security.iam.no-iam-resource-exposure.no-iam-resource-exposure + languages: + - hcl + message: Ensure IAM policies don't allow resource exposure. These actions can expose AWS resources to the public. For example `ecr:SetRepositoryPolicy` could let an attacker retrieve container images. Instead, use another action that doesn't expose AWS resources. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://cloudsplaining.readthedocs.io/en/latest/glossary/resource-exposure/ + - https://github.com/bridgecrewio/checkov/blob/ca830e14745c2c8e1b941985f305abe985d7f1f9/checkov/terraform/checks/data/aws/IAMPermissionsManagement.py + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ... + ] + ... + }) + ... + } + - pattern-not-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ..., + {... Effect = "Deny" ...}, + ... + ] + ... + }) + ... + } + - pattern: | + Action = $ACTION + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: | + "aws_iam_role_policy" + - pattern: | + "aws_iam_policy" + - pattern: | + "aws_iam_user_policy" + - pattern: | + "aws_iam_group_policy" + - patterns: + - pattern-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + } + ... + } + - pattern-not-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + effect = "Deny" + ... + } + ... + } + - pattern: | + actions = [..., $ACTION, ...] + - metavariable-pattern: + metavariable: $ACTION + pattern-either: + - pattern: | + "acm-pca:CreatePermission" + - pattern: | + "acm-pca:DeletePermission" + - pattern: | + "acm-pca:DeletePolicy" + - pattern: | + "acm-pca:PutPolicy" + - pattern: | + "apigateway:UpdateRestApiPolicy" + - pattern: | + "backup:DeleteBackupVaultAccessPolicy" + - pattern: | + "backup:PutBackupVaultAccessPolicy" + - pattern: | + "chime:DeleteVoiceConnectorTerminationCredentials" + - pattern: | + "chime:PutVoiceConnectorTerminationCredentials" + - pattern: | + "cloudformation:SetStackPolicy" + - pattern: | + "cloudsearch:UpdateServiceAccessPolicies" + - pattern: | + "codeartifact:DeleteDomainPermissionsPolicy" + - pattern: | + "codeartifact:DeleteRepositoryPermissionsPolicy" + - pattern: | + "codebuild:DeleteResourcePolicy" + - pattern: | + "codebuild:DeleteSourceCredentials" + - pattern: | + "codebuild:ImportSourceCredentials" + - pattern: | + "codebuild:PutResourcePolicy" + - pattern: | + "codeguru-profiler:PutPermission" + - pattern: | + "codeguru-profiler:RemovePermission" + - pattern: | + "codestar:AssociateTeamMember" + - pattern: | + "codestar:CreateProject" + - pattern: | + "codestar:DeleteProject" + - pattern: | + "codestar:DisassociateTeamMember" + - pattern: | + "codestar:UpdateTeamMember" + - pattern: | + "cognito-identity:CreateIdentityPool" + - pattern: | + "cognito-identity:DeleteIdentities" + - pattern: | + "cognito-identity:DeleteIdentityPool" + - pattern: | + "cognito-identity:GetId" + - pattern: | + "cognito-identity:MergeDeveloperIdentities" + - pattern: | + "cognito-identity:SetIdentityPoolRoles" + - pattern: | + "cognito-identity:UnlinkDeveloperIdentity" + - pattern: | + "cognito-identity:UnlinkIdentity" + - pattern: | + "cognito-identity:UpdateIdentityPool" + - pattern: | + "deeplens:AssociateServiceRoleToAccount" + - pattern: | + "ds:CreateConditionalForwarder" + - pattern: | + "ds:CreateDirectory" + - pattern: | + "ds:CreateMicrosoftAD" + - pattern: | + "ds:CreateTrust" + - pattern: | + "ds:ShareDirectory" + - pattern: | + "ec2:CreateNetworkInterfacePermission" + - pattern: | + "ec2:DeleteNetworkInterfacePermission" + - pattern: | + "ec2:ModifySnapshotAttribute" + - pattern: | + "ec2:ModifyVpcEndpointServicePermissions" + - pattern: | + "ec2:ResetSnapshotAttribute" + - pattern: | + "ecr:DeleteRepositoryPolicy" + - pattern: | + "ecr:SetRepositoryPolicy" + - pattern: | + "elasticfilesystem:DeleteFileSystemPolicy" + - pattern: | + "elasticfilesystem:PutFileSystemPolicy" + - pattern: | + "elasticmapreduce:PutBlockPublicAccessConfiguration" + - pattern: | + "es:CreateElasticsearchDomain" + - pattern: | + "es:UpdateElasticsearchDomainConfig" + - pattern: | + "glacier:AbortVaultLock" + - pattern: | + "glacier:CompleteVaultLock" + - pattern: | + "glacier:DeleteVaultAccessPolicy" + - pattern: | + "glacier:InitiateVaultLock" + - pattern: | + "glacier:SetDataRetrievalPolicy" + - pattern: | + "glacier:SetVaultAccessPolicy" + - pattern: | + "glue:DeleteResourcePolicy" + - pattern: | + "glue:PutResourcePolicy" + - pattern: | + "greengrass:AssociateServiceRoleToAccount" + - pattern: | + "health:DisableHealthServiceAccessForOrganization" + - pattern: | + "health:EnableHealthServiceAccessForOrganization" + - pattern: | + "iam:AddClientIDToOpenIDConnectProvider" + - pattern: | + "iam:AddRoleToInstanceProfile" + - pattern: | + "iam:AddUserToGroup" + - pattern: | + "iam:AttachGroupPolicy" + - pattern: | + "iam:AttachRolePolicy" + - pattern: | + "iam:AttachUserPolicy" + - pattern: | + "iam:ChangePassword" + - pattern: | + "iam:CreateAccessKey" + - pattern: | + "iam:CreateAccountAlias" + - pattern: | + "iam:CreateGroup" + - pattern: | + "iam:CreateInstanceProfile" + - pattern: | + "iam:CreateLoginProfile" + - pattern: | + "iam:CreateOpenIDConnectProvider" + - pattern: | + "iam:CreatePolicy" + - pattern: | + "iam:CreatePolicyVersion" + - pattern: | + "iam:CreateRole" + - pattern: | + "iam:CreateSAMLProvider" + - pattern: | + "iam:CreateServiceLinkedRole" + - pattern: | + "iam:CreateServiceSpecificCredential" + - pattern: | + "iam:CreateUser" + - pattern: | + "iam:CreateVirtualMFADevice" + - pattern: | + "iam:DeactivateMFADevice" + - pattern: | + "iam:DeleteAccessKey" + - pattern: | + "iam:DeleteAccountAlias" + - pattern: | + "iam:DeleteAccountPasswordPolicy" + - pattern: | + "iam:DeleteGroup" + - pattern: | + "iam:DeleteGroupPolicy" + - pattern: | + "iam:DeleteInstanceProfile" + - pattern: | + "iam:DeleteLoginProfile" + - pattern: | + "iam:DeleteOpenIDConnectProvider" + - pattern: | + "iam:DeletePolicy" + - pattern: | + "iam:DeletePolicyVersion" + - pattern: | + "iam:DeleteRole" + - pattern: | + "iam:DeleteRolePermissionsBoundary" + - pattern: | + "iam:DeleteRolePolicy" + - pattern: | + "iam:DeleteSAMLProvider" + - pattern: | + "iam:DeleteSSHPublicKey" + - pattern: | + "iam:DeleteServerCertificate" + - pattern: | + "iam:DeleteServiceLinkedRole" + - pattern: | + "iam:DeleteServiceSpecificCredential" + - pattern: | + "iam:DeleteSigningCertificate" + - pattern: | + "iam:DeleteUser" + - pattern: | + "iam:DeleteUserPermissionsBoundary" + - pattern: | + "iam:DeleteUserPolicy" + - pattern: | + "iam:DeleteVirtualMFADevice" + - pattern: | + "iam:DetachGroupPolicy" + - pattern: | + "iam:DetachRolePolicy" + - pattern: | + "iam:DetachUserPolicy" + - pattern: | + "iam:EnableMFADevice" + - pattern: | + "iam:PassRole" + - pattern: | + "iam:PutGroupPolicy" + - pattern: | + "iam:PutRolePermissionsBoundary" + - pattern: | + "iam:PutRolePolicy" + - pattern: | + "iam:PutUserPermissionsBoundary" + - pattern: | + "iam:PutUserPolicy" + - pattern: | + "iam:RemoveClientIDFromOpenIDConnectProvider" + - pattern: | + "iam:RemoveRoleFromInstanceProfile" + - pattern: | + "iam:RemoveUserFromGroup" + - pattern: | + "iam:ResetServiceSpecificCredential" + - pattern: | + "iam:ResyncMFADevice" + - pattern: | + "iam:SetDefaultPolicyVersion" + - pattern: | + "iam:SetSecurityTokenServicePreferences" + - pattern: | + "iam:UpdateAccessKey" + - pattern: | + "iam:UpdateAccountPasswordPolicy" + - pattern: | + "iam:UpdateAssumeRolePolicy" + - pattern: | + "iam:UpdateGroup" + - pattern: | + "iam:UpdateLoginProfile" + - pattern: | + "iam:UpdateOpenIDConnectProviderThumbprint" + - pattern: | + "iam:UpdateRole" + - pattern: | + "iam:UpdateRoleDescription" + - pattern: | + "iam:UpdateSAMLProvider" + - pattern: | + "iam:UpdateSSHPublicKey" + - pattern: | + "iam:UpdateServerCertificate" + - pattern: | + "iam:UpdateServiceSpecificCredential" + - pattern: | + "iam:UpdateSigningCertificate" + - pattern: | + "iam:UpdateUser" + - pattern: | + "iam:UploadSSHPublicKey" + - pattern: | + "iam:UploadServerCertificate" + - pattern: | + "iam:UploadSigningCertificate" + - pattern: | + "imagebuilder:PutComponentPolicy" + - pattern: | + "imagebuilder:PutImagePolicy" + - pattern: | + "imagebuilder:PutImageRecipePolicy" + - pattern: | + "iot:AttachPolicy" + - pattern: | + "iot:AttachPrincipalPolicy" + - pattern: | + "iot:DetachPolicy" + - pattern: | + "iot:DetachPrincipalPolicy" + - pattern: | + "iot:SetDefaultAuthorizer" + - pattern: | + "iot:SetDefaultPolicyVersion" + - pattern: | + "iotsitewise:CreateAccessPolicy" + - pattern: | + "iotsitewise:DeleteAccessPolicy" + - pattern: | + "iotsitewise:UpdateAccessPolicy" + - pattern: | + "kms:CreateGrant" + - pattern: | + "kms:PutKeyPolicy" + - pattern: | + "kms:RetireGrant" + - pattern: | + "kms:RevokeGrant" + - pattern: | + "lakeformation:BatchGrantPermissions" + - pattern: | + "lakeformation:BatchRevokePermissions" + - pattern: | + "lakeformation:GrantPermissions" + - pattern: | + "lakeformation:PutDataLakeSettings" + - pattern: | + "lakeformation:RevokePermissions" + - pattern: | + "lambda:AddLayerVersionPermission" + - pattern: | + "lambda:AddPermission" + - pattern: | + "lambda:DisableReplication" + - pattern: | + "lambda:EnableReplication" + - pattern: | + "lambda:RemoveLayerVersionPermission" + - pattern: | + "lambda:RemovePermission" + - pattern: | + "license-manager:UpdateServiceSettings" + - pattern: | + "lightsail:GetRelationalDatabaseMasterUserPassword" + - pattern: | + "logs:DeleteResourcePolicy" + - pattern: | + "logs:PutResourcePolicy" + - pattern: | + "mediapackage:RotateIngestEndpointCredentials" + - pattern: | + "mediastore:DeleteContainerPolicy" + - pattern: | + "mediastore:PutContainerPolicy" + - pattern: | + "opsworks:SetPermission" + - pattern: | + "opsworks:UpdateUserProfile" + - pattern: | + "quicksight:CreateAdmin" + - pattern: | + "quicksight:CreateGroup" + - pattern: | + "quicksight:CreateGroupMembership" + - pattern: | + "quicksight:CreateIAMPolicyAssignment" + - pattern: | + "quicksight:CreateUser" + - pattern: | + "quicksight:DeleteGroup" + - pattern: | + "quicksight:DeleteGroupMembership" + - pattern: | + "quicksight:DeleteIAMPolicyAssignment" + - pattern: | + "quicksight:DeleteUser" + - pattern: | + "quicksight:DeleteUserByPrincipalId" + - pattern: | + "quicksight:RegisterUser" + - pattern: | + "quicksight:UpdateDashboardPermissions" + - pattern: | + "quicksight:UpdateGroup" + - pattern: | + "quicksight:UpdateIAMPolicyAssignment" + - pattern: | + "quicksight:UpdateTemplatePermissions" + - pattern: | + "quicksight:UpdateUser" + - pattern: | + "ram:AcceptResourceShareInvitation" + - pattern: | + "ram:AssociateResourceShare" + - pattern: | + "ram:CreateResourceShare" + - pattern: | + "ram:DeleteResourceShare" + - pattern: | + "ram:DisassociateResourceShare" + - pattern: | + "ram:EnableSharingWithAwsOrganization" + - pattern: | + "ram:RejectResourceShareInvitation" + - pattern: | + "ram:UpdateResourceShare" + - pattern: | + "rds:AuthorizeDBSecurityGroupIngress" + - pattern: | + "rds-db:connect" + - pattern: | + "redshift:AuthorizeSnapshotAccess" + - pattern: | + "redshift:CreateClusterUser" + - pattern: | + "redshift:CreateSnapshotCopyGrant" + - pattern: | + "redshift:JoinGroup" + - pattern: | + "redshift:ModifyClusterIamRoles" + - pattern: | + "redshift:RevokeSnapshotAccess" + - pattern: | + "route53resolver:PutResolverRulePolicy" + - pattern: | + "s3:BypassGovernanceRetention" + - pattern: | + "s3:DeleteAccessPointPolicy" + - pattern: | + "s3:DeleteBucketPolicy" + - pattern: | + "s3:ObjectOwnerOverrideToBucketOwner" + - pattern: | + "s3:PutAccessPointPolicy" + - pattern: | + "s3:PutAccountPublicAccessBlock" + - pattern: | + "s3:PutBucketAcl" + - pattern: | + "s3:PutBucketPolicy" + - pattern: | + "s3:PutBucketPublicAccessBlock" + - pattern: | + "s3:PutObjectAcl" + - pattern: | + "s3:PutObjectVersionAcl" + - pattern: | + "secretsmanager:DeleteResourcePolicy" + - pattern: | + "secretsmanager:PutResourcePolicy" + - pattern: | + "secretsmanager:ValidateResourcePolicy" + - pattern: | + "servicecatalog:CreatePortfolioShare" + - pattern: | + "servicecatalog:DeletePortfolioShare" + - pattern: | + "sns:AddPermission" + - pattern: | + "sns:CreateTopic" + - pattern: | + "sns:RemovePermission" + - pattern: | + "sns:SetTopicAttributes" + - pattern: | + "sqs:AddPermission" + - pattern: | + "sqs:CreateQueue" + - pattern: | + "sqs:RemovePermission" + - pattern: | + "sqs:SetQueueAttributes" + - pattern: | + "ssm:ModifyDocumentPermission" + - pattern: | + "sso:AssociateDirectory" + - pattern: | + "sso:AssociateProfile" + - pattern: | + "sso:CreateApplicationInstance" + - pattern: | + "sso:CreateApplicationInstanceCertificate" + - pattern: | + "sso:CreatePermissionSet" + - pattern: | + "sso:CreateProfile" + - pattern: | + "sso:CreateTrust" + - pattern: | + "sso:DeleteApplicationInstance" + - pattern: | + "sso:DeleteApplicationInstanceCertificate" + - pattern: | + "sso:DeletePermissionSet" + - pattern: | + "sso:DeletePermissionsPolicy" + - pattern: | + "sso:DeleteProfile" + - pattern: | + "sso:DisassociateDirectory" + - pattern: | + "sso:DisassociateProfile" + - pattern: | + "sso:ImportApplicationInstanceServiceProviderMetadata" + - pattern: | + "sso:PutPermissionsPolicy" + - pattern: | + "sso:StartSSO" + - pattern: | + "sso:UpdateApplicationInstanceActiveCertificate" + - pattern: | + "sso:UpdateApplicationInstanceDisplayData" + - pattern: | + "sso:UpdateApplicationInstanceResponseConfiguration" + - pattern: | + "sso:UpdateApplicationInstanceResponseSchemaConfiguration" + - pattern: | + "sso:UpdateApplicationInstanceSecurityConfiguration" + - pattern: | + "sso:UpdateApplicationInstanceServiceProviderConfiguration" + - pattern: | + "sso:UpdateApplicationInstanceStatus" + - pattern: | + "sso:UpdateDirectoryAssociation" + - pattern: | + "sso:UpdatePermissionSet" + - pattern: | + "sso:UpdateProfile" + - pattern: | + "sso:UpdateSSOConfiguration" + - pattern: | + "sso:UpdateTrust" + - pattern: | + "sso-directory:AddMemberToGroup" + - pattern: | + "sso-directory:CreateAlias" + - pattern: | + "sso-directory:CreateGroup" + - pattern: | + "sso-directory:CreateUser" + - pattern: | + "sso-directory:DeleteGroup" + - pattern: | + "sso-directory:DeleteUser" + - pattern: | + "sso-directory:DisableUser" + - pattern: | + "sso-directory:EnableUser" + - pattern: | + "sso-directory:RemoveMemberFromGroup" + - pattern: | + "sso-directory:UpdateGroup" + - pattern: | + "sso-directory:UpdatePassword" + - pattern: | + "sso-directory:UpdateUser" + - pattern: | + "sso-directory:VerifyEmail" + - pattern: | + "storagegateway:DeleteChapCredentials" + - pattern: | + "storagegateway:SetLocalConsolePassword" + - pattern: | + "storagegateway:SetSMBGuestPassword" + - pattern: | + "storagegateway:UpdateChapCredentials" + - pattern: | + "waf:DeletePermissionPolicy" + - pattern: | + "waf:PutPermissionPolicy" + - pattern: | + "waf-regional:DeletePermissionPolicy" + - pattern: | + "waf-regional:PutPermissionPolicy" + - pattern: | + "wafv2:CreateWebACL" + - pattern: | + "wafv2:DeletePermissionPolicy" + - pattern: | + "wafv2:DeleteWebACL" + - pattern: | + "wafv2:PutPermissionPolicy" + - pattern: | + "wafv2:UpdateWebACL" + - pattern: | + "worklink:UpdateDevicePolicyConfiguration" + - pattern: | + "workmail:ResetPassword" + - pattern: | + "workmail:ResetUserPassword" + - pattern: | + "xray:PutEncryptionConfig" + - pattern: | + "worklink:*" + - pattern: | + "route53resolver:*" + - pattern: | + "es:*" + - pattern: | + "greengrass:*" + - pattern: | + "redshift:*" + - pattern: | + "license-manager:*" + - pattern: | + "rds:*" + - pattern: | + "lambda:*" + - pattern: | + "elasticfilesystem:*" + - pattern: | + "logs:*" + - pattern: | + "sso:*" + - pattern: | + "waf:*" + - pattern: | + "mediastore:*" + - pattern: | + "acm-pca:*" + - pattern: | + "sso-directory:*" + - pattern: | + "imagebuilder:*" + - pattern: | + "sqs:*" + - pattern: | + "codeguru-profiler:*" + - pattern: | + "wafv2:*" + - pattern: | + "cloudformation:*" + - pattern: | + "xray:*" + - pattern: | + "codeartifact:*" + - pattern: | + "iotsitewise:*" + - pattern: | + "workmail:*" + - pattern: | + "glue:*" + - pattern: | + "deeplens:*" + - pattern: | + "chime:*" + - pattern: | + "mediapackage:*" + - pattern: | + "opsworks:*" + - pattern: | + "ds:*" + - pattern: | + "ram:*" + - pattern: | + "iam:*" + - pattern: | + "waf-regional:*" + - pattern: | + "glacier:*" + - pattern: | + "cloudsearch:*" + - pattern: | + "lakeformation:*" + - pattern: | + "elasticmapreduce:*" + - pattern: | + "quicksight:*" + - pattern: | + "sns:*" + - pattern: | + "ec2:*" + - pattern: | + "health:*" + - pattern: | + "lightsail:*" + - pattern: | + "codestar:*" + - pattern: | + "kms:*" + - pattern: | + "codebuild:*" + - pattern: | + "s3:*" + - pattern: | + "cognito-identity:*" + - pattern: | + "apigateway:*" + - pattern: | + "rds-db:*" + - pattern: | + "iot:*" + - pattern: | + "backup:*" + - pattern: | + "secretsmanager:*" + - pattern: | + "servicecatalog:*" + - pattern: | + "ssm:*" + - pattern: | + "storagegateway:*" + - pattern: | + "ecr:*" + severity: WARNING + - id: terraform.lang.security.iam.no-iam-star-actions.no-iam-star-actions + languages: + - hcl + message: Ensure that no IAM policies allow "*" as a statement's actions. This allows all actions to be performed on the specified resources, and is a violation of the principle of least privilege. Instead, specify the actions that a certain user or policy is allowed to take. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-269: Improper Privilege Management' + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy + - https://github.com/bridgecrewio/checkov/blob/ca830e14745c2c8e1b941985f305abe985d7f1f9/checkov/terraform/checks/data/aws/StarActionPolicyDocument.py + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ... + ] + ... + }) + ... + } + - pattern-not-inside: | + resource $TYPE "..." { + ... + policy = jsonencode({ + ... + Statement = [ + ..., + {... Effect = "Deny" ...}, + ... + ] + ... + }) + ... + } + - pattern-either: + - pattern: Action = "*" + - pattern: Action = ["*"] + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: | + "aws_iam_role_policy" + - pattern: | + "aws_iam_policy" + - pattern: | + "aws_iam_user_policy" + - pattern: | + "aws_iam_group_policy" + - patterns: + - pattern-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + } + ... + } + - pattern-not-inside: | + data aws_iam_policy_document "..." { + ... + statement { + ... + effect = "Deny" + ... + } + ... + } + - pattern: | + actions = ["*"] + severity: WARNING + - id: terraform.lang.security.rds-insecure-password-storage-in-source-code.rds-insecure-password-storage-in-source-code + languages: + - hcl + message: RDS instance or cluster with hardcoded credentials in source code. It is recommended to pass the credentials at runtime, or generate random credentials using the random_password resource. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#master_password + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster#master_password + - https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password + subcategory: + - vuln + technology: + - terraform + - aws + pattern-either: + - patterns: + - pattern: password = "..." + - pattern-inside: | + resource "aws_db_instance" "..." { + ... + } + - patterns: + - pattern: master_password = "..." + - pattern-inside: | + resource "aws_rds_cluster" "..." { + ... + } + severity: WARNING + - id: terraform.lang.security.rds-public-access.rds-public-access + languages: + - hcl + message: RDS instance accessible from the Internet detected. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: LOW + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#publicly_accessible + - https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html#USER_VPC.Hiding + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern: publicly_accessible = true + - pattern-inside: | + resource "aws_db_instance" "..." { + ... + } + severity: WARNING + - id: terraform.lang.security.s3-cors-all-origins.all-origins-allowed + languages: + - hcl + message: CORS rule on bucket permits any origin + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-942: Permissive Cross-domain Policy with Untrusted Domains' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#using-cors + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-inside: cors_rule { ... } + - pattern: allowed_origins = ["*"] + severity: WARNING + - id: terraform.lang.security.s3-public-read-bucket.s3-public-read-bucket + languages: + - hcl + message: S3 bucket with public read access detected. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#acl + - https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: + - pattern: acl = "public-read" + - pattern: acl = "authenticated-read" + - pattern-not-inside: | + resource "aws_s3_bucket" "..." { + ... + website { ... } + ... + } + severity: WARNING + - id: terraform.lang.security.s3-public-rw-bucket.s3-public-rw-bucket + languages: + - hcl + message: S3 bucket with public read-write access detected. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#acl + - https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl + subcategory: + - vuln + technology: + - terraform + - aws + pattern: acl = "public-read-write" + severity: ERROR + - id: terraform.lang.security.s3-unencrypted-bucket.s3-unencrypted-bucket + languages: + - hcl + message: This rule has been deprecated, as all s3 buckets are encrypted by default with no way to disable it. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration for more info. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + deprecated: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#server_side_encryption_configuration + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html + subcategory: + - vuln + technology: + - terraform + - aws + patterns: + - pattern: a + - pattern: b + severity: INFO + - id: typescript.angular.security.audit.angular-domsanitizer.angular-bypasssecuritytrust + languages: + - typescript + message: Detected the use of `$TRUST`. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. If you have to use `$TRUST`, ensure it does not come from user-input or use the appropriate prevention mechanism e.g. input validation or sanitization depending on the context. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://angular.io/api/platform-browser/DomSanitizer + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - angular + - browser + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) + - patterns: + - pattern: sanitizer.sanitize(...) + - pattern-not: sanitizer.sanitize(SecurityContext.NONE, ...); + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $X.$TRUST($Y) + - focus-metavariable: $Y + - pattern-not: | + $X.$TRUST(`...`) + - pattern-not: | + $X.$TRUST("...") + - metavariable-regex: + metavariable: $TRUST + regex: (bypassSecurityTrustHtml|bypassSecurityTrustStyle|bypassSecurityTrustScript|bypassSecurityTrustUrl|bypassSecurityTrustResourceUrl) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + function ...({..., $X: string, ...}) { ... } + - pattern-inside: | + function ...(..., $X: string, ...) { ... } + - focus-metavariable: $X + severity: WARNING + - id: typescript.aws-cdk.security.audit.awscdk-bucket-encryption.awscdk-bucket-encryption + languages: + - typescript + message: 'Add "encryption: $Y.BucketEncryption.KMS_MANAGED" or "encryption: $Y.BucketEncryption.S3_MANAGED" to the bucket props for Bucket construct $X' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html + subcategory: + - vuln + technology: + - AWS-CDK + pattern-either: + - patterns: + - pattern-inside: | + import {Bucket} from '@aws-cdk/aws-s3' + ... + - pattern: const $X = new Bucket(...) + - pattern-not: | + const $X = new Bucket(..., {..., encryption: BucketEncryption.KMS_MANAGED, ...}) + - pattern-not: | + const $X = new Bucket(..., {..., encryption: BucketEncryption.KMS, ...}) + - pattern-not: | + const $X = new Bucket(..., {..., encryption: BucketEncryption.S3_MANAGED, ...}) + - patterns: + - pattern-inside: | + import * as $Y from '@aws-cdk/aws-s3' + ... + - pattern: const $X = new $Y.Bucket(...) + - pattern-not: | + const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.KMS_MANAGED, ...}) + - pattern-not: | + const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.KMS, ...}) + - pattern-not: | + const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.S3_MANAGED, ...}) + severity: ERROR + - id: typescript.aws-cdk.security.audit.awscdk-bucket-enforcessl.aws-cdk-bucket-enforcessl + languages: + - ts + message: Bucket $X is not set to enforce encryption-in-transit, if not explictly setting this on the bucket policy - the property "enforceSSL" should be set to true + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html + subcategory: + - vuln + technology: + - AWS-CDK + pattern-either: + - patterns: + - pattern-inside: | + import {Bucket} from '@aws-cdk/aws-s3'; + ... + - pattern: const $X = new Bucket(...) + - pattern-not: | + const $X = new Bucket(..., {enforceSSL: true}, ...) + - patterns: + - pattern-inside: | + import * as $Y from '@aws-cdk/aws-s3'; + ... + - pattern: const $X = new $Y.Bucket(...) + - pattern-not: | + const $X = new $Y.Bucket(..., {..., enforceSSL: true, ...}) + severity: ERROR + - id: typescript.aws-cdk.security.audit.awscdk-sqs-unencryptedqueue.awscdk-sqs-unencryptedqueue + languages: + - ts + message: 'Queue $X is missing encryption at rest. Add "encryption: $Y.QueueEncryption.KMS" or "encryption: $Y.QueueEncryption.KMS_MANAGED" to the queue props to enable encryption at rest for the queue.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-data-protection.html + subcategory: + - vuln + technology: + - AWS-CDK + pattern-either: + - patterns: + - pattern-inside: | + import {Queue} from '@aws-cdk/aws-sqs' + ... + - pattern: const $X = new Queue(...) + - pattern-not: | + const $X = new Queue(..., {..., encryption: QueueEncryption.KMS_MANAGED, ...}) + - pattern-not: | + const $X = new Queue(..., {..., encryption: QueueEncryption.KMS, ...}) + - patterns: + - pattern-inside: | + import * as $Y from '@aws-cdk/aws-sqs' + ... + - pattern: const $X = new $Y.Queue(...) + - pattern-not: | + const $X = new $Y.Queue(..., {..., encryption: $Y.QueueEncryption.KMS_MANAGED, ...}) + - pattern-not: | + const $X = new $Y.Queue(..., {..., encryption: $Y.QueueEncryption.KMS, ...}) + severity: WARNING + - id: typescript.aws-cdk.security.awscdk-bucket-grantpublicaccessmethod.awscdk-bucket-grantpublicaccessmethod + languages: + - ts + message: Using the GrantPublicAccess method on bucket contruct $X will make the objects in the bucket world accessible. Verify if this is intentional. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-306: Missing Authentication for Critical Function' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: HIGH + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-overview.html + subcategory: + - vuln + technology: + - AWS-CDK + pattern-either: + - patterns: + - pattern-inside: | + import {Bucket} from '@aws-cdk/aws-s3' + ... + - pattern: | + const $X = new Bucket(...) + ... + $X.grantPublicAccess(...) + - patterns: + - pattern-inside: | + import * as $Y from '@aws-cdk/aws-s3' + ... + - pattern: | + const $X = new $Y.Bucket(...) + ... + $X.grantPublicAccess(...) + severity: WARNING + - id: typescript.aws-cdk.security.awscdk-codebuild-project-public.awscdk-codebuild-project-public + languages: + - ts + message: CodeBuild Project $X is set to have a public URL. This will make the build results, logs, artifacts publically accessible, including builds prior to the project being public. Ensure this is acceptable for the project. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-306: Missing Authentication for Critical Function' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://docs.aws.amazon.com/codebuild/latest/userguide/public-builds.html + subcategory: + - vuln + technology: + - AWS-CDK + pattern-either: + - patterns: + - pattern-inside: | + import {Project} from '@aws-cdk/aws-codebuild' + ... + - pattern: | + const $X = new Project(..., {..., badge: true, ...}) + - patterns: + - pattern-inside: | + import * as $Y from '@aws-cdk/aws-codebuild' + ... + - pattern: | + const $X = new $Y.Project(..., {..., badge: true, ...}) + severity: WARNING + - id: typescript.lang.best-practice.moment-deprecated.moment-deprecated + languages: + - typescript + - javascript + message: Moment is a legacy project in maintenance mode. Consider using libraries that are actively supported, e.g. `dayjs`. + metadata: + category: best-practice + references: + - https://momentjs.com/docs/#/-project-status/ + - https://day.js.org/ + technology: + - moment + - dayjs + pattern: | + import 'moment' + severity: INFO + - id: typescript.lang.correctness.useless-ternary.useless-ternary + languages: + - typescript + - javascript + message: It looks like no matter how $CONDITION is evaluated, this expression returns $ANS. This is probably a copy-paste error. + metadata: + category: correctness + technology: + - react + pattern: | + $CONDITION ? $ANS : $ANS + severity: ERROR + - id: typescript.lang.security.audit.cors-regex-wildcard.cors-regex-wildcard + languages: + - ts + message: 'Unescaped ''.'' character in CORS domain regex $CORS: $PATTERN' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-183: Permissive List of Allowed Inputs' + impact: LOW + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit + technology: + - cors + patterns: + - pattern-either: + - pattern: $CORS = [...,/$PATTERN/,...] + - pattern: $CORS = /$PATTERN/ + - focus-metavariable: $PATTERN + - metavariable-regex: + metavariable: $PATTERN + regex: .+?(?} + - pattern: | + this.state = {$NAME: <... this.props.$PROP ...>} + - metavariable-regex: + metavariable: $NAME + regex: ^(?!default|initial).*$ + - patterns: + - pattern-either: + - pattern-inside: | + function $FN({$PROP},...) { + ... + } + - pattern-inside: | + function $FN($PROP,...) { + ... + } + - pattern-either: + - pattern: useState(<... $PROP ...>) + - pattern: useState(<... $PROP.$KEY ...>) + - pattern: | + useState(function $X(...) { + ... + <... $PROP ...> + ... + }) + - pattern: | + useState(function $X(...) { + ... + <... $PROP.$KEY ...> + ... + }) + - metavariable-regex: + metavariable: $PROP + regex: ^(?!default|initial).*$ + severity: WARNING + - id: typescript.react.best-practice.react-props-spreading.react-props-spreading + languages: + - typescript + - javascript + message: It's best practice to explicitly pass props to an HTML component rather than use the spread operator. The spread operator risks passing invalid HTML props to an HTML element, which can cause console warnings or worse, give malicious actors a way to inject unexpected attributes. + metadata: + category: best-practice + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + references: + - https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md + source-rule-url: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md + technology: + - react + patterns: + - pattern: <$X {...$PROPS} /> + - focus-metavariable: $PROPS + severity: WARNING + - id: typescript.react.portability.i18next.i18next-key-format.i18next-key-format + languages: + - typescript + - javascript + message: Translation key '$KEY' should match format 'MODULE.FEATURE.*' + metadata: + category: portability + references: + - https://www.notion.so/hendyirawan/Internationalization-Localization-Policy-318c21674e5f44c48d6f136a6eb2e024 + - https://mui.com/ + - https://react.i18next.com/ + technology: + - react + - mui + - i18next + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: t('$KEY') + - pattern: t('$KEY', $OPTIONS) + - pattern: t([$DYNAMIC_KEY, '$KEY']) + - pattern: t([$DYNAMIC_KEY, '$KEY'], $OPTIONS) + - metavariable-regex: + metavariable: $KEY + regex: (?!^[a-z0-9-]+\.[a-z0-9-]+\.[a-zA-Z0-9_.-]+$) + - patterns: + - pattern-either: + - pattern: t([$DYNAMIC_KEY, '$KEY']) + - pattern: t([$DYNAMIC_KEY, '$KEY'], $OPTIONS) + - metavariable-regex: + metavariable: $DYNAMIC_KEY + regex: (?!^[`][a-z0-9-]+[.][a-z0-9-]+[.]\S+$) + - patterns: + - pattern-either: + - pattern: $I18NEXT.t('$KEY') + - pattern: $I18NEXT.t('$KEY', $OPTIONS) + - pattern: $I18NEXT.t([$DYNAMIC_KEY, '$KEY']) + - pattern: $I18NEXT.t([$DYNAMIC_KEY, '$KEY'], $OPTIONS) + - metavariable-regex: + metavariable: $I18NEXT + regex: (^i18n|i18next$) + - metavariable-regex: + metavariable: $KEY + regex: (?!^[a-z0-9-]+\.[a-z0-9-]+\.[a-zA-Z0-9_.-]+$) + - patterns: + - pattern-either: + - pattern: $I18NEXT.t([$DYNAMIC_KEY, '$KEY']) + - pattern: $I18NEXT.t([$DYNAMIC_KEY, '$KEY'], $OPTIONS) + - metavariable-regex: + metavariable: $I18NEXT + regex: (^(i18n|i18next)$) + - metavariable-regex: + metavariable: $DYNAMIC_KEY + regex: (?!^[`][a-z0-9-]+[.][a-z0-9-]+[.]\S+$) + severity: WARNING + - id: typescript.react.portability.i18next.jsx-label-not-i18n.jsx-label-not-i18n + languages: + - typescript + - javascript + message: 'JSX Component label not internationalized: ''$MESSAGE''' + metadata: + category: portability + references: + - https://www.notion.so/hendyirawan/Internationalization-Localization-Policy-318c21674e5f44c48d6f136a6eb2e024 + - https://mui.com/ + - https://react.i18next.com/ + technology: + - react + - mui + - i18next + patterns: + - pattern-either: + - pattern: + - pattern: + - metavariable-regex: + metavariable: $MESSAGE + regex: (.*[a-zA-Z]+.*) + - pattern-not: <$ELEMENT ... label="" ... /> + - pattern-not: <$ELEMENT ... label={t($KEY, ...)} ... /> + severity: WARNING + - id: typescript.react.portability.i18next.jsx-not-internationalized.jsx-not-internationalized + languages: + - typescript + - javascript + message: 'JSX element not internationalized: ''$MESSAGE''. You should support different languages in your website or app with internationalization. Instead, use packages such as `i18next` in order to internationalize your elements.' + metadata: + category: portability + references: + - https://www.notion.so/hendyirawan/Internationalization-Localization-Policy-318c21674e5f44c48d6f136a6eb2e024 + - https://mui.com/ + - https://react.i18next.com/ + technology: + - react + - mui + - i18next + patterns: + - pattern: <$ELEMENT>$MESSAGE + - metavariable-regex: + metavariable: $MESSAGE + regex: ([A-Za-z\n ]+[A-Za-z]+[A-Za-z\n ]+) + - pattern-not: <$ELEMENT>t('$KEY', ...) + severity: WARNING + - id: typescript.react.portability.i18next.mui-snackbar-message.mui-snackbar-message + languages: + - typescript + - javascript + message: 'React MUI enqueueSnackbar() title is not internationalized: ''$MESSAGE''' + metadata: + category: portability + references: + - https://hendyirawan.notion.site/Internationalization-Localization-Policy-318c21674e5f44c48d6f136a6eb2e024 + - https://mui.com/ + - https://react.i18next.com/ + technology: + - react + - mui + - i18next + patterns: + - pattern: enqueueSnackbar('$MESSAGE', $X2) + - pattern-not: enqueueSnackbar(t($KEY), $X2) + severity: WARNING + - id: typescript.react.portability.i18next.useselect-label-not-i18n.useselect-label-not-i18n + languages: + - typescript + - javascript + message: React useSelect() label is not internationalized - '$LABEL'. You should support different langauges in your website or app with internationalization. Instead, use packages such as `i18next` to internationalize your elements. + metadata: + category: portability + references: + - https://www.notion.so/hendyirawan/Internationalization-Localization-Policy-318c21674e5f44c48d6f136a6eb2e024 + - https://react.i18next.com/ + technology: + - react + - mui + - i18next + patterns: + - pattern: useSelect($X1, $X2, '$LABEL', $X4) + - metavariable-regex: + metavariable: $LABEL + regex: (.*[A-Za-z].*) + - pattern-not: useSelect($X1, $X2, t('...'), $X4) + severity: WARNING + - id: typescript.react.security.audit.react-dangerouslysetinnerhtml.react-dangerouslysetinnerhtml + languages: + - typescript + - javascript + message: Detection of dangerouslySetInnerHTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use dangerouslySetInnerHTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html + subcategory: + - vuln + technology: + - react + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + $S = new Remarkable() + ... + - pattern: $S.render(...) + pattern-sinks: + - patterns: + - focus-metavariable: $X + - pattern-either: + - pattern: | + {...,dangerouslySetInnerHTML: {__html: $X},...} + - pattern: | + <$Y ... dangerouslySetInnerHTML={{__html: $X}} /> + - pattern-not: | + <$Y ... dangerouslySetInnerHTML={{__html: "..."}} /> + - pattern-not: | + {...,dangerouslySetInnerHTML:{__html: "..."},...} + - metavariable-pattern: + metavariable: $X + patterns: + - pattern-not: | + {...} + - pattern-not: | + <... {__html: "..."} ...> + - pattern-not: | + <... {__html: `...`} ...> + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + function ...({..., $X, ...}) { ... } + - pattern-inside: | + function ...(..., $X, ...) { ... } + - focus-metavariable: $X + - pattern-not-inside: | + $F. ... .$SANITIZEUNC(...) + severity: WARNING + - id: typescript.react.security.audit.react-href-var.react-href-var + languages: + - typescript + - javascript + message: Detected a variable used in an anchor tag with the 'href' attribute. A malicious actor may be able to input the 'javascript:' URI, which could cause cross-site scripting (XSS). It is recommended to disallow 'javascript:' URIs within your application. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://reactjs.org/blog/2019/08/08/react-v16.9.0.html#deprecating-javascript-urls + - https://pragmaticwebsecurity.com/articles/spasecurity/react-xss-part1.html + subcategory: + - audit + technology: + - react + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $X + - pattern-either: + - pattern: | + <$EL href={$X} /> + - pattern: | + React.createElement($EL, {href: $X}) + - pattern-inside: | + $PARAMS = {href: $X}; + ... + React.createElement($EL, $PARAMS); + - metavariable-pattern: + metavariable: $EL + patterns: + - pattern-not-regex: (?i)(button) + requires: TAINTED and not CONCAT and not CLEAN + pattern-sources: + - label: TAINTED + patterns: + - pattern-either: + - pattern-inside: | + function ...({..., $X, ...}) { ... } + - pattern-inside: | + function ...(..., $X, ...) { ... } + - focus-metavariable: $X + - pattern-either: + - pattern: $X.$Y + - pattern: $X[...] + - pattern-not-inside: | + $F. ... .$SANITIZEUNC(...) + - label: CONCAT + patterns: + - pattern-either: + - pattern: | + `...${$X}...` + - pattern: | + $SANITIZE + <... $X ...> + - pattern-not: | + `${$X}...` + - pattern-not: | + $X + ... + - focus-metavariable: $X + requires: TAINTED + - by-side-effect: true + label: CLEAN + patterns: + - pattern-either: + - pattern: $A($SOURCE) + - pattern: $SANITIZE. ... .$A($SOURCE) + - pattern: $A. ... .$SANITIZE($SOURCE) + - focus-metavariable: $SOURCE + - metavariable-regex: + metavariable: $A + regex: (?i)(.*valid|.*sanitiz) + severity: WARNING + - id: typescript.react.security.audit.react-jwt-decoded-property.react-jwt-decoded-property + languages: + - typescript + - javascript + message: Property decoded from JWT token without verifying and cannot be trustworthy. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-922: Insecure Storage of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://pragmaticwebsecurity.com/articles/oauthoidc/localstorage-xss.html + subcategory: + - audit + technology: + - react + patterns: + - pattern-inside: | + import jwt_decode from "jwt-decode"; + ... + - pattern-inside: | + $DECODED = jwt_decode($TOKEN,...); + ... + - pattern: $DECODED.$PROPERTY + severity: INFO + - id: typescript.react.security.audit.react-jwt-in-localstorage.react-jwt-in-localstorage + languages: + - typescript + - javascript + message: Storing JWT tokens in localStorage known to be a bad practice, consider moving your tokens from localStorage to a HTTP cookie. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-922: Insecure Storage of Sensitive Information' + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies + subcategory: + - audit + technology: + - react + patterns: + - pattern-inside: | + import jwt_decode from "jwt-decode"; + ... + - pattern-either: + - pattern: | + $DECODED = jwt_decode($TOKEN,...); + ... + localStorage.setItem($NAME, <... $TOKEN ...>); + - pattern: | + $DECODED = jwt_decode(...); + ... + localStorage.setItem($NAME, <... $DECODED ...>); + severity: INFO + - id: typescript.react.security.audit.react-unsanitized-method.react-unsanitized-method + languages: + - typescript + - javascript + message: Detection of $HTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use $HTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://developer.mozilla.org/en-US/docs/Web/API/Document/writeln + - https://developer.mozilla.org/en-US/docs/Web/API/Document/write + - https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML + subcategory: + - vuln + technology: + - react + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + $S = new Remarkable() + ... + - pattern: $S.render(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: "this.window.document. ... .$HTML('...',$SINK) \n" + - pattern: "window.document. ... .$HTML('...',$SINK) \n" + - pattern: "document.$HTML($SINK) \n" + - metavariable-regex: + metavariable: $HTML + regex: (writeln|write) + - focus-metavariable: $SINK + - patterns: + - pattern-either: + - pattern: "$PROP. ... .$HTML('...',$SINK) \n" + - metavariable-regex: + metavariable: $HTML + regex: (insertAdjacentHTML) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + function ...({..., $X, ...}) { ... } + - pattern-inside: | + function ...(..., $X, ...) { ... } + - focus-metavariable: $X + - pattern-either: + - pattern: $X.$Y + - pattern: $X[...] + severity: WARNING + - id: typescript.react.security.audit.react-unsanitized-property.react-unsanitized-property + languages: + - typescript + - javascript + message: Detection of $HTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use $HTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html + subcategory: + - vuln + technology: + - react + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + $S = new Remarkable() + ... + - pattern: $S.render(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $BODY = $REACT.useRef(...) + ... + - pattern-inside: | + $BODY = useRef(...) + ... + - pattern-inside: | + $BODY = findDOMNode(...) + ... + - pattern-inside: | + $BODY = createRef(...) + ... + - pattern-inside: | + $BODY = $REACT.findDOMNode(...) + ... + - pattern-inside: | + $BODY = $REACT.createRef(...) + ... + - pattern-either: + - pattern: "$BODY. ... .$HTML = $SINK \n" + - pattern: "$BODY.$HTML = $SINK \n" + - metavariable-regex: + metavariable: $HTML + regex: (innerHTML|outerHTML) + - focus-metavariable: $SINK + - patterns: + - pattern-either: + - pattern: ReactDOM.findDOMNode(...).$HTML = $SINK + - metavariable-regex: + metavariable: $HTML + regex: (innerHTML|outerHTML) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + function ...({..., $X, ...}) { ... } + - pattern-inside: | + function ...(..., $X, ...) { ... } + - focus-metavariable: $X + - pattern-either: + - pattern: $X.$Y + - pattern: $X[...] + severity: WARNING + - id: typescript.react.security.react-insecure-request.react-insecure-request + languages: + - typescript + - javascript + message: Unencrypted request over HTTP detected. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.npmjs.com/package/axios + subcategory: + - vuln + technology: + - react + vulnerability: Insecure Transport + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + import $AXIOS from 'axios'; + ... + $AXIOS.$METHOD(...) + - pattern-inside: | + $AXIOS = require('axios'); + ... + $AXIOS.$METHOD(...) + - pattern-either: + - pattern: $AXIOS.get("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.post("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.delete("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.head("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.patch("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.put("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.options("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - patterns: + - pattern-either: + - pattern-inside: | + import $AXIOS from 'axios'; + ... + $AXIOS(...) + - pattern-inside: | + $AXIOS = require('axios'); + ... + $AXIOS(...) + - pattern-either: + - pattern: '$AXIOS({url: "=~/[Hh][Tt][Tt][Pp]:\/\/.*/"}, ...)' + - pattern: | + $OPTS = {url: "=~/[Hh][Tt][Tt][Pp]:\/\/.*/"} + ... + $AXIOS($OPTS, ...) + - pattern: fetch("=~/[Hh][Tt][Tt][Pp]:\/\/.*/", ...) + severity: ERROR + - id: typescript.react.security.react-markdown-insecure-html.react-markdown-insecure-html + languages: + - typescript + - javascript + message: Overwriting `transformLinkUri` or `transformImageUri` to something insecure, or turning `allowDangerousHtml` on, or turning `escapeHtml` off, will open the code up to XSS vectors. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://www.npmjs.com/package/react-markdown#security + subcategory: + - audit + technology: + - react + patterns: + - pattern-either: + - pattern-inside: | + $X = require('react-markdown/with-html'); + ... + - pattern-inside: | + $X = require('react-markdown'); + ... + - pattern-inside: | + import 'react-markdown/with-html'; + ... + - pattern-inside: | + import 'react-markdown'; + ... + - pattern-either: + - pattern: | + <$EL allowDangerousHtml /> + - pattern: | + <$EL escapeHtml={false} /> + - pattern: | + <$EL transformLinkUri=... /> + - pattern: | + <$EL transformImageUri=... /> + severity: WARNING + - id: yaml.argo.correctness.event-binding-payload-with-hyphen.event-binding-payload-with-hyphen + languages: + - yaml + match: + all: + - inside: | + apiVersion: argoproj.io/v1alpha1 + kind: WorkflowEventBinding + ... + - inside: | + spec: + ... + submit: + ... + arguments: + ... + parameters: + ... + - | + event: $VALUE + where: + - metavariable: $VALUE + regex: payload\..*-.* + message: The parameter `$VALUE` to this WorkflowEventBinding includes hyphens, which will, very confusingly, throw an error when Argo Workflows tries to invoke the workflow. Set the payload value to use underscores instead. + metadata: + category: correctness + references: + - https://argoproj.github.io/argo-workflows/variables/#expression + technology: + - argo + - argo-workflows + severity: WARNING + - id: yaml.argo.security.argo-workflow-parameter-command-injection.argo-workflow-parameter-command-injection + languages: + - yaml + message: Using input or workflow parameters in here-scripts can lead to command injection or code injection. Convert the parameters to env variables instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + impact: HIGH + likelihood: MEDIUM + owasp: + - A03:2021 – Injection + references: + - https://github.com/argoproj/argo-workflows/issues/5061 + - https://github.com/argoproj/argo-workflows/issues/5114#issue-808865370 + subcategory: + - vuln + technology: + - ci + - argo + patterns: + - pattern-inside: | + apiVersion: $VERSION + ... + - metavariable-regex: + metavariable: $VERSION + regex: (argoproj.io.*) + - pattern-either: + - patterns: + - pattern-inside: "command:\n ...\n - python\n ...\n...\nsource: \n $SCRIPT\n" + - focus-metavariable: $SCRIPT + - metavariable-pattern: + language: python + metavariable: $SCRIPT + patterns: + - pattern: | + $FUNC(..., $PARAM, ...) + - metavariable-pattern: + metavariable: $PARAM + pattern-either: + - pattern-regex: (.*{{.*inputs.parameters.*}}.*) + - pattern-regex: (.*{{.*workflow.parameters.*}}.*) + - patterns: + - pattern-inside: "command:\n ...\n - $LANG\n ...\n...\nsource: \n $SCRIPT\n" + - metavariable-regex: + metavariable: $LANG + regex: (bash|sh) + - focus-metavariable: $SCRIPT + - metavariable-pattern: + language: bash + metavariable: $SCRIPT + patterns: + - pattern: | + $CMD ... $PARAM ... + - metavariable-pattern: + metavariable: $PARAM + pattern-either: + - pattern-regex: (.*{{.*inputs.parameters.*}}.*) + - pattern-regex: (.*{{.*workflow.parameters.*}}.*) + - patterns: + - pattern-inside: | + container: + ... + command: $LANG + ... + args: $PARAM + - metavariable-regex: + metavariable: $LANG + regex: .*(sh|bash|ksh|csh|tcsh|zsh).* + - metavariable-pattern: + metavariable: $PARAM + pattern-either: + - pattern-regex: (.*{{.*inputs.parameters.*}}.*) + - pattern-regex: (.*{{.*workflow.parameters.*}}.*) + - focus-metavariable: $PARAM + severity: ERROR + - id: yaml.docker-compose.security.exposing-docker-socket-volume.exposing-docker-socket-volume + languages: + - yaml + message: Exposing host's Docker socket to containers via a volume. The owner of this socket is root. Giving someone access to it is equivalent to giving unrestricted root access to your host. Remove 'docker.sock' from volumes to prevent this. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: HIGH + likelihood: LOW + owasp: + - A06:2017 - Security Misconfiguration + - A05:2021 - Security Misconfiguration + references: + - https://docs.docker.com/compose/compose-file/compose-file-v3/#volume-configuration-reference + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-1-do-not-expose-the-docker-daemon-socket-even-to-the-containers + subcategory: + - audit + technology: + - docker-compose + patterns: + - pattern-inside: | + version: ... + ... + - pattern-either: + - pattern: | + volumes: + - ... + - /var/run/docker.sock:/var/run/docker.sock + - ... + - pattern: | + volumes: + - ... + - /run/docker.sock:/run/docker.sock + - ... + - pattern: | + volumes: + - ... + - /var/run/docker.sock:/run/docker.sock + - ... + - pattern: | + volumes: + - ... + - /run/docker.sock:/var/run/docker.sock + - ... + - pattern: | + volumes: + - ... + - /var/run/docker.sock + - ... + - pattern: | + volumes: + - ... + - /run/docker.sock + - ... + - pattern: | + volumes: + - ... + - ... + source: /var/run/docker.sock + ... + - ... + - pattern: | + volumes: + - ... + - ... + source: /run/docker.sock + ... + - ... + severity: WARNING + - id: yaml.docker-compose.security.no-new-privileges.no-new-privileges + languages: + - yaml + message: Service '$SERVICE' allows for privilege escalation via setuid or setgid binaries. Add 'no-new-privileges:true' in 'security_opt' to prevent this. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs/ + - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag + subcategory: + - audit + technology: + - docker-compose + patterns: + - pattern-inside: | + version: ... + ... + services: + ... + - pattern: | + $SERVICE: + ... + image: ... + - pattern-not: | + $SERVICE: + ... + image: ... + ... + security_opt: + - ... + - no-new-privileges:true + - ... + - focus-metavariable: $SERVICE + severity: WARNING + - fix: | + false + id: yaml.docker-compose.security.privileged-service.privileged-service + languages: + - yaml + message: Service '$SERVICE' is running in privileged mode. This grants the container the equivalent of root capabilities on the host machine. This can lead to container escapes, privilege escalation, and other security concerns. Remove the 'privileged' key to disable this capability. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH + owasp: + - A06:2017 - Security Misconfiguration + - A05:2021 - Security Misconfiguration + references: + - https://www.trendmicro.com/en_us/research/19/l/why-running-a-privileged-container-in-docker-is-a-bad-idea.html + - https://containerjournal.com/topics/container-security/why-running-a-privileged-container-is-not-a-good-idea/ + subcategory: + - vuln + technology: + - docker-compose + patterns: + - pattern-inside: | + version: ... + ... + services: + ... + $SERVICE: + ... + privileged: $TRUE + - focus-metavariable: $TRUE + - metavariable-regex: + metavariable: $TRUE + regex: (true) + severity: WARNING + - id: yaml.docker-compose.security.seccomp-confinement-disabled.seccomp-confinement-disabled + languages: + - yaml + message: Service '$SERVICE' is explicitly disabling seccomp confinement. This runs the service in an unrestricted state. Remove 'seccomp:unconfined' to prevent this. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: HIGH + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://docs.docker.com/engine/security/seccomp/ + subcategory: + - audit + technology: + - docker-compose + patterns: + - pattern-inside: | + version: ... + ... + services: + ... + - pattern: | + $SERVICE: + ... + image: ... + ... + security_opt: + - ... + - seccomp:unconfined + severity: WARNING + - id: yaml.docker-compose.security.selinux-separation-disabled.selinux-separation-disabled + languages: + - yaml + message: Service '$SERVICE' is explicitly disabling SELinux separation. This runs the service as an unconfined type. Remove 'label:disable' to prevent this. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-284: Improper Access Control' + impact: HIGH + likelihood: LOW + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://www.projectatomic.io/blog/2016/03/dwalsh_selinux_containers/ + - https://docs.docker.com/engine/reference/run/#security-configuration + subcategory: + - audit + technology: + - docker-compose + patterns: + - pattern-inside: | + version: ... + ... + services: + ... + - pattern: | + $SERVICE: + ... + image: ... + ... + security_opt: + - ... + - label:disable + severity: WARNING + - id: yaml.docker-compose.security.writable-filesystem-service.writable-filesystem-service + languages: + - yaml + message: 'Service ''$SERVICE'' is running with a writable root filesystem. This may allow malicious applications to download and run additional payloads, or modify container files. If an application inside a container has to save something temporarily consider using a tmpfs. Add ''read_only: true'' to this service to prevent this.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://docs.docker.com/compose/compose-file/compose-file-v3/#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir + - https://blog.atomist.com/security-of-docker-kubernetes/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-8-set-filesystem-and-volumes-to-read-only + subcategory: + - audit + technology: + - docker-compose + patterns: + - pattern-inside: | + version: ... + ... + services: + ... + - pattern: | + $SERVICE: + ... + image: ... + ... + - pattern-not: | + $SERVICE: + ... + image: ... + ... + read_only: true + - focus-metavariable: $SERVICE + severity: WARNING + - id: yaml.github-actions.security.allowed-unsecure-commands.allowed-unsecure-commands + languages: + - yaml + message: The environment variable `ACTIONS_ALLOW_UNSECURE_COMMANDS` grants this workflow permissions to use the `set-env` and `add-path` commands. There is a vulnerability in these commands that could result in environment variables being modified by an attacker. Depending on the use of the environment variable, this could enable an attacker to, at worst, modify the system path to run a different command than intended, resulting in arbitrary code execution. This could result in stolen code or secrets. Don't use `ACTIONS_ALLOW_UNSECURE_COMMANDS`. Instead, use Environment Files. See https://github.com/actions/toolkit/blob/main/docs/commands.md#environment-files for more information. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-749: Exposed Dangerous Method or Function' + impact: MEDIUM + likelihood: LOW + owasp: A06:2017 - Security Misconfiguration + references: + - https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/ + - https://github.com/actions/toolkit/security/advisories/GHSA-mfwh-5m23-j46w + - https://github.com/actions/toolkit/blob/main/docs/commands.md#environment-files + subcategory: + - vuln + technology: + - github-actions + patterns: + - pattern-either: + - patterns: + - pattern-inside: '{env: ...}' + - pattern: 'ACTIONS_ALLOW_UNSECURE_COMMANDS: true' + severity: WARNING + - id: yaml.github-actions.security.curl-eval.curl-eval + languages: + - yaml + message: Data is being eval'd from a `curl` command. An attacker with control of the server in the `curl` command could inject malicious code into the `eval`, resulting in a system comrpomise. Avoid eval'ing untrusted data if you can. If you must do this, consider checking the SHA sum of the content returned by the server to verify its integrity. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections + subcategory: + - audit + technology: + - github-actions + - bash + - curl + patterns: + - pattern-inside: 'steps: [...]' + - pattern-inside: | + - run: ... + ... + - pattern: 'run: $SHELL' + - metavariable-pattern: + language: bash + metavariable: $SHELL + patterns: + - pattern: | + $DATA=<... curl ...> + ... + eval <... $DATA ...> + severity: ERROR + - id: yaml.github-actions.security.github-script-injection.github-script-injection + languages: + - yaml + message: 'Using variable interpolation `${{...}}` with `github` context data in a `actions/github-script`''s `script:` step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. `github` context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with `env:` to store the data and use the environment variable in the `run:` script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: HIGH + owasp: + - A03:2021 - Injection + references: + - https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections + - https://securitylab.github.com/research/github-actions-untrusted-input/ + - https://github.com/actions/github-script + subcategory: + - vuln + technology: + - github-actions + patterns: + - pattern-inside: 'steps: [...]' + - pattern-inside: | + uses: $ACTION + ... + - pattern-inside: | + with: + ... + script: ... + ... + - pattern: 'script: $SHELL' + - metavariable-regex: + metavariable: $ACTION + regex: actions/github-script@.* + - metavariable-pattern: + language: generic + metavariable: $SHELL + patterns: + - pattern-either: + - pattern: ${{ github.event.issue.title }} + - pattern: ${{ github.event.issue.body }} + - pattern: ${{ github.event.pull_request.title }} + - pattern: ${{ github.event.pull_request.body }} + - pattern: ${{ github.event.comment.body }} + - pattern: ${{ github.event.review.body }} + - pattern: ${{ github.event.review_comment.body }} + - pattern: ${{ github.event.pages. ... .page_name}} + - pattern: ${{ github.event.head_commit.message }} + - pattern: ${{ github.event.head_commit.author.email }} + - pattern: ${{ github.event.head_commit.author.name }} + - pattern: ${{ github.event.commits ... .author.email }} + - pattern: ${{ github.event.commits ... .author.name }} + - pattern: ${{ github.event.pull_request.head.ref }} + - pattern: ${{ github.event.pull_request.head.label }} + - pattern: ${{ github.event.pull_request.head.repo.default_branch }} + - pattern: ${{ github.head_ref }} + - pattern: ${{ github.event.inputs ... }} + severity: ERROR + - id: yaml.github-actions.security.pull-request-target-code-checkout.pull-request-target-code-checkout + languages: + - yaml + message: This GitHub Actions workflow file uses `pull_request_target` and checks out code from the incoming pull request. When using `pull_request_target`, the Action runs in the context of the target repository, which includes access to all repository secrets. Normally, this is safe because the Action only runs code from the target repository, not the incoming PR. However, by checking out the incoming PR code, you're now using the incoming code for the rest of the action. You may be inadvertently executing arbitrary code from the incoming PR with access to repository secrets, which would let an attacker steal repository secrets. This normally happens by running build scripts (e.g., `npm build` and `make`) or dependency installation scripts (e.g., `python setup.py install`). Audit your workflow file to make sure no code from the incoming PR is executed. Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-913: Improper Control of Dynamically-Managed Code Resources' + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ + - https://github.com/justinsteven/advisories/blob/master/2021_github_actions_checkspelling_token_leak_via_advice_symlink.md + subcategory: + - audit + technology: + - github-actions + patterns: + - pattern-either: + - pattern-inside: | + on: + ... + pull_request_target: ... + ... + ... + - pattern-inside: | + on: [..., pull_request_target, ...] + ... + - pattern-inside: | + on: pull_request_target + ... + - pattern-inside: | + jobs: + ... + $JOBNAME: + ... + steps: + ... + - pattern: | + ... + uses: "$ACTION" + with: + ... + ref: $EXPR + - metavariable-regex: + metavariable: $ACTION + regex: actions/checkout@.* + - metavariable-pattern: + language: generic + metavariable: $EXPR + patterns: + - pattern: ${{ github.event.pull_request ... }} + severity: WARNING + - id: yaml.github-actions.security.run-shell-injection.run-shell-injection + languages: + - yaml + message: 'Using variable interpolation `${{...}}` with `github` context data in a `run:` step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. `github` context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with `env:` to store the data and use the environment variable in the `run:` script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections + - https://securitylab.github.com/research/github-actions-untrusted-input/ + subcategory: + - vuln + technology: + - github-actions + patterns: + - pattern-inside: 'steps: [...]' + - pattern-inside: | + - run: ... + ... + - pattern: 'run: $SHELL' + - metavariable-pattern: + language: generic + metavariable: $SHELL + patterns: + - pattern-either: + - pattern: ${{ github.event.issue.title }} + - pattern: ${{ github.event.issue.body }} + - pattern: ${{ github.event.pull_request.title }} + - pattern: ${{ github.event.pull_request.body }} + - pattern: ${{ github.event.comment.body }} + - pattern: ${{ github.event.review.body }} + - pattern: ${{ github.event.review_comment.body }} + - pattern: ${{ github.event.pages. ... .page_name}} + - pattern: ${{ github.event.head_commit.message }} + - pattern: ${{ github.event.head_commit.author.email }} + - pattern: ${{ github.event.head_commit.author.name }} + - pattern: ${{ github.event.commits ... .author.email }} + - pattern: ${{ github.event.commits ... .author.name }} + - pattern: ${{ github.event.pull_request.head.ref }} + - pattern: ${{ github.event.pull_request.head.label }} + - pattern: ${{ github.event.pull_request.head.repo.default_branch }} + - pattern: ${{ github.head_ref }} + - pattern: ${{ github.event.inputs ... }} + severity: ERROR + - id: yaml.github-actions.security.third-party-action-not-pinned-to-commit-sha.third-party-action-not-pinned-to-commit-sha + languages: + - yaml + message: An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-1357: Reliance on Insufficiently Trustworthy Component' + - 'CWE-353: Missing Support for Integrity Check' + impact: LOW + likelihood: LOW + owasp: A06:2021 - Vulnerable and Outdated Components + references: + - https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components + - https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions + subcategory: + - vuln + technology: + - github-actions + patterns: + - pattern-inside: '{steps: ...}' + - pattern: | + uses: "$USES" + - metavariable-pattern: + language: generic + metavariable: $USES + patterns: + - pattern-not-regex: ^[.]/ + - pattern-not-regex: ^actions/ + - pattern-not-regex: ^github/ + - pattern-not-regex: '@[0-9a-f]{40}$' + - pattern-not-regex: ^docker://.*@sha256:[0-9a-f]{64}$ + severity: WARNING + - id: yaml.github-actions.security.workflow-run-target-code-checkout.workflow-run-target-code-checkout + languages: + - yaml + message: This GitHub Actions workflow file uses `workflow_run` and checks out code from the incoming pull request. When using `workflow_run`, the Action runs in the context of the target repository, which includes access to all repository secrets. Normally, this is safe because the Action only runs code from the target repository, not the incoming PR. However, by checking out the incoming PR code, you're now using the incoming code for the rest of the action. You may be inadvertently executing arbitrary code from the incoming PR with access to repository secrets, which would let an attacker steal repository secrets. This normally happens by running build scripts (e.g., `npm build` and `make`) or dependency installation scripts (e.g., `python setup.py install`). Audit your workflow file to make sure no code from the incoming PR is executed. Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations. + metadata: + category: security + confidence: MEDIUM + cwe: 'CWE-913: Improper Control of Dynamically-Managed Code Resources' + impact: MEDIUM + likelihood: MEDIUM + owasp: A01:2017 - Injection + references: + - https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ + - https://github.com/justinsteven/advisories/blob/master/2021_github_actions_checkspelling_token_leak_via_advice_symlink.md + - https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability + subcategory: + - vuln + technology: + - github-actions + patterns: + - pattern-inside: | + on: + ... + workflow_run: ... + ... + ... + - pattern-inside: | + jobs: + ... + $JOBNAME: + ... + steps: + ... + - pattern: | + ... + uses: "$ACTION" + with: + ... + ref: $EXPR + - metavariable-regex: + metavariable: $ACTION + regex: actions/checkout@.* + - metavariable-pattern: + language: generic + metavariable: $EXPR + patterns: + - pattern: ${{ github.event.workflow_run ... }} + severity: WARNING + - id: yaml.github-actions.semgrep-configuration.semgrep-github-action-push-without-branches.semgrep-github-action-push-without-branches + languages: + - yaml + message: The 'branches' field (in the push event configuration) contains no branches. This causes all branches to be scanned and may result in unneccessary duplicate findings across the entire codebase. + metadata: + category: correctness + technology: + - github-action + paths: + include: + - .github/workflows/semgrep.yml + - '*.test.yml' + patterns: + - pattern-either: + - pattern: | + on: [..., push, ...] + ... + - pattern: | + on: push + ... + - pattern: | + on: + ... + push: "" + ... + ... + - pattern: | + on: + ... + push: {} + ... + ... + - patterns: + - pattern-inside: | + on: + ... + push: ... + ... + ... + - pattern-either: + - pattern: | + branches: "" + - pattern: | + branches: [] + severity: WARNING + - id: yaml.gitlab.correctness.changes-with-when-never.changes-with-when-never + languages: + - yaml + message: 'This Gitlab CI YAML will never run on default branches due to a `changes` rule with `when:never`. To fix this, make sure the triggering event is a push event. You can do this with `if: ''$CI_PIPELINE_SOURCE == "push"''`. See https://docs.gitlab.com/ee/ci/yaml/index.html#ruleschanges' + metadata: + category: correctness + technology: + - gitlab + - gitlab-ci + pattern: | + - changes: + - ... + when: never + severity: WARNING + - fix: 'cpu: 1000m' + id: yaml.kubernetes.best-practice.no-fractional-cpu-limits.no-fractional-cpu-limits + languages: + - yaml + message: When you set a fractional CPU limit on a container, the CPU cycles available will be throttled, even though most nodes can handle processes alternating between using 100% of the CPU. + metadata: + category: best-practice + technology: + - kubernetes + patterns: + - pattern-inside: | + limits: + ... + - pattern: | + cpu: $CPU_LIMIT + - metavariable-regex: + metavariable: $CPU_LIMIT + regex: \d{0,3}m + severity: WARNING + - fix: | + securityContext: + allowPrivilegeEscalation: false + $NAME + id: yaml.kubernetes.security.allow-privilege-escalation-no-securitycontext.allow-privilege-escalation-no-securitycontext + languages: + - yaml + message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. By adding a `securityContext` to your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag + subcategory: + - vuln + technology: + - kubernetes + patterns: + - pattern-inside: | + containers: + ... + - pattern-inside: | + - $NAME: $CONTAINER + ... + - pattern: | + image: ... + ... + - pattern-not: | + image: ... + ... + securityContext: + ... + - metavariable-regex: + metavariable: $NAME + regex: name + - focus-metavariable: $NAME + severity: WARNING + - fix: | + false + id: yaml.kubernetes.security.allow-privilege-escalation-true.allow-privilege-escalation-true + languages: + - yaml + message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. In the container `$CONTAINER` this parameter is set to `true` which makes this container much more vulnerable to privelege escalation attacks. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag + subcategory: + - vuln + technology: + - kubernetes + patterns: + - pattern-inside: | + containers: + ... + - pattern-inside: | + - name: $CONTAINER + ... + - pattern-inside: | + image: ... + ... + - pattern-inside: | + securityContext: + ... + - pattern: | + allowPrivilegeEscalation: $TRUE + - metavariable-pattern: + metavariable: $TRUE + pattern: | + true + - focus-metavariable: $TRUE + severity: WARNING + - fix: | + securityContext: + allowPrivilegeEscalation: false # + id: yaml.kubernetes.security.allow-privilege-escalation.allow-privilege-escalation + languages: + - yaml + message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. By adding the `allowPrivilegeEscalation` parameter to your the `securityContext`, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag + subcategory: + - vuln + technology: + - kubernetes + patterns: + - pattern-inside: | + containers: + ... + - pattern-inside: | + - name: $CONTAINER + ... + - pattern: | + image: ... + ... + - pattern-inside: | + image: ... + ... + $SC: + ... + - metavariable-regex: + metavariable: $SC + regex: ^(securityContext)$ + - pattern-not-inside: | + image: ... + ... + securityContext: + ... + allowPrivilegeEscalation: $VAL + - focus-metavariable: $SC + severity: WARNING + - fix-regex: + regex: development + replacement: dev + id: yaml.kubernetes.security.env.flask-debugging-enabled.flask-debugging-enabled + languages: + - yaml + message: Do not set FLASK_ENV to "development" since that sets `debug=True` in Flask. Use "dev" or a similar term instead. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-489: Active Debug Code' + impact: MEDIUM + likelihood: LOW + owasp: A06:2017 - Security Misconfiguration + references: + - https://flask.palletsprojects.com/en/2.0.x/debugging/ + - https://flask.palletsprojects.com/en/2.0.x/config/#ENV + subcategory: + - audit + technology: + - kubernetes + - flask + patterns: + - pattern-inside: | + env: [...] + - pattern: | + {name: FLASK_ENV, value: "development"} + severity: WARNING + - id: yaml.kubernetes.security.exposing-docker-socket-hostpath.exposing-docker-socket-hostpath + languages: + - yaml + message: Exposing host's Docker socket to containers via a volume. The owner of this socket is root. Giving someone access to it is equivalent to giving unrestricted root access to your host. Remove 'docker.sock' from hostpath to prevent this. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: HIGH + likelihood: LOW + references: + - https://kubernetes.io/docs/concepts/storage/volumes/#hostpath + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#volumes-and-file-systems + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-1-do-not-expose-the-docker-daemon-socket-even-to-the-containers + subcategory: + - vuln + technology: + - kubernetes + patterns: + - pattern-inside: | + volumes: + ... + - pattern: | + hostPath: + ... + path: /var/run/docker.sock + severity: WARNING + - id: yaml.kubernetes.security.hostipc-pod.hostipc-pod + languages: + - yaml + message: Pod is sharing the host IPC namespace. This allows container processes to communicate with processes on the host which reduces isolation and bypasses container protection models. Remove the 'hostIPC' key to disable this functionality. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-693: Protection Mechanism Failure' + impact: MEDIUM + likelihood: LOW + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces + subcategory: + - audit + technology: + - kubernetes + patterns: + - pattern-inside: | + spec: + ... + - pattern: | + hostIPC: true + severity: WARNING + - id: yaml.kubernetes.security.hostnetwork-pod.hostnetwork-pod + languages: + - yaml + message: Pod may use the node network namespace. This gives the pod access to the loopback device, services listening on localhost, and could be used to snoop on network activity of other pods on the same node. Remove the 'hostNetwork' key to disable this functionality. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-406: Insufficient Control of Network Message Volume (Network Amplification)' + impact: MEDIUM + likelihood: LOW + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces + subcategory: + - audit + technology: + - kubernetes + patterns: + - pattern-inside: | + spec: + ... + - pattern: | + hostNetwork: true + severity: WARNING + - id: yaml.kubernetes.security.hostpid-pod.hostpid-pod + languages: + - yaml + message: Pod is sharing the host process ID namespace. When paired with ptrace this can be used to escalate privileges outside of the container. Remove the 'hostPID' key to disable this functionality. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-269: Improper Privilege Management' + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2021 - Insecure Design + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces + subcategory: + - audit + technology: + - kubernetes + patterns: + - pattern-inside: | + spec: + ... + - pattern: | + hostPID: true + severity: WARNING + - id: yaml.kubernetes.security.legacy-api-clusterrole-excessive-permissions.legacy-api-clusterrole-excessive-permissions + languages: + - yaml + message: 'Semgrep detected a Kubernetes core API ClusterRole with excessive permissions. Attaching excessive permissions to a ClusterRole associated with the core namespace allows the V1 API to perform arbitrary actions on arbitrary resources attached to the cluster. Prefer explicit allowlists of verbs/resources when configuring the core API namespace. ' + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-269: Improper Privilege Management' + cwe2021-top25: false + impact: HIGH + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole + - https://kubernetes.io/docs/concepts/security/rbac-good-practices/#general-good-practice + - https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#api-groups + subcategory: + - vuln + technology: + - kubernetes + patterns: + - pattern: | + "*" + - pattern-inside: | + resources: $A + ... + - pattern-inside: | + verbs: $A + ... + - pattern-inside: | + - apiGroups: [""] + ... + - pattern-inside: | + apiVersion: rbac.authorization.k8s.io/v1 + ... + - pattern-inside: | + kind: ClusterRole + ... + severity: WARNING + - id: yaml.kubernetes.security.privileged-container.privileged-container + languages: + - yaml + message: Container or pod is running in privileged mode. This grants the container the equivalent of root capabilities on the host machine. This can lead to container escapes, privilege escalation, and other security concerns. Remove the 'privileged' key to disable this capability. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privileged + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html + subcategory: + - vuln + technology: + - kubernetes + pattern-either: + - patterns: + - pattern-inside: | + containers: + ... + - pattern: | + image: ... + ... + securityContext: + ... + privileged: true + - patterns: + - pattern-inside: | + spec: + ... + - pattern-not-inside: | + image: ... + ... + - pattern: | + privileged: true + severity: WARNING + - fix: | + securityContext: + runAsNonRoot: true + $IMAGE + id: yaml.kubernetes.security.run-as-non-root-container-level-missing-security-context.run-as-non-root-container-level-missing-security-context + languages: + - yaml + message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user + subcategory: + - audit + technology: + - kubernetes + patterns: + - pattern-inside: | + spec: + ... + containers: + ... + ... + - pattern-not-inside: | + spec: + ... + securityContext: + ... + runAsNonRoot: $VAL + ... + - pattern-inside: | + spec: + ... + containers: + ... + - pattern-inside: | + spec: + ... + containers: + ... + - name: $NAME + image: ... + ... + securityContext: + ... + runAsNonRoot: $VALUE + - pattern: | + - name: $CONTAINER + $IMAGE: $IMAGEVAL + ... + - pattern-not: | + - name: $CONTAINER + image: $IMAGEVAL + ... + securityContext: + ... + - metavariable-regex: + metavariable: $IMAGE + regex: image + - focus-metavariable: $IMAGE + severity: INFO + - fix: | + $SC: + runAsNonRoot: true # + id: yaml.kubernetes.security.run-as-non-root-container-level.run-as-non-root-container-level + languages: + - yaml + message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user + subcategory: + - audit + technology: + - kubernetes + patterns: + - pattern-inside: | + spec: + ... + containers: + ... + ... + - pattern-not-inside: | + spec: + ... + securityContext: + ... + runAsNonRoot: $VAL + ... + - pattern-inside: | + spec: + ... + containers: + ... + - pattern-inside: | + spec: + ... + containers: + ... + - name: $NAME + image: ... + ... + securityContext: + ... + runAsNonRoot: $VALUE + - pattern: | + - name: $CONTAINER + image: ... + ... + $SC: + ... + - metavariable-regex: + metavariable: $SC + regex: ^(securityContext)$ + - pattern-not: | + - name: $CONTAINER + image: ... + ... + securityContext: + ... + runAsNonRoot: $VALUE + - focus-metavariable: $SC + severity: INFO + - fix: | + $SC: + runAsNonRoot: true # + id: yaml.kubernetes.security.run-as-non-root-security-context-pod-level.run-as-non-root-security-context-pod-level + languages: + - yaml + message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user + subcategory: + - audit + technology: + - kubernetes + patterns: + - pattern-inside: | + spec: + ... + $SC: + ... + ... + - metavariable-regex: + metavariable: $SC + regex: ^(securityContext)$ + - pattern-not-inside: | + spec: + ... + securityContext: + runAsNonRoot: $VAL + ... + - pattern-inside: | + $SPEC: + ... + containers: + ... + - pattern-not-inside: | + $SPEC: + ... + containers: + ... + - name: $NAME + image: ... + ... + securityContext: + ... + runAsNonRoot: $VALUE + - focus-metavariable: $SC + severity: INFO + - fix: | + true + id: yaml.kubernetes.security.run-as-non-root-unsafe-value.run-as-non-root-unsafe-value + languages: + - yaml + message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: HIGH + likelihood: MEDIUM + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user + subcategory: + - audit + technology: + - kubernetes + patterns: + - pattern-either: + - pattern: | + spec: + ... + securityContext: + ... + runAsNonRoot: $VALUE + - patterns: + - pattern-inside: | + containers: + ... + - pattern: | + image: ... + ... + securityContext: + ... + runAsNonRoot: $VALUE + - metavariable-pattern: + metavariable: $VALUE + pattern: | + false + - focus-metavariable: $VALUE + severity: INFO + - fix: | + $SPEC: + securityContext: + runAsNonRoot: true # + id: yaml.kubernetes.security.run-as-non-root.run-as-non-root + languages: + - yaml + message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user + subcategory: + - audit + technology: + - kubernetes + patterns: + - pattern-inside: | + $SPEC: + ... + containers: + ... + ... + - metavariable-regex: + metavariable: $SPEC + regex: ^(spec)$ + - pattern-not-inside: | + spec: + ... + securityContext: + ... + ... + - pattern-inside: | + $SPEC: + ... + containers: + ... + - pattern-not-inside: | + $SPEC: + ... + containers: + ... + - name: $NAME + image: ... + ... + securityContext: + ... + runAsNonRoot: $VALUE + - focus-metavariable: $SPEC + severity: INFO + - id: yaml.kubernetes.security.seccomp-confinement-disabled.seccomp-confinement-disabled + languages: + - yaml + message: 'Container is explicitly disabling seccomp confinement. This runs the service in an unrestricted state. Remove ''seccompProfile: unconfined'' to prevent this.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-284: Improper Access Control' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + subcategory: + - vuln + technology: + - kubernetes + patterns: + - pattern-inside: | + containers: + ... + - pattern: | + image: ... + ... + securityContext: + ... + seccompProfile: unconfined + severity: WARNING + - id: yaml.kubernetes.security.secrets-in-config-file.secrets-in-config-file + languages: + - yaml + message: 'Secrets ($VALUE) should not be stored in infrastructure as code files. Use an alternative such as Bitnami Sealed Secrets or KSOPS to encrypt Kubernetes Secrets. ' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://kubernetes.io/docs/concepts/configuration/secret/ + - https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/0/CTR_Kubernetes_Hardening_Guidance_1.1_20220315.PDF + - https://docs.gitlab.com/ee/user/clusters/agent/gitops/secrets_management.html + - https://www.cncf.io/blog/2021/04/22/revealing-the-secrets-of-kubernetes-secrets/ + - https://github.com/bitnami-labs/sealed-secrets + - https://www.cncf.io/blog/2022/01/25/secrets-management-essential-when-using-kubernetes/ + - https://blog.oddbit.com/post/2021-03-09-getting-started-with-ksops/ + subcategory: + - vuln + technology: + - kubernetes + patterns: + - pattern: | + $KEY: $VALUE + - pattern-inside: | + data: ... + - pattern-inside: | + kind: Secret + ... + - metavariable-regex: + metavariable: $VALUE + regex: (?i)^[aA-zZ0-9+/]+={0,2}$ + - metavariable-analysis: + analyzer: entropy + metavariable: $VALUE + severity: WARNING + - id: yaml.kubernetes.security.skip-tls-verify-cluster.skip-tls-verify-cluster + languages: + - yaml + message: 'Cluster is disabling TLS certificate verification when communicating with the server. This makes your HTTPS connections insecure. Remove the ''insecure-skip-tls-verify: true'' key to secure communication.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://kubernetes.io/docs/reference/config-api/client-authentication.v1beta1/#client-authentication-k8s-io-v1beta1-Cluster + subcategory: + - vuln + technology: + - kubernetes + pattern: | + cluster: + ... + insecure-skip-tls-verify: true + severity: WARNING + - id: yaml.kubernetes.security.skip-tls-verify-service.skip-tls-verify-service + languages: + - yaml + message: 'Service is disabling TLS certificate verification when communicating with the server. This makes your HTTPS connections insecure. Remove the ''insecureSkipTLSVerify: true'' key to secure communication.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#apiservice-v1-apiregistration-k8s-io + subcategory: + - vuln + technology: + - kubernetes + pattern: | + spec: + ... + insecureSkipTLSVerify: true + severity: WARNING + - id: yaml.kubernetes.security.writable-filesystem-container.writable-filesystem-container + languages: + - yaml + message: 'Container $CONTAINER is running with a writable root filesystem. This may allow malicious applications to download and run additional payloads, or modify container files. If an application inside a container has to save something temporarily consider using a tmpfs. Add ''readOnlyRootFilesystem: true'' to this container to prevent this.' + metadata: + category: security + confidence: LOW + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#volumes-and-file-systems + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://blog.atomist.com/security-of-docker-kubernetes/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-8-set-filesystem-and-volumes-to-read-only + subcategory: + - audit + technology: + - kubernetes + patterns: + - pattern-inside: | + containers: + ... + - pattern-inside: | + - name: $CONTAINER + ... + - pattern: | + image: ... + ... + - pattern-not: | + image: ... + ... + securityContext: + ... + readOnlyRootFilesystem: true + - focus-metavariable: $CONTAINER + severity: WARNING + - id: yaml.openapi.security.api-key-in-query-parameter.api-key-in-query-parameter + languages: + - yaml + message: The $SECURITY_SCHEME security scheme passes an API key in a query parameter. API keys should not be passed as query parameters in security schemes. Pass the API key in the header or body. If using a query parameter is necessary, ensure that the API key is tightly scoped and short lived. + metadata: + category: security + confidence: LOW + cwe: 'CWE-598: Use of GET Request Method With Sensitive Query Strings' + impact: HIGH + likelihood: MEDIUM + owasp: + - A04:2021 Insecure Design + - A07:2021 Identification and Authentication Failures + references: + - https://datatracker.ietf.org/doc/html/rfc6749 + - https://cwe.mitre.org/data/definitions/598.html + - https://owasp.org/Top10/A04_2021-Insecure_Design/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ + subcategory: + - vuln + technology: + - openapi + patterns: + - pattern-inside: | + openapi: $VERSION + ... + components: + ... + securitySchemes: + ... + - metavariable-regex: + metavariable: $VERSION + regex: 3.* + - pattern: "$SECURITY_SCHEME:\n ...\n type: apiKey\n ...\n in: query\n \n" + severity: WARNING + - id: yaml.openapi.security.use-of-basic-authentication.use-of-basic-authentication + languages: + - yaml + message: Basic authentication is considered weak and should be avoided. Use a different authentication scheme, such of OAuth2, OpenID Connect, or mTLS. + metadata: + category: security + confidence: HIGH + cwe: 'CWE-287: Improper Authentication' + impact: HIGH + likelihood: MEDIUM + owasp: + - A04:2021 Insecure Design + - A07:2021 Identification and Authentication Failures + references: + - https://cwe.mitre.org/data/definitions/287.html + - https://owasp.org/Top10/A04_2021-Insecure_Design/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ + subcategory: + - vuln + technology: + - openapi + patterns: + - pattern-inside: | + openapi: $VERSION + ... + components: + ... + securitySchemes: + ... + $SCHEME: + ... + - metavariable-regex: + metavariable: $VERSION + regex: 3.* + - pattern: | + type: http + ... + scheme: basic + severity: ERROR + - id: yaml.semgrep.duplicate-id.duplicate-id + languages: + - yaml + message: The 'id' field $X was used multiple times. The 'id' field needs to be unique. + metadata: + category: correctness + technology: + - semgrep + patterns: + - pattern-inside: 'rules: [..., $RULE, ...]' + - pattern-inside: | + ... + - id: $X + ... + ... + - id: $X + ... + ... + - pattern: | + id: $X + severity: ERROR + - id: yaml.semgrep.duplicate-pattern.duplicate-pattern + languages: + - yaml + message: Two identical pattern clauses were detected. This will cause Semgrep to run the same pattern twice. Remove one of the duplicate pattern clauses. + metadata: + category: correctness + technology: + - semgrep + patterns: + - pattern-inside: 'rules: [..., $RULE, ...]' + - pattern-inside: | + - pattern: $X + ... + - pattern: $X + ... + - pattern: | + pattern: $X + severity: ERROR + - id: yaml.semgrep.empty-message.empty-message + languages: + - yaml + message: This rule has an empty message field. Consider adding a message field that communicates why this rule is an issue and how to fix it. This will increase the chance that the finding gets addressed. + metadata: + category: correctness + technology: + - semgrep + patterns: + - pattern-inside: 'rules: [..., $RULE, ...]' + - pattern: | + message: "" + severity: WARNING + - fix: | + options: + interfile: true + metadata + id: yaml.semgrep.interfile-true-under-metadata-and-no-options.interfile-true-under-metadata-and-no-options + languages: + - yaml + message: '`interfile: true` should be under the `options` field, not the `metadata` field.' + patterns: + - pattern: | + rules: + - id: $ID + ... + $METADATA: + ... + $INTERFILE: true + ... + ... + - pattern-not-inside: | + rules: + - id: $ID + ... + options: + ... + ... + - metavariable-regex: + metavariable: $INTERFILE + regex: interfile + - metavariable-regex: + metavariable: $METADATA + regex: metadata + - focus-metavariable: $METADATA + severity: WARNING + - fix: | + interfile: true + $FIRST_OPT + id: yaml.semgrep.interfile-true-under-metadata-and-options-already-present.interfile-true-under-metadata-and-options-already-present + languages: + - yaml + message: '`interfile: true` should be under the `options` field, not the `metadata` field.' + patterns: + - pattern: | + rules: + - id: $ID + ... + $METADATA: + ... + $INTERFILE: true + ... + ... + - pattern-inside: | + rules: + - id: $ID + ... + $OPTIONS: + $FIRST_OPT: $VAL + ... + ... + - pattern-not-inside: | + rules: + - id: $ID + ... + $OPTIONS: + ... + interfile: true + ... + ... + - metavariable-regex: + metavariable: $INTERFILE + regex: interfile + - metavariable-regex: + metavariable: $METADATA + regex: metadata + - metavariable-regex: + metavariable: $OPTIONS + regex: options + - focus-metavariable: $FIRST_OPT + severity: WARNING + - id: yaml.semgrep.key-indentation.yaml-key-indentation-check + languages: + - yaml + message: 'It looks like you have an YAML indentation issue -- instead of writing `$KEY`, put a space between the hyphen and what comes after! Otherwise, it reads as a single string. ' + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository + technology: + - semgrep + pattern-either: + - patterns: + - pattern-inside: | + rules: ... + - pattern: | + $KEY: >- + $VALUE + - focus-metavariable: $KEY + - metavariable-regex: + metavariable: $KEY + regex: ^-(\w*)$ + severity: WARNING + - fix-regex: + regex: (?<=\S)\s(\s{1,}) + replacement: ' ' + id: yaml.semgrep.message-whitespace.message-whitespace-check + languages: + - yaml + message: It looks like you have an additional space in your rule message, this can look awkward in the finding output, please remove the additional whitespace! + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository + technology: + - semgrep + patterns: + - pattern-inside: | + rules: ... + - pattern: | + message: >- + $VALUE + - focus-metavariable: + - $VALUE + - pattern-regex: \w.* + - pattern-regex: \s{2,} + severity: WARNING + - id: yaml.semgrep.metadata-category.metadata-category + languages: + - yaml + message: This Semgrep rule is missing a valid 'category' field in the 'metadata'. 'category' must be one of 'security', 'correctness', 'best-practice', 'performance', 'maintainability', or 'portability'. + metadata: + category: best-practice + technology: + - semgrep + patterns: + - pattern-inside: 'rules: [..., $RULE, ...]' + - pattern: 'id: $RULEID' + - pattern-not-inside: | + - ... + metadata: + ... + category: $CATEGORY + severity: INFO + - id: yaml.semgrep.metadata-confidence-incorrect-value.metadata-confidence-incorrect-value + languages: + - yaml + message: 'Semgrep rule confidence: $VALUE detected, but the value must be LOW, MEDIUM, or HIGH. For more information visit: https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/' + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ + technology: + - semgrep + patterns: + - pattern-inside: "rules: \n ...\n" + - pattern-inside: "metadata: \n ...\n category: security\n ...\n" + - pattern: | + confidence: $VALUE + - pattern-not: | + confidence: LOW + - pattern-not: | + confidence: MEDIUM + - pattern-not: | + confidence: HIGH + severity: WARNING + - id: yaml.semgrep.metadata-confidence.metadata-confidence + languages: + - yaml + message: This Semgrep rule is missing a valid 'confidence' field in the 'metadata'. which should be either LOW, MEDIUM, or HIGH. For more information visit https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository + technology: + - semgrep + patterns: + - pattern-inside: "rules: \n ...\n" + - pattern-inside: "metadata: \n ...\n category: security\n ...\n" + - pattern-not-inside: "metadata: \n ...\n confidence: $VALUE\n" + severity: WARNING + - id: yaml.semgrep.metadata-cwe.metadata-cwe + languages: + - yaml + message: '$...CWE The cwe tag in rule metadata should always be in the format "CWE-000: Title".' + metadata: + category: best-practice + technology: + - semgrep + patterns: + - pattern-inside: 'rules: ...' + - pattern-inside: 'metadata: ...' + - pattern: 'cwe: ...' + - pattern-not-regex: CWE-[\d]+:\s+\w + severity: ERROR + - fix-regex: + regex: deepsemgrep + replacement: interfile + id: yaml.semgrep.metadata-deepsemgrep.metadata-deepsemgrep + languages: + - yaml + message: 'We no longer support `deepsemgrep: true`, please use `interfile:true`' + metadata: + category: correctness + references: + - https://semgrep.dev/ + technology: + - semgrep + patterns: + - pattern-inside: "rules: \n ...\n" + - pattern-inside: "metadata: \n ...\n $DEEPSEMGREP: true\n ...\n" + - focus-metavariable: $DEEPSEMGREP + - metavariable-regex: + metavariable: $DEEPSEMGREP + regex: ^(deepsemgrep)$ + severity: WARNING + - id: yaml.semgrep.metadata-impact-incorrect-value.metadata-impact-incorrect-value + languages: + - yaml + message: 'Semgrep rule impact: $VALUE detected, but the value must be LOW, MEDIUM, or HIGH. For more information visit: https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/' + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ + technology: + - semgrep + patterns: + - pattern-inside: "rules: \n ...\n" + - pattern-inside: "metadata: \n ...\n category: security\n ...\n" + - pattern: | + impact: $VALUE + - pattern-not: | + impact: LOW + - pattern-not: | + impact: MEDIUM + - pattern-not: | + impact: HIGH + severity: WARNING + - id: yaml.semgrep.metadata-impact.metadata-impact + languages: + - yaml + message: This Semgrep rule is missing a valid 'impact' field in the 'metadata'. which should be either LOW, MEDIUM, or HIGH. For more information visit https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ + metadata: + category: correctness + references: + - https://semgrep.dev/docs/writing-rules/rule-syntax/#TODO + technology: + - semgrep + patterns: + - pattern-inside: "rules: \n ...\n" + - pattern-inside: "metadata: \n ...\n category: security\n ...\n" + - pattern-not-inside: "metadata: \n ...\n impact: $VALUE\n" + severity: WARNING + - id: yaml.semgrep.metadata-incorrect-option.metadata-incorrect-option + languages: + - yaml + message: It looks like $KEY is not in the default list of expected options, if this is a new key update this rule + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository + technology: + - semgrep + patterns: + - pattern-inside: | + rules: ... + - pattern-inside: | + options: + $A + - focus-metavariable: $A + - pattern: | + $KEY: $VALUE + - metavariable-regex: + metavariable: $KEY + regex: (?!options|constant_propagation|symbolic_propagation|taint_unify_mvars|taint_assume_safe_functions|taint_assume_safe_indexes|taint_assume_safe_comparisons|taint_assume_safe_booleans|taint_assume_safe_numbers|ac_matching|commutative_boolop|flddef_assign|arrow_is_function|let_is_var|go_deeper_expr|go_deeper_stmt|implicit_deep_exprstmt|implicit_ellipsis|xml_singleton_loose_matching|xml_attrs_implicit_ellipsis|xml_children_ordered|generic_engine|generic_multiline|generic_braces|generic_extra_braces|generic_extra_word_characters|generic_caseless|generic_ellipsis_max_span|generic_comment_style|interfile|generic_engine|commutative_compop|taint_focus_on) + severity: INFO + - id: yaml.semgrep.metadata-likelihood-incorrect-value.metadata-likelihood-incorrect-value + languages: + - yaml + message: 'Semgrep rule likelihood: $VALUE detected, but the value must be LOW, MEDIUM, or HIGH. For more information visit: https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/' + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ + technology: + - semgrep + patterns: + - pattern-inside: "rules: \n ...\n" + - pattern-inside: "metadata: \n ...\n category: security\n ...\n" + - pattern: | + likelihood: $VALUE + - pattern-not: | + likelihood: LOW + - pattern-not: | + likelihood: MEDIUM + - pattern-not: | + likelihood: HIGH + severity: WARNING + - id: yaml.semgrep.metadata-likelihood.metadata-likelihood + languages: + - yaml + message: This Semgrep rule is missing a valid 'likelihood' field in the 'metadata'. which should be either LOW, MEDIUM, or HIGH. For more information visit https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ + technology: + - semgrep + patterns: + - pattern-inside: "rules: \n ...\n" + - pattern-inside: "metadata: \n ...\n category: security\n ...\n" + - pattern-not-inside: "metadata: \n ...\n likelihood: $VALUE\n" + severity: WARNING + - id: yaml.semgrep.metadata-owasp.metadata-owasp + languages: + - json + - yaml + message: The `owasp` tag in Semgrep rule metadata should start with the format "A00:YYYY", where A00 is the OWASP top ten number and YYYY is the OWASP top ten year. + metadata: + category: best-practice + technology: + - semgrep + patterns: + - pattern-inside: 'rules: ...' + - pattern-inside: 'metadata: ...' + - pattern-either: + - patterns: + - pattern: 'owasp: "..."' + - pattern-not: 'owasp: "=~/^A(0?[1-9]|10):\s+.+$/"' + - pattern-not: 'owasp: "=~/^A(0[1-9]|10):([0-9]{4})?\s+.+$/"' + - patterns: + - pattern-inside: 'owasp: [...]' + - pattern: '"$ANYTHING"' + - pattern-not-regex: .*A(0[1-9]|10):[0-9]{4}\s+.* + - pattern-not-regex: 'owasp:' + severity: ERROR + - id: yaml.semgrep.metadata-references.metadata-references + languages: + - json + - yaml + message: The references in rule metadata should always be a list, even if there's only one. + metadata: + category: correctness + technology: + - semgrep + patterns: + - pattern-inside: | + rules: ... + - pattern-inside: | + metadata: ... + - pattern: | + references: ... + - pattern-not: | + references: [...] + severity: ERROR + - id: yaml.semgrep.metadata-subcategory-incorrect-value.metadata-subcategory-incorrect-value + languages: + - yaml + message: 'Semgrep rule likelihood: $VALUE detected, but the value must be vuln, audit, or guardrail. For more information visit: https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/' + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ + technology: + - semgrep + patterns: + - pattern-inside: "rules: \n ...\n" + - pattern-inside: "metadata: \n ...\n category: security\n ...\n" + - pattern: "subcategory: \n - $VALUE\n" + - pattern-not: "subcategory: \n - vuln\n" + - pattern-not: "subcategory: \n - audit\n" + - pattern-not: "subcategory: \n - guardrail\n" + severity: WARNING + - id: yaml.semgrep.metadata-subcategory.metadata-subcategory + languages: + - yaml + message: This Semgrep rule is missing a valid 'subcategory' field in the 'metadata'. which should be either audit, vuln, or guardrail. For more information visit https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ + technology: + - semgrep + patterns: + - pattern-inside: "rules: \n ...\n" + - pattern-inside: "metadata: \n ...\n category: security\n ...\n" + - pattern-not-inside: "metadata: \n ...\n subcategory: $VALUE\n" + severity: WARNING + - id: yaml.semgrep.metadata-technology.metadata-technology + languages: + - yaml + message: This Semgrep rule is missing a 'technology' field in the 'metadata'. Consider adding a list of technologies based on the rule's associated library or framework, or another piece of relevant information. + metadata: + category: best-practice + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/#technology + technology: + - semgrep + pattern-either: + - patterns: + - pattern-not-inside: | + - ... + mode: join + - pattern-inside: 'rules: [..., $RULE, ...]' + - pattern: $RULE + - pattern: | + id: ... + ... + - pattern-not: | + id: ... + ... + metadata: + ... + technology: + - ... + - patterns: + - pattern-inside: | + id: $OUTER_RULEID + mode: join + join: + rules: [ ..., $INNER_RULE, ...] + ... + ... + - pattern-not: | + id: $OUTER_RULEID + ... + metadata: + ... + technology: + - ... + severity: INFO + - id: yaml.semgrep.missing-language-field.missing-language-field + languages: + - yaml + message: Please include a 'languages' field for your rule $RULEID! + metadata: + category: correctness + references: + - https://semgrep.dev/docs/writing-rules/rule-syntax/#required + technology: + - semgrep + pattern-either: + - patterns: + - pattern-inside: 'rules: [..., $RULE, ...]' + - pattern: 'id: $RULEID' + - pattern-not-inside: | + - ... + languages: ... + - pattern-not-inside: | + - ... + mode: join + - patterns: + - pattern-inside: | + rules: [ ..., $OUTER_RULE, ...] + - pattern-inside: $OUTER_RULE + - pattern-inside: | + id: $OUTER_RULEID + mode: join + join: + rules: [ ..., $INNER_RULE, ...] + ... + ... + - pattern-inside: $INNER_RULE + - pattern-not-inside: | + - languages: ... + ... + - pattern: | + id: $RULEID + severity: WARNING + - id: yaml.semgrep.missing-message-field.missing-message-field + languages: + - yaml + message: This rule does not have a message. Semgrep requires that rules have a message. Include a message to explain what the rule does. Consider writing a message that explains why this is an issue and how to fix it. + metadata: + category: correctness + references: + - https://semgrep.dev/docs/writing-rules/rule-syntax/ + technology: + - semgrep + patterns: + - pattern-inside: 'rules: [..., $RULE, ...]' + - pattern: 'id: $RULEID' + - pattern-not-inside: | + - ... + message: ... + - pattern-not-inside: | + - ... + mode: extract + severity: WARNING + - id: yaml.semgrep.multi-line-message.multi-line-message + languages: + - yaml + message: 'This rule has a multi-line message field, which may display poorly in a terminal. Consider ensuring it is on one line. For example, use `message: >-`, not `message: |`.' + metadata: + category: correctness + references: + - https://github.com/returntocorp/semgrep-rules/issues/1431 + technology: + - semgrep + patterns: + - pattern-inside: 'rules: [..., $RULE, ...]' + - pattern: | + message: "=~/[\\n\\r]/" + severity: WARNING + - id: yaml.semgrep.rule-missing-deconstructed-value.missing-deconstructed-value + languages: + - yaml + message: Looks like this value is deconstructing a const/var/let you need to use all three `const {...} =` `var {...} =` and `let {...} =` to provide accurate coverage consider adding the missing patterns in a `pattern-inside` for better coverage. + metadata: + category: correctness + references: + - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository + technology: + - semgrep + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + rules: ... + - pattern-not-inside: | + - pattern-either: + ... + - pattern: | + - pattern-inside: + $VALUE + - pattern-either: + - pattern-regex: const {.*}.*= + - pattern-regex: let {.*}.*= + - pattern-regex: var {.*}.*= + - patterns: + - patterns: + - pattern-inside: | + rules: ... + - pattern-inside: | + - pattern-either: + $VALUE + - focus-metavariable: + - $VALUE + - pattern-inside: "- pattern-inside: \n $A\n" + - metavariable-regex: + metavariable: $A + regex: .*\s.*(var|const|let)\s{.*}\s= + - pattern-not: + patterns: + - pattern-inside: "...\n- pattern-inside: \n $Z\n...\n- pattern-inside: \n $B\n... \n- pattern-inside: \n $C\n...\n" + - metavariable-regex: + metavariable: $Z + regex: .*\s.*(var|const|let).*{.*} + - metavariable-regex: + metavariable: $B + regex: .*\s.*(var|const|let).*{.*} + - metavariable-regex: + metavariable: $C + regex: .*\s.*(var|const|let).*{.*} + severity: WARNING + - id: yaml.semgrep.slow-pattern-general-function.slow-pattern-general-func + languages: + - yaml + message: Using patterns like `function (...) {...}` is too general it will probably slow down the rule performance. + metadata: + category: performance + technology: + - semgrep + patterns: + - pattern-either: + - pattern-inside: | + pattern-inside: $X + - pattern-inside: | + pattern-not-inside: $X + - pattern-inside: | + pattern: $X + - pattern-inside: | + pattern-not: $X + - pattern-regex: function[^{]*{[\s\n]*\.\.\.[\s\n]*} + - pattern-either: + - pattern-inside: | + languages: [...,"javascript",...] + ... + - pattern-inside: | + languages: [...,"typescript",...] + ... + severity: WARNING + - id: yaml.semgrep.slow-pattern-general-property.slow-pattern-general-property + languages: + - yaml + message: Using patterns like `$X.$Y` may be too general and may slow down the rule performance. + metadata: + category: performance + technology: + - semgrep + patterns: + - pattern-either: + - pattern-inside: | + pattern-inside: $X + - pattern-inside: | + pattern-not-inside: $X + - pattern-inside: | + pattern: $X + - pattern-inside: | + pattern-not: $X + - pattern-regex: \$[A-Z]*\.\$[A-Z]* + severity: WARNING + - id: yaml.semgrep.slow-pattern-single-metavariable.slow-pattern-single-metavariable + languages: + - yaml + message: Using a single metavariable as a pattern drastically slows down the rule performance because it will match every expression in a file. Instead, try to match something specific such as a function name, or anchor on a statement that may occur above or below the pattern. The more specific you can be, the faster the pattern will run. + metadata: + category: performance + technology: + - semgrep + patterns: + - pattern-either: + - pattern-inside: | + pattern-inside: $PATTERN + - pattern-inside: | + pattern-not-inside: $PATTERN + - pattern-inside: | + pattern: $PATTERN + - pattern-inside: | + pattern-not: $PATTERN + - metavariable-regex: + metavariable: $PATTERN + regex: \$[A-Z_]* + severity: WARNING + - id: yaml.semgrep.slow-pattern-top-ellipsis.slow-pattern-top-ellipsis + languages: + - yaml + message: Using the ellipsis operator `...` at the top of the pattern drastically slows down the rule performance. + metadata: + category: performance + technology: + - semgrep + patterns: + - pattern-either: + - pattern-inside: | + pattern-inside: $X + - pattern-inside: | + pattern-not-inside: $X + - pattern-inside: | + pattern: $X + - pattern-inside: | + pattern-not: $X + - pattern-regex: \|\s*\n\s*\.\.\.\s*\n[^\n]*\n\s*\.\.\. + severity: WARNING + - id: yaml.semgrep.unnecessary-parent.unnecessary-parent-operator + languages: + - yaml + message: Unnecessary parent operator. Remove one to fix. + metadata: + category: best-practice + technology: + - semgrep + patterns: + - pattern-inside: 'rules: [..., $RULE, ...]' + - pattern-either: + - patterns: + - pattern: | + pattern-either: + - $THING1 + - ... + - pattern-not: | + pattern-either: + - $THING1 + - $THING2 + - ... + - patterns: + - pattern: | + patterns: + - $THING1 + - ... + - pattern-not: | + patterns: + - $THING1 + - $THING2 + - ... + - pattern: | + pattern-either: + - ... + - pattern-either: + - ... + severity: WARNING + - id: yaml.semgrep.unsatisfiable.unsatisfiable-rule + languages: + - yaml + message: You can not use 'pattern' $A and 'pattern-not' $A together; this will always be empty. + metadata: + category: correctness + technology: + - semgrep + patterns: + - pattern-inside: 'patterns: [...]' + - pattern-either: + - patterns: + - pattern-inside: | + - pattern: $A + ... + - pattern: | + - pattern-not: $A + - patterns: + - pattern-inside: | + - pattern-not: $A + ... + - pattern: | + - pattern: $A + severity: ERROR + - id: c_access_rule-RpcImpersonateClient-ImpersonateLoggedOnUser + languages: + - c + - cpp + - cpp + message: | + These functions may be used to either drop or change account privileges. If the calls + fail, the process will continue to run with the privileges assigned to it on start. Depending + on + the logic of the application, this may allow attackers to abuse the system due to privileges + never + being changed to a different access level. + + Always ensure return values of this function are checked to determine if the application should + continue to operate. + metadata: + category: security + cwe: CWE-250 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: High + shortDescription: Ensure return values are checked when attempting to drop privileges + pattern-either: + - pattern: RpcImpersonateClient(...) + - pattern: ImpersonateLoggedOnUser(...) + - pattern: CoImpersonateClient(...) + - pattern: ImpersonateNamedPipeClient(...) + - pattern: ImpersonateDdeClientWindow(...) + - pattern: ImpersonateSecurityContext(...) + - pattern: SetThreadToken(...) + severity: ERROR + - id: c_access_rule-umask + languages: + - c + - cpp + - cpp + message: | + The umask function call sets the process's file mode creation mask. umask values determine + what permissions a file should be created with and who can read or write to these files. + Ensure that umask is given most restrictive possible setting depending on the context, + usually 066 or 077, for more information please see: + https://en.wikipedia.org/wiki/Umask#Mask_effect. + metadata: + category: security + cwe: CWE-732 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: High + shortDescription: Ensure restrictive umask values + pattern: umask(...) + severity: INFO + - id: c_buffer_rule-MultiByteToWideChar + languages: + - c + - cpp + - cpp + message: | + The input buffer is the number of bytes in the string, but the size + of the output buffer is the number of characters. To avoid overflows, the + application must determine the correct buffer size which depends on the data type + the buffer receives. + + For more information see: + https://learn.microsoft.com/en-us/windows/win32/intl/security-considerations--international-features + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Easily misused function may lead to buffer overflows + pattern: MultiByteToWideChar(...) + severity: INFO + - id: c_buffer_rule-StrCat-StrCatA + languages: + - c + - cpp + - cpp + message: | + The `StrCat` family of functions do not guarantee the final string to be null terminated. + Consider using one of the following alternatives: `StringCbCat`, `StringCbCatEx`, + `StringCbCatN`, `StringCbCatNEx`, `StringCchCat`, `StringCchCatEx`, `StringCchCatN`, or + `StringCchCatNEx`. + + For more information please see: https://learn.microsoft.com/en-us/windows/win32/api/strsafe/ + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure string processing function + pattern-either: + - pattern: strcat(...) + - pattern: strcatA(...) + - pattern: StrcatW(...) + - pattern: lstrcatA(...) + - pattern: lstrcatW(...) + - pattern: strCatBuff(...) + - pattern: StrCatBuffA(...) + - pattern: StrCatBuffW(...) + - pattern: StrCatChainW(...) + - pattern: _tccat(...) + - pattern: _mbccat(...) + - pattern: _ftcscat(...) + - pattern: StrCatN(...) + - pattern: StrCatNA(...) + - pattern: StrCatNW(...) + - pattern: StrNCat(...) + - pattern: StrNCatA(...) + - pattern: StrNCatW(...) + - pattern: lstrncat(...) + - pattern: lstrcatnA(...) + - pattern: lstrcatnW(...) + severity: ERROR + - id: c_buffer_rule-fscanf-sscanf + languages: + - c + - cpp + - cpp + message: | + Format specifiers can take optional field widths, which should be + used to limit how many characters are copied into the target buffer. + + Example: + ``` + const char str[20] = "AAAAAAAAAAAAAAAAAAA"; + char buf[11] = {0}; + sscanf(str, "%10s", &buf); // buf = AAAAAAAAAA\0 + ``` + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: sscanf() functions may allow format string based overflows + pattern-either: + - pattern: fscanf(...) + - pattern: sscanf(...) + - pattern: vsscanf(...) + - pattern: vfscanf(...) + - pattern: _ftscanf(...) + - pattern: fwscanf(...) + - pattern: vfwscanf(...) + - pattern: vswscanf(...) + severity: ERROR + - id: c_buffer_rule-g-get-home-dir + languages: + - c + - cpp + - cpp + message: | + This function is synonymous with `getenv("HOME")` and should be treated + as untrusted input as it could be modified by an attacker. Possible risks + include: + + - The value being too large and causing buffer overflows + - Files under the attacker's control being used maliciously + - Files outside of an attacker's control becoming accessible, depending on + access privileges. + metadata: + category: security + cwe: CWE-807 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Reliance on untrusted inputs in a security decision + pattern: g_get_home_dir(...) + severity: WARNING + - id: c_buffer_rule-g-get-tmp-dir + languages: + - c + - cpp + - cpp + message: | + This function is synonymous with `getenv("TMP")` and should be treated + as untrusted input as it could be modified by an attacker. Possible risks + include: + + - The value being too large and causing buffer overflows + - Files under the attacker's control being used maliciously + - Files outside of an attacker's control becoming accessible, depending on + access privileges. + metadata: + category: security + cwe: CWE-807 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Reliance on untrusted inputs in a security decision + pattern: g_get_tmp_dir(...) + severity: WARNING + - id: c_buffer_rule-getenv-curl-getenv + languages: + - c + - cpp + - cpp + message: | + This function's return value should be treated as untrusted input as it could be + modified by an attacker. Possible risks include: + + - The value being too large and causing buffer overflows + - Files under the attacker's control being used maliciously + - Files outside of an attacker's control becoming accessible, depending on + access privileges. + metadata: + category: security + cwe: CWE-807 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Reliance on untrusted inputs in a security decision + pattern-either: + - pattern: getenv(...) + - pattern: curl_getenv(...) + severity: WARNING + - id: c_buffer_rule-gets--getts + languages: + - c + - cpp + - cpp + message: | + The gets() function reads a line from stdin into the provided buffer + until either a terminating newline or EOF. This terminating newline or + EOF is replaced with a null byte `'\0'`. No check for buffer overruns are + performed so it is recommended to use `fgets()` instead. Do note + that some platforms will continue reading data after a `'\0'` is encountered. + + Usage of `fgets()` is not recommended for reading binary based files or inputs, + instead the `read` or `fread` functions should be used. + + For more information please see: https://linux.die.net/man/3/fgets + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Use of deprecated function (gets) + pattern-either: + - pattern: gets(...) + - pattern: _getts(...) + - pattern: _getws(...) + severity: ERROR + - id: c_buffer_rule-getwd + languages: + - c + - cpp + - cpp + message: | + `getwd` does not contain a parameter to limit how many characters can be copied into the + destination buffer. For portability and security reasons `getwd` has been deprecated in + favor of `getcwd`. + + For more information please see: https://linux.die.net/man/3/getcwd + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insufficient protection against buffer overflow (getwd) + pattern: getwd(...) + severity: WARNING + - id: c_buffer_rule-lstrcat-wcscat + languages: + - c + - cpp + - cpp + message: | + The `strcat` family of functions are unable to limit how many bytes are copied + to the destination buffer. It is recommended to use more secure alternatives such as + `snprintf`. + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strcat-s-wcscat-s-mbscat-s?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure functions unable to limit / check buffer sizes + pattern-either: + - pattern: lstrcat(...) + - pattern: wcscat(...) + - pattern: _tcscat(...) + - pattern: _mbscat(...) + severity: ERROR + - id: c_buffer_rule-lstrcatn-wcsncat + languages: + - c + - cpp + - cpp + message: | + Consider using more secure alternatives such as `snprintf`, instead of the + `wcsncat` family of functions. + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncat-strncat-l-wcsncat-wcsncat-l-mbsncat-mbsncat-l?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Easily misused string processing functions + pattern-either: + - pattern: lstrcatn(...) + - pattern: wcsncat(...) + - pattern: _tcsncat(...) + - pattern: _mbsnbcat(...) + severity: INFO + - id: c_buffer_rule-lstrcpy-wcscpy + languages: + - c + - cpp + - cpp + message: | + The `lstrcpy` family of functions do not provide the ability to limit or check buffer + sizes before copying to a destination buffer. This can lead to buffer overflows. Consider + using more secure alternatives such as `strncpy_s`. + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-s-strncpy-s-l-wcsncpy-s-wcsncpy-s-l-mbsncpy-s-mbsncpy-s-l?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure functions unable to limit / check buffer sizes + pattern-either: + - pattern: lstrcpy(...) + - pattern: wcscpy(...) + - pattern: _tcscpy(...) + - pattern: _mbscpy(...) + severity: ERROR + - id: c_buffer_rule-lstrcpyn-wcsncpy + languages: + - c + - cpp + - cpp + message: | + The `lstrcpyn` family of functions do not always check for invalid pointers or check if there + is sufficient space prior to copying. The count argument limits the number of characters copied + but does validate if the count will fit within the size of the destination buffer, leading to + potential overflows. + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-s-strncpy-s-l-wcsncpy-s-wcsncpy-s-l-mbsncpy-s-mbsncpy-s-l?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure functions do not always null terminate or check invalid pointers + pattern-either: + - pattern: lstrcpyn(...) + - pattern: wcsncpy(...) + - pattern: _tcsncpy(...) + - pattern: _mbsnbcpy(...) + severity: INFO + - id: c_buffer_rule-memcpy-CopyMemory + languages: + - c + - cpp + - cpp + message: | + The `memcpy` family of functions require the developer to validate that the destination buffer + is the same size or larger than the source buffer. Buffer overflows could be introduced if care + is not taken to validate buffer sizes. + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/memcpy-s-wmemcpy-s?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Function does not check for buffer overflows when copying + pattern-either: + - pattern: memcpy(...) + - pattern: CopyMemory(...) + - pattern: bcopy(...) + severity: INFO + - id: c_buffer_rule-realpath + languages: + - c + - cpp + - cpp + message: | + The `realpath` function should not be called with a destination buffer as it could + lead to overflowing if the path is greater than PATH_LEN. It is instead recommended + to call `realpath` with the destination buffer set to NULL and use the return value + as the resolved path. Be sure to free the returned pointer as realpath will allocate + the buffer internally using `malloc`. + + For more information see: https://linux.die.net/man/3/realpath + + Example: + + ``` + char const *symlink_path = "/tmp/symlink"; + char *resolved_path = NULL; + + resolved_path = realpath(symlink_path, NULL); + if (errno == 0) { + // ... use resolved_path... + free(resolved_path); + } + ``` + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Function does not ensure destination buffer length is sufficient before copying + pattern: realpath(...) + severity: WARNING + - id: c_buffer_rule-scanf-vscanf + languages: + - c + - cpp + - cpp + message: | + Format specifiers can take optional field widths, which should be + used to limit how many characters are copied into the target buffer. + + For more information please see: https://linux.die.net/man/3/scanf + + Example: + ``` + char buf[11] = {0}; + scanf("%10s", &buf); // buf = AAAAAAAAAA\0 + ``` + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/scanf-s-scanf-s-l-wscanf-s-wscanf-s-l?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: scanf() functions may allow format string based overflows + pattern-either: + - patterns: + - pattern: scanf($FMT, ...) + - pattern-not: scanf("...", ...) + - patterns: + - pattern: vscanf($FMT, ...) + - pattern-not: vscanf("...", ...) + - patterns: + - pattern: wscanf($FMT, ...) + - pattern-not: wscanf("...", ...) + - patterns: + - pattern: _tscanf($FMT, ...) + - pattern-not: _tscanf(_T("..."), ...) + - patterns: + - pattern: vwscanf(FMT, ...) + - pattern-not: vwscanf("...", ...) + severity: ERROR + - id: c_buffer_rule-sprintf-vsprintf + languages: + - c + - cpp + - cpp + message: | + Use sprintf_s, snprintf, or vsnprintf instead. The `sprintf` family of functions do not allow + callers to set limits on how many bytes the destination buffer can hold. Consider using more + secure alternatives such as `snprintf`. + + For more information please see: https://linux.die.net/man/3/snprintf + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/sprintf-s-sprintf-s-l-swprintf-s-swprintf-s-l?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure function unable to limit / check buffer sizes + pattern-either: + - pattern: sprintf(...) + - pattern: vsprintf(...) + - pattern: swprintf(...) + - pattern: vswprintf(...) + - pattern: _stprintf(...) + - pattern: _vstprintf(...) + severity: ERROR + - id: c_buffer_rule-strcat + languages: + - c + - cpp + - cpp + message: | + The `strcat` family of functions are unable to limit how many bytes are copied + to the destination buffer. It is recommended to use more secure alternatives such as + `snprintf`. + + For more information please see: https://linux.die.net/man/3/snprintf + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strcat-s-wcscat-s-mbscat-s?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure string processing function + pattern: strcat(...) + severity: ERROR + - id: c_buffer_rule-strccpy-strcadd + languages: + - c + - cpp + - cpp + message: | + The `strccpy` and `strcadd` functions do not allow the caller to check that the destination + size + of the buffer will fit the input buffer prior to copying. + + For more information please see: + https://docs.oracle.com/cd/E18752_01/html/816-5172/streadd-3gen.html + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure string processing functions + pattern-either: + - pattern: strccpy(...) + - pattern: strcadd(...) + severity: INFO + - id: c_buffer_rule-strcpy + languages: + - c + - cpp + - cpp + message: | + The `strcpy` family of functions do not provide the ability to limit or check buffer + sizes before copying to a destination buffer. This can lead to buffer overflows. Consider + using more secure alternatives such as `strncpy` and provide the correct limit to the + destination buffer and ensure the string is null terminated. + + For more information please see: https://linux.die.net/man/3/strncpy + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-s-strncpy-s-l-wcsncpy-s-wcsncpy-s-l-mbsncpy-s-mbsncpy-s-l?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure string processing function (strcpy) + pattern: strcpy(...) + severity: ERROR + - id: c_buffer_rule-strcpyA-strcpyW + languages: + - c + - cpp + - cpp + message: | + The `StrCpy` family of functions do not guarantee the final string to be null terminated. + Consider + using one of the following alternatives `StringCbCopy`, `StringCbCopyEx`, `StringCbCopyN`, + `StringCbCopyNEx`, `StringCchCopy`, `StringCchCopyEx`, `StringCchCopyN`, or `StringCchCopyNEx`. + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-s-strncpy-s-l-wcsncpy-s-wcsncpy-s-l-mbsncpy-s-mbsncpy-s-l?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure string processing function + pattern-either: + - pattern: strcpyA(...) + - pattern: strcpyW(...) + - pattern: StrCpy(...) + - pattern: StrCpyA(...) + - pattern: lstrcpyA(...) + - pattern: lstrcpyW(...) + - pattern: _tccpy(...) + - pattern: _mbccpy(...) + - pattern: _ftcscpy(...) + - pattern: _mbsncpy(...) + - pattern: StrCpyN(...) + - pattern: StrCpyNA(...) + - pattern: StrCpyNW(...) + - pattern: StrNCpy(...) + - pattern: strcpynA(...) + - pattern: StrNCpyA(...) + - pattern: StrNCpyW(...) + - pattern: lstrcpynA(...) + - pattern: lstrcpynW(...) + severity: ERROR + - id: c_buffer_rule-streadd-strecpy + languages: + - c + - cpp + - cpp + message: | + The `strecpy` and `streadd` functions require that the destination buffer size be at least + four + times the size of the source due to each character potentially becoming a `\` and 3 digits. + + For more information please see: + https://docs.oracle.com/cd/E18752_01/html/816-5172/streadd-3gen.html + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure string processing functions + pattern-either: + - pattern: streadd(...) + - pattern: strecpy(...) + severity: ERROR + - id: c_buffer_rule-strlen-wcslen + languages: + - c + - cpp + - cpp + message: | + The `strlen` family of functions does not handle strings that are not null + terminated. This can lead to buffer over reads and cause the application to + crash by accessing unintended memory locations. It is recommended that `strnlen` + be used instead as a `maxlen` value can be provided. + + For more information please see: https://linux.die.net/man/3/strnlen + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strnlen-strnlen-s?view=msvc-170 + metadata: + category: security + cwe: CWE-126 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Function does not handle null terminated strings properly + pattern-either: + - pattern: strlen(...) + - pattern: wcslen(...) + - pattern: _tcslen(...) + - pattern: _mbslen(...) + severity: INFO + - id: c_buffer_rule-strncat + languages: + - c + - cpp + - cpp + message: | + The `strncat` family of functions are easy to use incorrectly when calculating destination + buffer + sizes. It is recommended to use more secure alternatives such as `snprintf`. + + For more information please see: https://linux.die.net/man/3/snprintf + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncat-s-strncat-s-l-wcsncat-s-wcsncat-s-l-mbsncat-s-mbsncat-s-l?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Function does not handle null terminated strings or invalid pointers properly + pattern: strncat(...) + severity: INFO + - id: c_buffer_rule-strncpy + languages: + - c + - cpp + - cpp + message: | + The `strncpy` family of functions do not properly handle strings that are not null terminated. + It is recommended to use more secure alternatives such as `snprintf`. + + For more information please see: https://linux.die.net/man/3/snprintf + + If developing for C Runtime Library (CRT), more secure versions of these functions should be + used, see: + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-s-strncpy-s-l-wcsncpy-s-wcsncpy-s-l-mbsncpy-s-mbsncpy-s-l?view=msvc-170 + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Function does not handle null terminated strings or invalid pointers properly + pattern: strncpy(...) + severity: INFO + - id: c_buffer_rule-strtrns + languages: + - c + - cpp + - cpp + message: | + This function is easy to misuse by not accounting for the space necessary when transforming + strings. Ensure that the destination buffer is large enough to fit the transformed output. + + For more information please see: + https://docs.oracle.com/cd/E36784_01/html/E36877/strtrns-3gen.html + metadata: + category: security + cwe: CWE-120 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Insecure string processing function + pattern: strtrns(...) + severity: WARNING + - id: c_crypto_rule-EVP-des-ecb-EVP-des-cbc + languages: + - c + - cpp + - cpp + message: | + The DES algorithm has not been recommended for over 15 years and was withdrawn from NIST (FIPS + 46-3) in 2005. + + Consider using libsodium's `crypto_secretbox_easy` authenticated encryption functions instead. + + For more information please see: + https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox. + + If you must be FIPS compliant, consider using OpenSSLs AES or 3DES ciphers. + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Insecure encryption algorithm (DES) + pattern-either: + - pattern: EVP_des_ecb(...) + - pattern: EVP_des_cbc(...) + - pattern: EVP_des_cfb(...) + - pattern: EVP_des_ofb(...) + - pattern: EVP_desx_cbc(...) + severity: ERROR + - id: c_crypto_rule-EVP-rc4-40-EVP-rc2-40-cbc + languages: + - c + - cpp + - cpp + message: | + The RC4 algorithm is vulnerable to many attacks and should no longer be used for encrypting + data streams. + + Consider using libsodium's `crypto_secretstream_xchacha20poly1305` stream cipher encryption + functions instead. For more information please see: + https://libsodium.gitbook.io/doc/secret-key_cryptography/secretstream + + If you must be FIPS compliant, consider using OpenSSLs AES or 3DES ciphers. + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Insecure stream cipher (RC4) + pattern-either: + - pattern: EVP_rc4_40(...) + - pattern: EVP_rc2_40_cbc(...) + - pattern: EVP_rc2_64_cbc(...) + severity: ERROR + - id: c_crypto_rule-crypt-crypt-r + languages: + - c + - cpp + - cpp + message: | + The crypt functions are not recommended due to the significantly small + key space. Modern hardware can crack crypt produced passwords relatively quickly. + + Consider using the Argon2id password hashing algorithm provided by libsodium. + For more information please see: https://libsodium.gitbook.io/doc/password_hashing. + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Insecure hashing algorithm + pattern-either: + - pattern: crypt(...) + - pattern: crypt_r(...) + severity: ERROR + - id: c_format_rule-fprintf-vfprintf + languages: + - c + - cpp + - cpp + message: | + Format string vulnerabilities allow an attacker to read or in some cases, + potentially write data to + and from locations in the processes' memory. To prevent against format + string attacks, do not allow + users or un-validated input to provide the format specification. + Consider using a constant for the format specification, or only allow specific + characters to be provided to the format argument for the `fprintf` family of functions. + + For more information please see: https://linux.die.net/man/3/fprintf + + For more information on format string attacks please see OWASP's attack + guide: https://owasp.org/www-community/attacks/Format_string_attack + metadata: + category: security + cwe: CWE-134 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Potential format string vulnerability + pattern-either: + - patterns: + - pattern: fprintf($FD, $FMT, ...) + - pattern-not: fprintf($FD, "...", ...) + - patterns: + - pattern: vfprintf($FMT, $ARGS, ...) + - pattern-not: vfprintf("...", $ARGS, ...) + - patterns: + - pattern: _ftprintf($FD, $FMT, ...) + - pattern-not: _ftprintf($FD, "...", ...) + - patterns: + - pattern: fwprintf($FD, $FMT, ...) + - pattern-not: fwprintf($FD, "...", ...) + - patterns: + - pattern: fvwprintf($FD, $FMT, ...) + - pattern-not: fvwprintf($FD, "...", ...) + severity: ERROR + - id: c_format_rule-printf-vprintf + languages: + - c + - cpp + - cpp + message: | + Format string vulnerabilities allow an attacker to read or in some cases, potentially write + data to + and from locations in the processes' memory. To prevent against format string attacks, do not + allow + users or un-validated input to provide the format specification. + Consider using a constant for the format specification, or only allow specific + characters to be provided to the format argument for the `printf` family of functions. + + For more information please see: https://linux.die.net/man/3/fprintf + + For more information on format string attacks please see OWASP's attack guide: + https://owasp.org/www-community/attacks/Format_string_attack + metadata: + category: security + cwe: CWE-134 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Potential format string vulnerability + pattern-either: + - patterns: + - pattern: printf(...) + - pattern-not: printf("...",...) + - patterns: + - pattern: vprintf($FMT, ...) + - pattern-not: vprintf("...", ...) + - patterns: + - pattern: vwprintf($FMT, ...) + - pattern-not: vwprintf("...", ...) + - patterns: + - pattern: vfwprintf($FILE, $FMT, ...) + - pattern-not: vfwprintf($FILE, "...", ...) + - patterns: + - pattern: _vtprintf($FILE, $FMT, ...) + - pattern-not: _vtprintf($FILE, "...", ...) + - patterns: + - pattern: wprintf($FMT, ...) + - pattern-not: wprintf("...", ...) + severity: ERROR + - id: c_format_rule-snprintf-vsnprintf + languages: + - c + - cpp + - cpp + message: | + Format string vulnerabilities allow an attacker to read or in some cases, potentially write + data to + and from locations in the processes' memory. To prevent against format string attacks, do not + allow + users or un-validated input to provide the format specification. + Consider using a constant for the format specification, or strip all format + specifiers from the input prior to calling the `snprintf` family of functions. + + Note that some variations of this function do not always null terminate the strings. + + For more information on using snprintf please see: https://linux.die.net/man/3/snprintf + + For more information on format string attacks please see OWASP's attack guide: + https://owasp.org/www-community/attacks/Format_string_attack + metadata: + category: security + cwe: CWE-134 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Potential format string vulnerability + pattern-either: + - patterns: + - pattern: snprintf($BUF,$SIZE,$FMT,...) + - pattern-not: snprintf($BUF,$SIZE,"...",...) + - patterns: + - pattern: vsnprintf($BUF,$SIZE,$FMT) + - pattern-not: vsnprintf($BUF,$SIZE,"...",...) + - patterns: + - pattern: _snprintf($BUF,$SIZE,$FMT,...) + - pattern-not: _snprintf($BUF,$SIZE,$FMT,"...",...) + - patterns: + - pattern: _sntprintf($VAR,$FMT,...) + - pattern-not: sntprintf($VAR,"...",...) + - patterns: + - pattern: _vsntprintf($VAR,$FMT,...) + - pattern-not: _vsntprintf($VAR,"...",...) + severity: ERROR + - id: c_format_rule-syslog + languages: + - c + - cpp + - cpp + message: | + Format string vulnerabilities allow an attacker to read or in some cases, potentially write + data to + and from locations in the processes' memory. To prevent against format string attacks, do not + allow + users or un-validated input to provide the format specification. + Consider using a constant for the format specification, or strip all format + specifiers from the input prior to calling the `syslog` function. + + For more information please see: https://capec.mitre.org/data/definitions/67.html + metadata: + category: security + cwe: CWE-134 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Potential format string vulnerability in syslog call + pattern-either: + - patterns: + - pattern: syslog($FUNC,...) + - pattern-not: syslog($FUNC,"...",...) + severity: ERROR + - id: c_free_rule-memalign + languages: + - c + - cpp + - cpp + message: | + The `memalign` function may not check that the alignment argument is correct. Calling + free (on non Linux-based systems) may fail and in certain circumstances this failure + may be exploitable. This function has been deprecated in favor of `posix_memalign`. + + For more information please see: https://linux.die.net/man/3/memalign + metadata: + category: security + cwe: CWE-676 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Use of deprecated function (memalign) + pattern-either: + - pattern: memalign(...) + - pattern-regex: (void)\s\*(\s|)(memalign)\; + severity: INFO + - id: c_integer_rule-atoi-atol + languages: + - c + - cpp + - cpp + message: | + The `atoi` family of functions can potentially overflow or underflow integer values. Consider + using `stroul` instead. + + For more information please see: + https://wiki.sei.cmu.edu/confluence/display/c/ERR34-C.+Detect+errors+when+converting+a+string+to+a+number + metadata: + category: security + cwe: CWE-190 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Possible integer overflow or underflow + pattern-either: + - pattern: atoi(...) + - pattern: atol(...) + - pattern: _wtoi(...) + - pattern: _wtoi64(...) + severity: INFO + - id: c_misc_rule-AddAccessAllowedAce + languages: + - c + - cpp + - cpp + message: | + Make sure that you set inheritance by hand if you wish it to inherit. + metadata: + category: security + cwe: CWE-732 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: High + shortDescription: This doesn't set the inheritance bits in the access control entry (ACE) header (CWE-732) + pattern: AddAccessAllowedAce(...) + severity: WARNING + - id: c_misc_rule-LoadLibrary + languages: + - c + - cpp + - cpp + message: | + The `LoadLibrary` function is used to load DLLs dynamically. Depending on the filepath + parameter, + the OS version, and the modes set for the process prior to calling LoadLibrary, DLL hijacking + may + be possible. Attackers can exploit this by placing DLL files with the same name in directories + that + are searched before the legitimate DLL is. + + To assist in preventing against this class of vulnerability consider: + - Specifying a fully qualified path when using LoadLibraryEx. + - Use the `LOAD_LIBRARY_SEARCH` flags with LoadLibraryEx or with SetDefaultDllDirectories. + - If you use SetDefaultDllDirectories, be sure to use the AddDllDirectory or SetDllDirectory + functions to modify the list of directories. + - Only use `SearchPath` if the `SetSearchPathMode` function is called with + `BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE`. (Note: this only moves the current directory to + the end of the SearchPath search list.) + + For more information see the security remarks section of the MSDN documentation: + https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya#security-remarks + + For general information securely loading dynamic link libraries, see the MSDN documentation: + https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-security + metadata: + category: security + cwe: CWE-427 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Uncontrolled search path element + pattern: LoadLibrary(...) + severity: WARNING + - id: c_misc_rule-LoadLibraryEx + languages: + - c + - cpp + - cpp + message: | + The `LoadLibraryEx` function is used to load DLLs dynamically. Depending on the filepath + parameter, + the OS version, and the modes set for the process prior to calling LoadLibrary, DLL hijacking + may + be possible. Attackers can exploit this by placing DLL files with the same name in directories + that + are searched before the legitimate DLL is. + + To assist in preventing against this class of vulnerability consider: + - Specifying a fully qualified path when using LoadLibraryEx. + - Use the `LOAD_LIBRARY_SEARCH` flags with LoadLibraryEx or with SetDefaultDllDirectories. + - If you use SetDefaultDllDirectories, be sure to use the AddDllDirectory or SetDllDirectory + functions to modify the list of directories. + - Only use `SearchPath` if the `SetSearchPathMode` function is called with + `BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE`. (Note: this only moves the current directory to + the end of the SearchPath search list.) + + For more information see the security remarks section of the MSDN documentation: + https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya#security-remarks + + For general information securely loading dynamic link libraries, see the MSDN documentation: + https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-security + metadata: + category: security + cwe: CWE-427 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Uncontrolled search path element + pattern: LoadLibraryEx(...) + severity: WARNING + - id: c_misc_rule-SetSecurityDescriptorDacl + languages: + - c + - cpp + - cpp + message: | + When `SetSecurityDescriptorDacl` is called with a null `pDacl` parameter and the + `bDaclPresent` flag is `TRUE`, all access to the object is allowed. An attacker + could set the object to Deny all, which would include even the Administrator user(s). + + Either call `SetSecurityDescriptorDacl` with bDaclPresent as `FALSE`, or supply a valid + non-null `pDacl` parameter value. + + For more information please see: + https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-setsecuritydescriptordacl#remarks + metadata: + category: security + cwe: CWE-732 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Null ACL when calling SetSecurityDescriptorDacl may allow all access to objects + pattern: SetSecurityDescriptorDacl(...) + severity: ERROR + - id: c_misc_rule-cuserid + languages: + - c + - cpp + - cpp + message: | + `cuserid()` is poorly defined (e.g., some systems use the effective + UID, like Linux, while others like System V use the real UID). Therefore, you can't trust + what it does. The cuserid function was included in the 1988 version of POSIX, but removed + from the 1990 version. Also, if passed a non-null parameter, there's a risk of a buffer + overflow if the passed-in buffer is not at least `L_cuserid` characters long. + + Use `getpwuid(geteuid())` and extract the desired information instead. + + For more information please see: https://linux.die.net/man/3/getpwuid + metadata: + category: security + cwe: CWE-120 + owasp: + - A9:2017-Using Components with Known Vulnerabilities + - A06:2021-Vulnerable and Outdated Components + security-severity: Low + shortDescription: Usage of deprecated function (cuserid) + pattern: cuserid(...) + severity: ERROR + - id: c_misc_rule-fopen-open + languages: + - c + - cpp + - cpp + message: | + Usage of the `open` family of functions may hint at a potential Time Of Check Time Of Use + (TOCTOU) + vulnerability. An attacker may be able to modify the file being specified by the `open` + function prior to the `open` function being called. + + Prior to calling `open`, use `lstat` to open the file and confirm the attributes + are correct. Then use `open` to get a file descriptor to this file. Call `fstat` on the + `open` file descriptor to confirm that `st_dev` and `st_ino` are equal between the two. + If they are, it is safe to read and operate on the file's contents. + + For more information please see: + https://wiki.sei.cmu.edu/confluence/display/c/FIO45-C.+Avoid+TOCTOU+race+conditions+while+accessing+files + metadata: + category: security + cwe: CWE-362 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Potential time of check time of use vulnerability (open/fopen) + pattern-either: + - pattern: fopen(...) + - pattern: open(...) + severity: INFO + - id: c_misc_rule-getlogin + languages: + - c + - cpp + - cpp + message: | + The `getlogin` function suffers from many bugs or unknown behaviors depending on the + system. Often, it gives only the first 8 characters of the login name. The user + currently logged in on the controlling TTY of our program does not necessarily mean + it is the user who started the process. + + Use getpwuid(geteuid()) and extract the desired information instead. + + For more information please see: https://linux.die.net/man/3/getpwuid + metadata: + category: security + cwe: CWE-807 + owasp: + - A9:2017-Using Components with Known Vulnerabilities + - A06:2021-Vulnerable and Outdated Components + security-severity: Low + shortDescription: Usage of deprecated function (getlogin) + pattern: getlogin(...) + severity: ERROR + - id: c_misc_rule-getpass + languages: + - c + - cpp + - cpp + message: | + This function is obsolete and not portable. It was in SUSv2 but removed by POSIX.2. What + it does exactly varies considerably between systems, particularly in where its prompt is + displayed and where it gets its data. Some systems will write to stderr instead of stdout. + Some will read from stdin if it can not be read from /dev/tty. In some systems the + buffer is static and limited to 127 characters, meaning the full password may not be returned + properly. + + If you want to read input without terminal echoing enabled, see the description of the ECHO + flag + in the termios manual pager. If you ever read passwords from a terminal, be sure to zero the + password as soon as possible, to avoid leaving the cleartext password visible in the + process' address space. + metadata: + category: security + cwe: CWE-477 + owasp: + - A9:2017-Using Components with Known Vulnerabilities + - A06:2021-Vulnerable and Outdated Components + security-severity: Low + shortDescription: Use of obsolete function + pattern: getpass(...) + severity: ERROR + - id: c_obsolete_rule-gsignal-ssignal + languages: + - c + - cpp + - cpp + message: | + The `gsignal` and `ssignal` functions are obsolete and no longer recommended. Consider + using the `raise` or `sigaction` functions instead for process signaling. + + For more information please see: https://linux.die.net/man/3/sigaction + metadata: + category: security + cwe: CWE-676 + owasp: + - A9:2017-Using Components with Known Vulnerabilities + - A06:2021-Vulnerable and Outdated Components + security-severity: Info + shortDescription: Deprecated function calls (ssignal/gsignal) + pattern-either: + - pattern: gsignal(...) + - pattern: ssignal(...) + severity: INFO + - id: c_obsolete_rule-ulimit + languages: + - c + - cpp + - cpp + message: | + The ulimit function is obsolete and no longer recommended. Use `getrlimit(2)`, + `setrlimit`, or `sysconf` instead. + + For more information please see: https://linux.die.net/man/3/setrlimit + metadata: + category: security + cwe: CWE-676 + owasp: + - A9:2017-Using Components with Known Vulnerabilities + - A06:2021-Vulnerable and Outdated Components + security-severity: Info + shortDescription: Usage of deprecated function (ulimit) + pattern: ulimit(...) + severity: INFO + - id: c_obsolete_rule-usleep + languages: + - c + - cpp + - cpp + message: | + The `usleep` function has been deprecated, use `nanosleep` or `setitimer` instead. + + For more information please see: https://linux.die.net/man/3/setitimer + metadata: + category: security + cwe: CWE-676 + owasp: + - A9:2017-Using Components with Known Vulnerabilities + - A06:2021-Vulnerable and Outdated Components + security-severity: Info + shortDescription: Usage of deprecated function (usleep) + pattern: usleep(...) + severity: INFO + - id: c_race_rule-access + languages: + - c + - cpp + - cpp + message: | + Usage of the `access` function call hints at a potential Time Of Check Time Of Use (TOCTOU) + vulnerability. Using the `access` function to check if a file exists and is readable before + opening it, an attacker can create a race condition between the `access` call and + opening the file. The attacker could replace the file with a different one or modify its + content between the time the `access` function is called and the file is opened, thus + bypassing the permission check. + + Call `setuid` to drop privileges on the process prior to opening any files. Instead of using + `access`, use `lstat` prior to opening the file and confirm the attributes are correct. Then + use `open` to get a file descriptor to this file. Call `fstat` on the `open` file descriptor + to confirm that `st_dev` and `st_ino` are equal between the two. If they are, it is safe to + read and operate on the file's contents. + + For more information please see: + https://wiki.sei.cmu.edu/confluence/display/c/FIO45-C.+Avoid+TOCTOU+race+conditions+while+accessing+files + metadata: + category: security + cwe: CWE-362 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Potential time of check time of use vulnerability (access) + pattern: access(...) + severity: ERROR + - id: c_race_rule-chmod + languages: + - c + - cpp + - cpp + message: | + Usage of the `chmod` function call hints at a potential Time Of Check Time Of Use (TOCTOU) + vulnerability. An attacker may be able to modify the file being specified by the `chmod` + function prior to the `chmod` function being called. Since `chmod` will resolve symbolic links, + an attacker may be able to exploit this fact to have files outside of their control modified. + + It is recommended that the `fchmod` function be used instead since this function takes + a file descriptor instead of a file. Ensure the opened file descriptor is pointing to + the correct file or directory prior to executing `fchmod` or any other file based operations. + + For more information please see: + https://wiki.sei.cmu.edu/confluence/display/c/FIO01-C.+Be+careful+using+functions+that+use+file+names+for+identification + metadata: + category: security + cwe: CWE-362 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Potential time of check time of use vulnerability (chmod) + pattern: chmod(...) + severity: ERROR + - id: c_race_rule-chown + languages: + - c + - cpp + - cpp + message: | + Usage of the `chown` function call hints at a potential Time Of Check Time Of Use (TOCTOU) + vulnerability. An attacker may be able to modify the file being specified by the `chmod` + function prior to the `chown` function being called. Since `chown` will resolve symbolic links, + an attacker may be able to exploit this fact to have files outside of their control modified. + + It is recommended that the `fchown` or the `lchown` functions be used instead. The `fchown` + function takes a file descriptor instead of a file. The `lchown` function does not follow + symbolic links. Ensure the opened file descriptor is pointing to the correct file or + directory prior to executing `fchown` or any other file based operations. + + For more information please see: + https://wiki.sei.cmu.edu/confluence/display/c/FIO01-C.+Be+careful+using+functions+that+use+file+names+for+identification + metadata: + category: security + cwe: CWE-362 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Potential time of check time of use vulnerability (chown) + pattern: chown(...) + severity: ERROR + - id: c_race_rule-readlink + languages: + - c + - cpp + - cpp + message: | + Usage of the `readlink` function call hints at a potential Time Of Check Time Of Use (TOCTOU) + vulnerability. An attacker may be able to modify the file being specified by the `readlink` + function prior to the `readlink` function being called. Additionally, care must be taken + that the buffer provided is large enough to hold the contents of the file. + + Instead of using `readlink`, use `lstat` prior to opening the file and confirm the attributes + are correct. Then use `open` to get a file descriptor to this file. Call `fstat` on the + `open` file descriptor to confirm that `st_dev` and `st_ino` are equal between the two. + If they are, it is safe to read and operate on the file's contents. + + For more information please see: + https://wiki.sei.cmu.edu/confluence/display/c/FIO45-C.+Avoid+TOCTOU+race+conditions+while+accessing+files + metadata: + category: security + cwe: CWE-367 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Time-of-check time-of-use (TOCTOU) race condition + pattern: readlink(...) + severity: ERROR + - id: c_race_rule-vfork + languages: + - c + - cpp + - cpp + message: | + The `vfork` function is suffers from portability issues and is not recommended. In + some Linux systems `vfork` is vulnerable to a race condition while the child process + is running as the user's UID but hasn't executed `execve`. The user may be able to send + signals to this process, which in `vfork` would not be sent to the parent process. As + a result a user may be able to cause a denial of service against the privileged process. + + Use `fork` instead and be aware of other potential Time Of Check Time Of Use (TOCTOU) + vulnerabilities. + + For more information please see: + https://wiki.sei.cmu.edu/confluence/display/c/POS38-C.+Beware+of+race+conditions+when+using+fork+and+file+descriptors + metadata: + category: security + cwe: CWE-362 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Potential time of check time of use vulnerability (vfork) + pattern: vfork(...) + severity: INFO + - id: c_random_rule-drand48-erand48 + languages: + - c + - cpp + - cpp + message: | + The detected function is not sufficient at generating security-related random numbers, + such as those used in key and nonce creation. Consider using the libsodium library's + `randombytes_random` function instead. More information on libsodium's random number + generators can be found here: https://libsodium.gitbook.io/doc/generating_random_data. + + If FIPS validation is required, consider using OpenSSLs `RAND_bytes` family of functions after + enabling the `FIPS_mode_set`. + + For more information on OpenSSL random numbers please see: + https://wiki.openssl.org/index.php/Random_Numbers + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Usage of insufficient random number generators + pattern-either: + - pattern: drand48(...) + - pattern: erand48(...) + - pattern: jrand48(...) + - pattern: lcong48(...) + - pattern: lrand48(...) + - pattern: mrand48(...) + - pattern: nrand48(...) + - pattern: random(...) + - pattern: seed48(...) + - pattern: setstate(...) + - pattern: srand(...) + - pattern: strfry(...) + - pattern: srandom(...) + - pattern: g_rand_boolean(...) + - pattern: g_rand_int(...) + - pattern: g_rand_int_range(...) + - pattern: g_rand_double(...) + - pattern: g_rand_double_range(...) + - pattern: g_random_boolean(...) + - pattern: g_random_int(...) + - pattern: g_random_int_range(...) + - pattern: g_random_double(...) + - pattern: g_random_double_range(...) + - pattern-regex: (long|short|double|int|float|void)\s(\*|)(\s|)(seed48|lcong48)(\(.*\))\; + severity: WARNING + - id: c_shell_rule-CreateProcess + languages: + - c + - cpp + - cpp + message: | + Due to how `CreateProcess` parses spaces, an attacker may be able to exploit this function + by creating a binary with the same name that is loaded first, depending on the search path + order. + + Ensure that quotation marks around the executable path are used, such as: + ``` + CreateProcessA(NULL, "\"C:\\Program Files\\MyApp.exe\"", ...) + ``` + For more information, please see MSDNs documentation at: + https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa#security-remarks + metadata: + category: security + cwe: CWE-78 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Possible executable path hijacking (CreateProcess) + pattern: CreateProcess(...) + severity: WARNING + - id: c_shell_rule-CreateProcessAsUser-CreateProcessWithLogon + languages: + - c + - cpp + - cpp + message: | + Due to how `CreateProcess` parses spaces, an attacker may be able to exploit this function + by creating a binary with the same name that is loaded first, depending on the search path + order. + + Ensure that quotation marks around the executable path are used, such as: + ``` + CreateProcessAsUser(hToken, NULL, "\"C:\\Program Files\\MyApp.exe\"", ...) + ``` + For more information, please see MSDNs documentation at: + https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasusera#security-remarks + metadata: + category: security + cwe: CWE-78 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Possible executable path hijacking (CreateProcessAsUser/CreateProcessWithLogon) + pattern-either: + - pattern: CreateProcessAsUser(...) + - pattern: CreateProcessWithLogon(...) + severity: WARNING + - id: c_shell_rule-execl-execlp + languages: + - c + - cpp + - cpp + message: | + It is generally not recommended to call out to the operating system to execute commands. + When the application is executing file system based commands, user input should never be used + in + constructing commands or command arguments. If possible, determine if a library can be used + instead to provide the same functionality. Otherwise, consider hard coding both the command + and arguments to be used, or at the very least restricting which arguments can be passed + to the command execution function. + + Please see the compliant solutions in the following page: + https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152177 + metadata: + category: security + cwe: CWE-78 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Potential for OS command injection + pattern-either: + - pattern: execl(...) + - pattern: execlp(...) + - pattern: execle(...) + - pattern: execv(...) + - pattern: execvp(...) + - pattern: popen(...) + - pattern: WinExec(...) + - pattern: ShellExecute(...) + severity: ERROR + - id: c_shell_rule-system + languages: + - c + - cpp + - cpp + message: | + It is generally not recommended to call out to the operating system to execute commands. + When the application is executing file system based commands, user input should never be used + in + constructing commands or command arguments. If possible, determine if a library can be used + instead to provide the same functionality. Otherwise, consider hard coding both the command + and arguments to be used, or at the very least restricting which arguments can be passed + to the command execution function. + + For more information please see: + https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152177 + metadata: + category: security + cwe: CWE-78 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Potential for OS command injection + pattern: system(...) + severity: ERROR + - id: c_tmpfile_rule-GetTempFileName + languages: + - c + - cpp + - cpp + message: | + The `GetTempFileName` function works by generating a randomly named file, creating the file + (if it does not exist) and then closing it. An application wishing to use this temporary file + will need to reopen this file to begin working with it. This leads to a potential + Time Of Check Time Of Use (TOCTOU) vulnerability, as an attacker could replace or modify + the contents of the file prior to it being used by the application. + + Consider generating a random filename and opening the file directly in a single `CreateFile` + or `OpenFile` call. + metadata: + category: security + cwe: CWE-377 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Potential time of check time of use vulnerability (GetTempFileName) + pattern: GetTempFileName(...) + severity: WARNING + - id: c_tmpfile_rule-mkstemp + languages: + - c + - cpp + - cpp + message: | + Some older Unix-like systems, `mkstemp` would create temp files with 0666 permissions, + meaning the file created would be read/write access for all users. + + Ensure the process has called the `umask` function with restricted permissions prior + to calling `mkstemp` and validate the permissions prior to using the file descriptor. + + For more information on temporary files please see: + https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152425 + metadata: + category: security + cwe: CWE-377 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Potential file permissions issue (mkstemp) + pattern: mkstemp(...) + severity: INFO + - id: c_tmpfile_rule-mktemp + languages: + - c + - cpp + - cpp + message: | + The `mktemp` function should no longer be used due to multiple flaws. Some implementations + created random files by using known information like the process ID and a single letter. This + allows for possible race conditions where an attacker could guess or manipulate these files + prior to them being used. + + Consider using the `mkstemp` function instead, but be aware it also contains possible + risks. Ensure the process has called the `umask` function with restricted permissions prior + to calling `mkstemp` and validate the permissions prior to using the file descriptor. + + For more information on temporary files please see: + https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152425 + metadata: + category: security + cwe: CWE-377 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Use of deprecated function (mktemp) + pattern: mktemp(...) + severity: ERROR + - id: c_tmpfile_rule-tmpfile + languages: + - c + - cpp + - cpp + message: | + There exists a possible race condition in between the time that `tmpfile` returns + a pathname, and the time that the program opens it, another program might create + that pathname using `open`, or create it as a symbolic link. + + Consider using the `mkstemp` function instead, but be aware it also contains possible + risks. Ensure the process has called the `umask` function with restricted permissions prior + to calling `mkstemp` and validate the permissions prior to using the file descriptor. + + For more information on temporary files please see: + https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152425 + metadata: + category: security + cwe: CWE-377 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Potential time of check time of use vulnerability (tmpfile) + pattern: tmpfile(...) + severity: INFO + - id: c_tmpfile_rule-tmpnam-tempnam + languages: + - c + - cpp + - cpp + message: | + There exists a possible race condition in between the time that `tempnam` or `tmpnam` + returns a pathname, and the time that the program opens it, another program might create + that pathname using `open`, or create it as a symbolic link. + + Consider using the `mkstemp` function instead, but be aware it also contains possible + risks. Ensure the process has called the `umask` function with restricted permissions prior + to calling `mkstemp` and validate the permissions prior to using the file descriptor. + + For more information on temporary files please see: + https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152425 + metadata: + category: security + cwe: CWE-377 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Potential time of check time of use vulnerability (tmpnam/tempnam) + pattern-either: + - pattern: tmpnam(...) + - pattern: tempnam(...) + severity: WARNING + - id: csharp_cookies_rule-CookieWithoutHttpOnlyFlag + languages: + - csharp + message: | + The `HttpOnly` attribute when set to `true` protects the cookie value from being accessed by + client side JavaScript such + as reading the `document.cookie` values. By enabling this protection, a website that is + vulnerable to + Cross-Site Scripting (XSS) will be able to block malicious scripts from accessing the cookie + value from JavaScript. + + Example of protecting an HttpCookie: + ``` + // Create an HttpOnly cookie. + HttpCookie someCookie = new HttpCookie("SomeCookieName", "SomeValue"); + someCookie.HttpOnly = true; + ``` + + For more information see: + https://learn.microsoft.com/en-us/dotnet/api/system.web.httpcookie.httponly + + Session cookies should be configured with the following security directives: + + - [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) + - [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) + - [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) + metadata: + category: security + cwe: CWE-1004 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Low + shortDescription: Sensitive cookie without 'HttpOnly' flag + mode: taint + pattern-sanitizers: + - pattern: $COOKIE.HttpOnly = true; + pattern-sinks: + - pattern: $COOKIE + pattern-sources: + - pattern: | + var $COOKIE = new HttpCookie(...); + severity: WARNING + - id: csharp_cookies_rule-CookieWithoutSSLFlag + languages: + - csharp + message: | + The `Secure` attribute when set to `true` protects the cookie value from being being + transmitted over clear text + communication paths such as HTTP. By enabling this protection, the cookie will only be sent + over HTTPS. + + Example of protecting an HttpCookie: + ``` + // Create an HttpOnly cookie. + HttpCookie someCookie = new HttpCookie("SomeCookieName", "SomeValue"); + someCookie.Secure = true; + ``` + + For more information see: + https://learn.microsoft.com/en-us/dotnet/api/system.web.httpcookie.secure + + Session cookies should be configured with the following security directives: + + - [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) + - [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) + - [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) + metadata: + category: security + cwe: CWE-614 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Low + shortDescription: Sensitive cookie in HTTPS session without 'Secure' attribute + mode: taint + pattern-sanitizers: + - pattern: $COOKIE.Secure = true; + pattern-sinks: + - pattern: $COOKIE + pattern-sources: + - pattern: | + var $COOKIE = new HttpCookie(...); + severity: WARNING + - id: csharp_crypto_rule-CertificateValidationDisabled + languages: + - csharp + message: | + The `ServicePointManager.ServerCertificateValidationCallback` event has been set + to always return `true`, which effectively disables the validation of server + certificates. + + This allows for an adversary who is in between the application and the target host to intercept + potentially sensitive information or transmit malicious data. + + Remove the callback function that is returning true to allow normal certificate validation to + proceed. + When no callback is provided, the client will validate that the certificate name matches the + hostname + that was used when creating the request. + + For more information on the `ServerCertificateValidationCallback` property see: + https://learn.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.servercertificatevalidationcallback + metadata: + category: security + cwe: CWE-295 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: Medium + shortDescription: Certificate validation disabled + patterns: + - pattern-inside: | + using System.Net; + ... + - pattern: ServicePointManager.ServerCertificateValidationCallback += $CALLBACK; + - metavariable-pattern: + metavariable: $CALLBACK + patterns: + - pattern-either: + - pattern: $RETURNTYPE $FUNC(...) { return true; } + - pattern: (...) => true; + severity: WARNING + - id: csharp_crypto_rule-WeakCipherAlgorithm + languages: + - csharp + message: | + DES, TripleDES and RC2 are all considered broken or insecure cryptographic algorithms. + If using .NET Framework greater than version 6.0 consider using `ChaCha20Poly1305` + instead as it is easier and faster than the alternatives such as `AES-256-GCM`. + + For older applications, `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Example using `ChaCha20Poly1305`: + ``` + // Generate a random key + byte[] key = new byte[32]; + RandomNumberGenerator.Fill(key); + + // Note nonce values _must_ be regenerated every time they are used. + byte[] nonce = new byte[12]; + RandomNumberGenerator.Fill(nonce); + + byte[] authTag = new byte[16]; + byte[] cipherText; + + using (ChaCha20Poly1305 encryptor = new ChaCha20Poly1305(key)) + { + byte[] plainText = System.Text.Encoding.UTF8.GetBytes("Secret text to encrypt"); + cipherText = new byte[plainText.Length]; + encryptor.Encrypt(nonce, plainText, cipherText, authTag); + } + + using (ChaCha20Poly1305 decryptor = new ChaCha20Poly1305(key)) + { + byte[] output = new byte[cipherText.Length]; + decryptor.Decrypt(nonce, cipherText, authTag, output); + Console.WriteLine("Output: {0}", System.Text.Encoding.UTF8.GetString(output)); + } + ``` + + Example using `AES-256-GCM`: + ``` + // Generate a random key + byte[] key = new byte[32]; + RandomNumberGenerator.Fill(key); + + // Note nonce values _must_ be regenerated every time they are used. + byte[] nonce = new byte[AesGcm.NonceByteSizes.MaxSize]; + RandomNumberGenerator.Fill(nonce); + + byte[] authTag = new byte[AesGcm.TagByteSizes.MaxSize]; + byte[] cipherText; + + using (AesGcm encryptor = new AesGcm(key)) + { + byte[] plainText = Encoding.UTF8.GetBytes("Secret text to encrypt"); + cipherText = new byte[plainText.Length]; + encryptor.Encrypt(nonce, plainText, cipherText, authTag); + } + + using (AesGcm decryptor = new AesGcm(key)) + { + byte[] output = new byte[cipherText.Length]; + decryptor.Decrypt(nonce, cipherText, authTag, output); + Console.WriteLine("Output: {0}", Encoding.UTF8.GetString(output)); + } + ``` + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-inside: | + using System.Security.Cryptography; + ... + - pattern-either: + - pattern-regex: .*DES\.Create\(\); + - pattern: new DESCryptoServiceProvider(); + - pattern-regex: .*TripleDES\.Create\(\); + - pattern: new TripleDESCryptoServiceProvider(); + - pattern-regex: .*RC2\.Create\(\); + - pattern: new RC2CryptoServiceProvider(); + severity: WARNING + - id: csharp_crypto_rule-WeakCipherMode + languages: + - csharp + message: | + Cryptographic algorithms provide many different modes of operation, only some of which provide + message integrity. Without message integrity it could be possible for an adversary to attempt + to tamper with the ciphertext which could lead to compromising the encryption key. Newer + algorithms + apply message integrity to validate ciphertext has not been tampered with. + + Instead of using an algorithm that requires configuring a `CipherMode`, an algorithm + that has built-in message integrity should be used. If using .NET Framework greater + than version 6.0 consider using `ChaCha20Poly1305` or `AES-256-GCM`. + + For older applications, `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are re-used. + + Example using `ChaCha20Poly1305`: + ``` + // Generate a random key + byte[] key = new byte[32]; + RandomNumberGenerator.Fill(key); + + ChaCha20Poly1305 encryptor = new ChaCha20Poly1305(key); + + // Note nonce values _must_ be regenerated every time they are used. + var nonce = new byte[12]; + RandomNumberGenerator.Fill(nonce); + + byte[] plainText = System.Text.Encoding.UTF8.GetBytes("Secret text to encrypt"); + byte[] cipherText = new byte[plainText.Length]; + var authTag = new byte[16]; + + encryptor.Encrypt(nonce, plainText, cipherText, authTag); + byte[] output = new byte[cipherText.Length]; + encryptor.Decrypt(nonce, cipherText, authTag, output); + Console.WriteLine("Output: {0}", System.Text.Encoding.UTF8.GetString(output)); + ``` + + Example using `AES-256-GCM`: + ``` + var plaintextBytes = Encoding.UTF8.GetBytes("Secret text to encrypt"); + var key = new byte[32]; + RandomNumberGenerator.Fill(key); + + using var aes = new AesGcm(key); + var nonce = new byte[AesGcm.NonceByteSizes.MaxSize]; + RandomNumberGenerator.Fill(nonce); + + var cipherText = new byte[plaintextBytes.Length]; + var tag = new byte[AesGcm.TagByteSizes.MaxSize]; + + aes.Encrypt(nonce, plaintextBytes, cipherText, tag); + + // Decrypt + using (var decrypt = new AesGcm(key)) + { + var decryptedBytes = new byte[cipherText.Length]; + + decrypt.Decrypt(nonce, cipherText, tag, decryptedBytes); + + Console.WriteLine("Decrypted: {0}", Encoding.UTF8.GetString(decryptedBytes)); + } + ``` + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-inside: | + using System.Security.Cryptography; + ... + - metavariable-regex: + metavariable: $CIPHER + regex: ^(ECB|CBC|OFB|CFB|CTS)$ + - pattern: CipherMode.$CIPHER + severity: WARNING + - id: csharp_crypto_rule-WeakHashingFunction + languages: + - csharp + message: | + Both MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. Currently there is no vetted Argon2id implementation for + C# so + it is recommended that PBKDF2 be used until one is available. + + Example using PBKDF2 to generate and compare passwords: + ``` + const int SaltSize = 24; + const int HashSize = 24; + // number of pbkdf2 iterations, Rfc2898DeriveBytes uses hmac-sha1 + // so set a high iteration count + const int Iterations = 1_300_000; + byte[] salt = new byte[SaltSize]; + RandomNumberGenerator.Fill(salt); + + Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes("some password", salt, Iterations); + byte[] hashBytes = pbkdf2.GetBytes(HashSize); + // Store salt and hashedBytes in a data store such as database for authentication + Console.WriteLine("Hash {0}", BitConverter.ToString(hashBytes).Replace("-", "")); + // Do a constant time comparison as to not leak data based on timing + if (CryptographicOperations.FixedTimeEquals(hashBytes, hashBytes)) { + Console.WriteLine("hashes are equal"); + } + ``` + For more information on PBKDF2 see: + https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.rfc2898derivebytes + + For more information on secure password storage see OWASP: + https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm (SHA1/MD5) + patterns: + - pattern-either: + - patterns: + - metavariable-regex: + metavariable: $HASH_PROVIDER + regex: ^(SHA1CryptoServiceProvider|MD5CryptoServiceProvider)$ + - pattern: new $HASH_PROVIDER + - patterns: + - metavariable-regex: + metavariable: $HASH_CLASS + regex: ^System.Security.Cryptography.(SHA1|MD5)$ + - pattern: $HASH_CLASS.$METHOD(); + severity: WARNING + - id: csharp_crypto_rule-WeakRNG + languages: + - csharp + message: | + Depending on the context, generating weak random numbers may expose cryptographic functions + which rely on these numbers to be exploitable. When generating numbers for sensitive values + such as tokens, nonces, and cryptographic keys, it is recommended that the + `RandomNumberGenerator` class be used. + + Example `RandomNumberGenerator` usage: + ``` + Int32 randInt = RandomNumberGenerator.GetInt32(32000); + byte[] randomBytes = new byte[64]; + RandomNumberGenerator.Fill(randomBytes); + Console.WriteLine("Random Int32: {0}", randInt); + Console.WriteLine("Random Bytes: {0}", BitConverter.ToString(randomBytes).Replace("-", "")); + ``` + + For more information see: + https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator + metadata: + category: security + cwe: CWE-338 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of cryptographically weak Pseudo-Random Number Generator (PRNG) + patterns: + - pattern: (Random $RNG).$METHOD(...); + - focus-metavariable: $RNG + severity: WARNING + - id: csharp_csrf_rule-Csrf + languages: + - csharp + message: | + The application failed to protect against Cross-Site Request Forgery (CSRF) + due to not including the `[ValidateAntiForgeryToken]` attribute on an + HTTP method handler that could change user state (usually in the form of POST or PUT + methods). + + The vulnerability can be exploited by an adversary creating a link or form on a third + party site and tricking an authenticated victim to access them. + + Add the `[ValidateAntiForgeryToken]` to all methods which take in user data and change + user state (such as updating a database with a new value). This is especially true for + functionality such as updating passwords or other security sensitive functions. + + Alternatively, applications can enable a global + [AutoValidateAntiforgeryTokenAttribute](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.autovalidateantiforgerytokenattribute) + filter. + + For more information on ValidateAntiForgeryToken and other CSRF protections in .NET + see the following URL: + https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery + + Additionally, consider setting all session cookies to have the `SameSite=Strict` attribute. + It should be noted that this may impact usability when sharing links across other mediums. + It is recommended that a two cookie based approach is taken, as outlined in the + [Top level + navigations](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-08#section-8.8.2) + section + of the SameSite RFC. + + For more information on CSRF see OWASP's guide: + https://owasp.org/www-community/attacks/csrf + metadata: + category: security + cwe: CWE-352 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Potential Cross-Site Request Forgery (CSRF) + patterns: + - pattern: | + [$HTTPMETHOD] + public $RET $FOO(...) { + ... + } + - pattern-not: | + [ValidateAntiForgeryToken] + public $RET $FOO(...) { + ... + } + - pattern-not-inside: | + [AutoValidateAntiforgeryToken] + class $CLASS{ + ... + } + - pattern-not-inside: | + [ValidateAntiForgeryToken] + class $CLASS{ + ... + } + - metavariable-regex: + metavariable: $HTTPMETHOD + regex: Http(Post|Delete|Patch|Put) + severity: WARNING + - id: csharp_deserialization_rule-InsecureDeserialization + languages: + - csharp + message: | + Deserialization attacks exploit the process of reading serialized data and turning it back into an + object. By constructing malicious objects and serializing them, an adversary may attempt to: + + - Inject code that is executed upon object construction, which occurs during the deserialization process. + - Exploit mass assignment by including fields that are not normally a part of the serialized data but are + read in during deserialization. + + Microsoft recommends no longer using the following serialization formats: + + - BinaryFormatter + - SoapFormatter + - NetDataContractSerializer + - LosFormatter + - ObjectStateFormatter + + Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows + the application to specify exactly which object types are allowed to be deserialized. Additionally, when + deserializing, never deserialize to base object types like `Object` and only cast to the exact object + type that is expected. + + To protect against mass assignment, only allow deserialization of the specific fields that are required. + If this is not easily done, consider creating an intermediary type that can be serialized with only the + necessary fields exposed. + + For more information see Microsoft's deserialization security guide: + https://learn.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide + + For more details on deserialization attacks in general, see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + + It should be noted that [tools exist](https://github.com/pwntester/ysoserial.net) to automatically create + exploit code for these vulnerabilities. + metadata: + category: security + cwe: CWE-502 + owasp: + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: High + shortDescription: Deserialization of potentially untrusted data + mode: taint + pattern-sinks: + - pattern: (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter $OBJ).Deserialize(...) + - pattern: (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter $OBJ).UnsafeDeserialize(...) + - pattern: (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter $OBJ).UnsafeDeserializeMethod(...) + - pattern: (System.Runtime.Serialization.Formatters.Soap.SoapFormatter $OBJ).Deserialize(...) + - pattern: (System.Runtime.Serialization.NetDataContractSerializer $OBJ).Deserialize(...) + - pattern: (System.Web.UI.LosFormatter $OBJ).Deserialize(...) + pattern-sources: + - pattern: Request.Cookies[...] + - pattern: Request.Cookies.Get(...) + - pattern: Request.Form[...] + - pattern: Request.Form.Get(...) + - pattern: Request.Headers[...] + - pattern: Request.Headers.Get(...) + - pattern: Request.QueryString[...] + - pattern: Request.QueryString.Get(...) + - pattern: Request.Body + - pattern: $CTX.Request.Cookies[...] + - pattern: $CTX.Request.Cookies.Get(...) + - pattern: $CTX.Request.Form[...] + - pattern: $CTX.Request.Form.Get(...) + - pattern: $CTX.Request.Headers[...] + - pattern: $CTX.Request.Headers.Get(...) + - pattern: $CTX.Request.QueryString[...] + - pattern: $CTX.Request.QueryString.Get(...) + - pattern: $CTX.Request.Body + - pattern: System.IO.File.ReadAllText(...) + - pattern: System.IO.File.ReadAllTextAsync(...) + - pattern: System.IO.File.ReadAllLines(...) + - pattern: System.IO.File.ReadAllLinesAsync(...) + - pattern: System.IO.File.ReadAllBytes(...) + - pattern: System.IO.File.ReadAllBytesAsync(...) + - pattern: System.IO.File.ReadLines(...) + - pattern: System.IO.File.ReadLinesAsync(...) + - pattern: System.Environment.GetEnvironmentVariable(...) + severity: WARNING + - id: csharp_endpoint_rule-UnvalidatedRedirect + languages: + - csharp + message: | + The application may allow open redirects if created using user supplied input. Open redirects + are + commonly + abused in phishing attacks where the original domain or URL looks like a legitimate link, but + then + redirects a user to a malicious site. An example would be + `https://example.com/redirect?url=https://%62%61%64%2e%63%6f%6d%2f%66%61%6b%65%6c%6f%67%69%6e` + which, + when decoded, turns into `bad.com/fakelogin`. + + Never redirect a client based on user input. It is recommended that the list of target links + to + redirect a user to are contained server side, and retrieved using a numerical value + as an index to return the link to be redirected to. For example, `/redirect?id=1` would cause + the + application to look up the `1` index and return a URL such as `https://example.com`. This URL + would + then be used to redirect the user, using the 301 response code and `Location` header. + + For more information on open redirects see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-601 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Info + shortDescription: URL redirection to untrusted site 'open redirect' + mode: taint + pattern-sanitizers: + - pattern: Url.Action(...) + - pattern: Url.HttpRouteUrl(...) + - pattern: Url.RouteUrl(...) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: return $METHOD(...) + - pattern: return new $METHOD(...) + - pattern: | + if (!Url.IsLocalUrl(...)) { + ... + return $METHOD(...) + } + - patterns: + - pattern-not-inside: | + if (Url.IsLocalUrl(...)) { + ... + } + - pattern-not-inside: | + if (!Url.IsLocalUrl(...)) { + return $X + } + ... + - pattern-either: + - pattern: $METHOD(...) + - pattern: new $METHOD(...) + - metavariable-pattern: + metavariable: $METHOD + pattern-either: + - pattern: Redirect + - pattern: RedirectPermanent + - pattern: RedirectToRoute + - pattern: RedirectToRoutePermanent + - pattern: RedirectResult + pattern-sources: + - patterns: + - pattern: $SRC + - pattern-inside: | + public $RET $FUNC(...,$SRC,...){...} + - patterns: + - pattern: $SRC + - pattern-inside: | + if (Uri.TryCreate(..., ..., $SRC)){ + ... + } + severity: WARNING + - id: csharp_injection_rule-CommandInjection + languages: + - csharp + message: | + OS command injection is a critical vulnerability that can lead to a full system + compromise as it may allow an adversary to pass in arbitrary commands or arguments + to be executed. + + User input should never be used in constructing commands or command arguments + to functions which execute OS commands. This includes filenames supplied by + user uploads or downloads. + + Ensure your application does not: + + - Use user-supplied information in the process name to execute. + - Use user-supplied information in an OS command execution function which does + not escape shell meta-characters. + - Use user-supplied information in arguments to OS commands. + + The application should have a hardcoded set of arguments that are to be passed + to OS commands. If filenames are being passed to these functions, it is + recommended that a hash of the filename be used instead, or some other unique + identifier. It is strongly recommended that a native library that implements + the same functionality be used instead of using OS system commands, due to the + risk of unknown attacks against third party commands. + + When specifying the OS command, ensure the application uses the full path + information, otherwise the OS may attempt to look up which process to execute + and could be vulnerable to untrusted search path vulnerabilities (CWE-426). + + Example of safely executing an OS command: + ``` + public void ExecuteCommand(string userFileData) { + // generate a random filename, do not using user input + string fileName = "C:\\Temp\\" + Guid.NewGuid(); + File.WriteAllText(fileName, userFileData); + + using (Process process = new Process()) + { + // hardcode the full process path + ProcessStartInfo processInfo = new ProcessStartInfo("C:\\App\\FileReader.exe"); + // only pass in trust arguments, and never direct user input. + processInfo.Arguments = fileName; + processInfo.UseShellExecute = false; + process.StartInfo = processInfo; + process.Start(); + } + } + ``` + + For more information on OS command injection, see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-78 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + ... + (System.Diagnostics.Process $PROC).Start(...); + - pattern-either: + - patterns: + - pattern: (System.Diagnostics.Process $PROC).StartInfo.FileName = <...$ARG...>; + - pattern-not: (System.Diagnostics.Process $PROC).StartInfo.FileName = "..."; + - patterns: + - pattern: (System.Diagnostics.Process $PROC).StartInfo.Arguments = <...$ARG...>; + - pattern-not: (System.Diagnostics.Process $PROC).StartInfo.Arguments = "..."; + - patterns: + - pattern: System.Diagnostics.Process.Start($ARG); + - pattern-not: System.Diagnostics.Process.Start("..."); + - patterns: + - pattern-not: $PSINFO.Arguments = "..."; + - pattern-not: $PSINFO.FileName = "..."; + - pattern-not: new System.Diagnostics.ProcessStartInfo("..."); + - pattern-not: new System.Diagnostics.ProcessStartInfo(); + - pattern-either: + - pattern: new System.Diagnostics.ProcessStartInfo(...); + - pattern: $PSINFO.Arguments = <...$ARG...>; + - pattern: $PSINFO.FileName = <...$ARG...>; + - patterns: + - pattern-inside: | + new System.Diagnostics.ProcessStartInfo{ + ... + } + - pattern-not: Arguments = "..." + - pattern-not: FileName = "..." + - pattern-either: + - pattern: Arguments = ... + - pattern: FileName = ... + severity: ERROR + - id: csharp_injection_rule-LdapInjection + languages: + - csharp + message: | + LDAP injection attacks exploit LDAP queries to influence how data is returned by + the LDAP, or in this case an Active Directory server. + + It is recommended that newer applications use the `System.DirectoryServices.AccountManagement` + API instead of `DirectorySearcher` API as it hides the complexity of querying LDAP directly. + However, + the `AccountManagement` API is still susceptible to LDAP injection if a user inputs LDAP + queries, + including LDAP filter characters such as `*`. + + It is recommended that all input passed to LDAP querying systems encode the following values: + + - Any occurrence of the null character must be escaped as “\00”. + - Any occurrence of the open parenthesis character must be escaped as “\28”. + - Any occurrence of the close parenthesis character must be escaped as “\29”. + - Any occurrence of the asterisk character must be escaped as “\2a”. + - Any occurrence of the backslash character must be escaped as “\5c”. + + Example code that safely encodes input for use in an LDAP query using the `AccountManagement` + API: + ``` + using System.DirectoryServices.AccountManagement; + + string EncodeLDAPString(string input) { + // Note the \ character is replaced first + char[] chars = new char[] { '\\', '\0', '(', ')', '*' }; + string[] encoded = new string[] { "\\5c", "\\00", "\\28", "\\29", "\\2a" }; + + for (int i = 0; i < chars.Length; i++) + { + input = input.Replace(chars[i].ToString(), encoded[i]); + } + + return input; + } + + // unsafe, do not use without encoding first + string userInput = "Administrator"; + PrincipalContext AD = new PrincipalContext(ContextType.Domain, "ad.example.dev"); + + UserPrincipal u = new UserPrincipal(AD); + string encodedUserName = EncodeLDAPString(userInput); + + // The AD search term, encoded prior to calling search + u.SamAccountName = encodedUserName; + + // Search for user + PrincipalSearcher search = new PrincipalSearcher(u); + + // Use FindOne to only return a single result + UserPrincipal result = (UserPrincipal)search.FindOne(); + search.Dispose(); + + // show some details + if (result != null) { + Console.WriteLine("User: {0}", result.DisplayName); + } else { + Console.WriteLine("user not found"); + } + ``` + + The same encoding method shown in `EncodeLDAPString` can also be used when using the + older `DirectorySearcher` API. + + For more information see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-90 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of special elements used in an LDAP query ('LDAP Injection') + mode: taint + pattern-sinks: + - pattern: System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(...) + - pattern: new System.DirectoryServices.DirectoryEntry(...) + - pattern: new System.DirectoryServices.DirectorySearcher(...) + - pattern: new System.DirectoryServices.Protocols.SearchRequest(...) + - patterns: + - focus-metavariable: $TAINTED + - pattern-either: + - pattern: (System.DirectoryServices.DirectoryEntry $SOURCE).Path = $TAINTED + - pattern: (System.DirectoryServices.DirectorySearcher $SEARCHER).Filter = $TAINTED + - pattern: (System.DirectoryServices.Protocols.SearchRequest $SEARCHREQ).Filter = $TAINTED + - pattern: (System.DirectoryServices.Protocols.SearchRequest $SEARCHREQ).DistinguishedName = $TAINTED + - pattern: (System.DirectoryServices.AccountManagement.UserPrincipal $SEARCHREQ).$PROP = $TAINTED + pattern-sources: + - patterns: + - pattern-inside: | + $RET $METHOD(...,$VAR,...){...} + - pattern: $VAR + severity: WARNING + - id: csharp_injection_rule-SQLInjection + languages: + - csharp + message: | + SQL Injection is a critical vulnerability that can lead to data or system compromise. By + dynamically generating SQL query strings, user input may be able to influence the logic of + the SQL statement. This could lead to an adversary accessing information they should + not have access to, or in some circumstances, being able to execute OS functionality or code. + + Replace all dynamically generated SQL queries with parameterized queries. In situations where + dynamic queries must be created, never use direct user input, but instead use a map or + dictionary of valid values and resolve them using a user supplied key. + + For example, some database drivers do not allow parameterized queries for `>` or `<` comparison + operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the + user + supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` + values to be used in the construction of the dynamic query. The same goes for other queries + where + column or table names are required but cannot be parameterized. + + Example using parameterized queries with `SqlCommand`: + ``` + string userInput = "someUserInput"; + string connectionString = ...; + using (SqlConnection connection = new SqlConnection(connectionString)) + { + connection.Open(); + String sql = "SELECT name, value FROM table where name=@Name"; + + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar); + command.Parameters["@Name"].Value = userInput; + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + Console.WriteLine("{0} {1}", reader.GetString(0), reader.GetString(1)); + } + } + } + } + ``` + + For more information on SQL Injection see OWASP: + https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-89 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') + patterns: + - pattern-either: + - patterns: + - metavariable-pattern: + metavariable: $FUNC + pattern-either: + - pattern: SqlQuery + - pattern: ExecuteSqlCommand + - pattern: ExecuteSqlCommandAsync + - pattern: ExecuteSqlRaw + - pattern: ExecuteSqlRawAsync + - pattern: FromSqlRaw + - pattern: FromSql + - pattern: GetSqlStringCommand + - pattern: ExecuteDataSet + - pattern: ExecuteReader + - pattern: ExecuteNonQuery + - pattern: ExecuteScalar + - pattern: CreateSQLQuery + - pattern-either: + - pattern: $DB.$FUNC($ARG, ...) + - pattern: $DB.$FUNC<$CC>($ARG, ...) + - pattern-not: $DB.$FUNC("...", ...) + - pattern-not: $DB.$FUNC<$CC>("...", ...) + - patterns: + - pattern-inside: | + using System.Data.Linq; + ... + - pattern-either: + - patterns: + - pattern: (DataContext $CTX).ExecuteQuery<$TRESULT>($ARG, ...) + - pattern-not: (DataContext $CTX).ExecuteQuery<$TRESULT>("...", ...) + - patterns: + - pattern: (DataContext $CTX).ExecuteQuery($TYPE, $ARG, ...) + - pattern-not: (DataContext $CTX).ExecuteQuery($TYPE, "...", ...) + - patterns: + - pattern: (DataContext $CTX).ExecuteCommand($ARG, ...) + - pattern-not: (DataContext $CTX).ExecuteCommand("...", ...) + - patterns: + - metavariable-pattern: + metavariable: $IMPL + pattern-either: + - pattern: SqlCommand + - pattern: OracleCommand + - pattern: NpgsqlCommand + - pattern: MySqlCommand + - pattern: EntityCommand + - pattern: OdbcCommand + - pattern: OleDbCommand + - pattern: SqliteCommand + - pattern-either: + - patterns: + - pattern: new $IMPL($ARG, ...); + - pattern-not: new $IMPL("...", ...); + - patterns: + - pattern: ($IMPL $CMD).CommandText = <...$ARG...>; + - pattern-not: ($IMPL $CMD).CommandText = "..."; + - patterns: + - metavariable-pattern: + metavariable: $FUNC + pattern-either: + - pattern: ExecuteDataRow + - pattern: ExecuteDataRowAsync + - pattern: ExecuteDataset + - pattern: ExecuteDatasetAsync + - pattern: ExecuteNonQuery + - pattern: ExecuteNonQueryAsync + - pattern: ExecuteReader + - pattern: ExecuteReaderAsync + - pattern: ExecuteScalar + - pattern: ExecuteScalarAsync + - pattern: UpdateDataSet + - pattern: UpdateDataSetAsync + - pattern-inside: | + using MySql.Data.MySqlClient; + ... + - pattern: MySqlHelper.$FUNC($CONN, $ARG, ...) + - pattern-not: MySqlHelper.$FUNC($CONN, "...", ...) + - patterns: + - pattern-inside: | + using Cassandra; + ... + - pattern-not: $SESS.Execute("...", ...) + - pattern-either: + - pattern: (Session $SESS).Execute($ARG, ...) + - patterns: + - pattern-inside: | + var $SESS = $CLUSTER.Connect(...); + ... + - pattern: $SESS.Execute($ARG, ...) + severity: WARNING + - id: csharp_injection_rule-XPathInjection + languages: + - csharp + message: | + XPath injection is a vulnerability that can allow an adversary to inject or modify how an XML + query + is structured. Depending on the logic of the original query, this could lead to adversaries + extracting unauthorized information or in rare cases bypassing authorization checks. + + It is recommended that LINQ to XML is used instead of XPath for querying XML documents. Care + must be taken to **not** call these LINQ functions with user input as they can still lead to + XPath + injection: + + - `XPathEvaluate` + - `XPathSelectElement` + - `XPathSelectElements` + + Example using LINQ to XML to safely extract the first user from a list of users: + ``` + // XDocument is safe from XXE attacks as the resolver is disabled by default + XDocument doc = XDocument.Load("users.xml"); + XNamespace ns = "urn:users-schema"; + + string userInput = "LastName"; + + // Get all the users. + var user = doc.Descendants(ns + "user") + .Select(u => new { + FirstName = (string)u.Element(ns + "first-name"), + LastName = (string)u.Element(ns + "last-name") + }).Where(u => u.LastName == userInput).FirstOrDefault(); + + Console.WriteLine(user.FirstName + " " + user.LastName); + ``` + + For more information on LINQ to XML security see: + https://learn.microsoft.com/en-us/dotnet/standard/linq/linq-xml-security + + For more information on XML security see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#net + metadata: + category: security + cwe: CWE-643 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of data within XPath expressions ('XPath Injection') + patterns: + - pattern-inside: | + using System.Xml; + ... + - pattern-either: + - patterns: + - metavariable-regex: + metavariable: $FUNC + regex: ^(SelectNodes|SelectSingleNode|Compile|Evaluate|Matches|Select|SelectAncestors|SelectChildren|SelectDescendants)$ + - metavariable-regex: + metavariable: $TY + regex: ^(XPathNavigator|XmlDocument|XmlNode|XmlDocumentXPathExtensions)$ + - pattern: ($TY $VAR).$FUNC(<...$ARG...>, ...) + - pattern-not: ($TY $VAR).$FUNC("...", ...) + - patterns: + - pattern-inside: | + using System.Xml.Linq; + ... + - metavariable-regex: + metavariable: $FUNC + regex: ^(XPathEvaluate|XPathSelectElement|XPathSelectElements)$ + - pattern: $VAR.$FUNC(<...$ARG...>, ...) + - pattern-not: $VAR.$FUNC("...", ...) + - patterns: + - pattern-inside: | + using System.Xml.Schema; + ... + - pattern-either: + - patterns: + - pattern: $VAR.XPath = <...$ARG...>; + - pattern-not: $VAR.XPath = "..." + - patterns: + - pattern: new XmlSchemaXPath { XPath = <...$ARG...> }; + - focus-metavariable: $ARG + severity: INFO + - id: csharp_injection_rule-XmlDocumentXXEInjection + languages: + - csharp + message: | + External XML entities are a feature of XML parsers that allow documents to contain references + to + other documents or data. This feature can be abused to read files, communicate with external + hosts, + exfiltrate data, or cause a Denial of Service (DoS). + + XML parsers and document loaders must be configured to not resolve entities. This can be done + by: + - Ensuring you are running a version of .NET Framework greater than 4.5.2 (released in 2014). + - Using `XDocument` which disables entity resolution and is generally safe from DoS. + - Setting `XmlDocument`'s `XmlResolver` to null. + + Example of safely loading an XML file using `XmlDocument`: + ``` + XmlDocument document = new XmlDocument(); + document.XmlResolver = null; + document.Load("users.xml"); + ``` + + For more information on XML security, see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#net + metadata: + category: security + cwe: CWE-611 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper restriction of XML external entity reference ('XXE') + mode: taint + pattern-sinks: + - patterns: + - pattern-not-inside: | + (XmlDocument $DOC).XmlResolver = null; + ... + - pattern-either: + - pattern: (XmlDocument $DOC).Load(...); + - pattern: (XmlDocument $DOC).LoadXml(...); + pattern-sources: + - pattern: var $DOC = new System.Xml.XmlDocument(...); + - patterns: + - pattern: var $DOC = new System.Xml.XmlDocument {...}; + - pattern-not: var $DOC = new System.Xml.XmlDocument {...,XmlResolver = null,...}; + severity: WARNING + - id: csharp_injection_rule-XmlReaderXXEInjection + languages: + - csharp + message: | + External XML entities are a feature of XML parsers that allow documents to contain references + to + other documents or data. This feature can be abused to read files, communicate with external + hosts, + exfiltrate data, or cause a Denial of Service (DoS). + + XML parsers and document loaders must be configured to not resolve entities. This can be done + by: + - Ensuring you are running a version of .NET Framework greater than 4.5.2 (released in 2014). + - Setting `XmlTextReader`'s `ProhibitDtd` to `true` + - Setting `XmlReaderSettings` `DtdProcessing` to `DtdProcessing.Prohibit` + + Example of safely loading an XML file using `XmlDocument`: + ``` + var settings = new XmlReaderSettings(); + settings.DtdProcessing = DtdProcessing.Prohibit; + XmlReader reader = XmlReader.Create(path, settings); + ``` + + For more information on XML security, see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#net + metadata: + category: security + cwe: CWE-611 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference ('XXE') + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $SETTINGS.ProhibitDtd = false; + ... + - pattern-inside: | + $SETTINGS.DtdProcessing = DtdProcessing.Parse; + ... + - pattern: System.Xml.XmlReader.Create(..., $SETTINGS); + pattern-sources: + - pattern: var $SETTINGS = new XmlReaderSettings(); + severity: WARNING + - id: csharp_other_rule-UnsafeXSLTSettingUsed + languages: + - csharp + message: | + By setting `XsltSettings.EnableScript` to true, an adversary who is able to influence the + loaded + XSL document could directly inject code to compromise the system. It is strongly + recommended that an alternative approach is used to work with XML data. + + For increased security: + + - Never process user-supplied XSL style sheets + - Ensure `XsltSettings.EnableScript` is set to false + - Ensure `XsltSettings.EnableDocumentFunction` is set to false + + If the application must calculate values from XML input, instead of using XSL scripts to + execute functions, modify the XML document prior to running the + `XslCompiledTransform.Transform` method. + + Example of modifying the XML prior to running `Transform`: + ``` + const String filename = "number.xml"; + const String stylesheet = "calc.xsl"; + + // Compile the style sheet. + XsltSettings xslt_settings = new XsltSettings(); + xslt_settings.EnableScript = false; // disable script + xslt_settings.EnableDocumentFunction = false; // disable document() function + XslCompiledTransform xslt = new XslCompiledTransform(); + XmlResolver resolver = null; // set a null entity resolver + xslt.Load(stylesheet, xslt_settings, resolver); + + // Load the XML source file, using XDocument for safety + XDocument doc = XDocument.Load(filename); + + // do our modifications to the document before the transformation + // instead of inside of a script. + doc.Element("data").Add(new XElement("circle", new XElement("radius", 12))); + + // Create an XmlWriter. + XmlWriterSettings settings = new XmlWriterSettings(); + settings.OmitXmlDeclaration = true; + settings.Indent = true; + XmlWriter writer = XmlWriter.Create("output.xml", settings); + // Finally, execute the transformation. + xslt.Transform(doc.CreateReader(), writer); + writer.Close(); + ``` + + For more information on security considerations when using XSL see the following URLs: + - https://learn.microsoft.com/en-us/dotnet/standard/data/xml/xslt-security-considerations + - https://learn.microsoft.com/en-us/dotnet/api/system.xml.xsl.xslcompiledtransform?view=net-7.0#security-considerations + metadata: + category: security + cwe: CWE-91 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: XML injection (aka Blind XPath injection) + patterns: + - pattern-either: + - patterns: + - pattern: new XsltSettings() {...,$OPTIONS,...}; + - metavariable-pattern: + metavariable: $OPTIONS + pattern-either: + - pattern: EnableDocumentFunction = true + - pattern: EnableScript = true + - patterns: + - pattern: $SETTINGS.$OPT = true; + - pattern: | + var $SETTINGS = new XsltSettings(); + ... + $SETTINGS.$OPT = true; + - metavariable-pattern: + metavariable: $OPT + pattern-either: + - pattern: EnableDocumentFunction + - pattern: EnableScript + severity: WARNING + - id: csharp_password_rule-PasswordComplexity + languages: + - csharp + message: | + The application's `PasswordValidator.RequiredLength` property allows passwords + to be less than 8 characters. Consider requiring a length of at least 8 or more + characters to reduce the chance of passwords being brute forced. + + Example of setting the RequiredLength to 8 in ASP.NET Core Identity: + ``` + builder.Services.Configure(options => + { + // Default Password settings. + options.Password.RequireDigit = true; + options.Password.RequireLowercase = true; + options.Password.RequireNonAlphanumeric = true; + options.Password.RequireUppercase = true; + options.Password.RequiredLength = 8; + options.Password.RequiredUniqueChars = 1; + }); + ``` + + For more information on configuring ASP.NET Core Identity see: + https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-configuration + metadata: + category: security + cwe: CWE-521 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: Info + shortDescription: Weak password requirements + pattern-either: + - pattern: $OPT.Password.RequireDigit = false; + - pattern: $OPT.Password.RequireLowercase = false; + - pattern: $OPT.Password.RequireNonAlphanumeric = false; + - pattern: $OPT.Password.RequireUppercase = false; + - patterns: + - pattern: $OPT.Password.RequiredLength = $LEN; + - metavariable-comparison: + comparison: $LEN < 8 + metavariable: $LEN + - patterns: + - pattern: $OPT.Password.RequiredUniqueChars = $LEN; + - metavariable-comparison: + comparison: $LEN < 1 + metavariable: $LEN + severity: WARNING + - id: csharp_path_rule-PathTraversal + languages: + - csharp + message: | + The application dynamically constructs file or path information. If the path + information comes from user input, it could be abused to read sensitive files, + access other users data, or aid in exploitation to gain further system access. + + User input should never be used in constructing paths or files for interacting + with the filesystem. This includes filenames supplied by user uploads or downloads. + If possible consider hashing user input or replacing it with unique values and + use `System.IO.Path.GetFullPath` to resolve and validate the path information + prior to processing any file functionality. + + Example using `Path.GetFullPath` and not allowing direct user input: + ``` + // store user input alongside an ID we control + struct userData + { + public string userFilename; + public Guid id; + } + + class Program + { + public static void Main() + { + userData data = new userData(); + // user input, saved only as a reference + data.userFilename = "..\\test.txt"; + + // random id as the filename + data.id = Guid.NewGuid(); + + // restrict all file processing to this directory only + string basePath = "C:\\Restricted\\"; + + // resolve the full path, but only use our random generated id + string fullPath = Path.GetFullPath(basePath + data.id); + + // verify the path is contained within our basePath + if (!fullPath.StartsWith(basePath)) { + Console.WriteLine("Invalid path specified!"); + return; + } + // process / work with file + } + } + ``` + + For more information on path traversal issues see OWASP: + https://owasp.org/www-community/attacks/Path_Traversal + metadata: + category: security + cwe: CWE-22 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + mode: taint + pattern-sanitizers: + - pattern-either: + - pattern: (Microsoft.Extensions.FileProviders.PhysicalFileProvider $E).GetFileInfo(...) + - pattern: (System.Web.HttpServerUtility $E).MapPath(...) + - pattern: (System.Web.HttpServerUtilityBase $E).MapPath(...) + - pattern: (System.Web.HttpRequest $E).MapPath(...) + pattern-sinks: + - pattern-either: + - pattern: System.IO.Directory.Delete(...) + - pattern: System.IO.Directory.GetFiles(...) + - pattern: System.IO.Directory.Move(...) + - pattern: System.IO.File.AppendAllLines(...) + - pattern: System.IO.File.AppendAllLinesAsync(...) + - pattern: System.IO.File.AppendAllText(...) + - pattern: System.IO.File.AppendAllTextAsync(...) + - pattern: System.IO.File.AppendText(...) + - pattern: System.IO.File.Copy(...) + - pattern: System.IO.File.Create(...) + - pattern: System.IO.File.CreateText(...) + - pattern: System.IO.File.Delete(...) + - pattern: System.IO.File.Move(...) + - pattern: System.IO.File.Open(...) + - pattern: System.IO.File.OpenRead(...) + - pattern: System.IO.File.OpenText(...) + - pattern: System.IO.File.OpenWrite(...) + - pattern: System.IO.File.ReadAllBytes(...) + - pattern: System.IO.File.ReadAllBytesAsync(...) + - pattern: System.IO.File.ReadAllLines(...) + - pattern: System.IO.File.ReadAllLinesAsync(...) + - pattern: System.IO.File.ReadAllText(...) + - pattern: System.IO.File.ReadAllTextAsync(...) + - pattern: System.IO.File.ReadLines(...) + - pattern: System.IO.File.Replace(...) + - pattern: System.IO.File.SetAccessControl(...) + - pattern: System.IO.File.WriteAllBytes(...) + - pattern: System.IO.File.WriteAllBytesAsync(...) + - pattern: System.IO.File.WriteAllLines(...) + - pattern: System.IO.File.WriteAllLinesAsync(...) + - pattern: System.IO.File.WriteAllText(...) + - pattern: System.IO.File.WriteAllTextAsync(...) + - pattern: new System.IO.FileInfo(...) + - pattern: (System.IO.FileInfo $E).CopyTo(...) + - pattern: (System.IO.FileInfo $E).MoveTo(...) + - pattern: (System.IO.FileInfo $E).Replace(...) + - pattern: System.Reflection.Assembly.LoadFile(...) + - pattern: System.Reflection.Assembly.LoadFrom(...) + - pattern: System.Reflection.Assembly.ReflectionOnlyLoadFrom(...) + - pattern: System.Reflection.Assembly.UnsafeLoadFrom(...) + - pattern: System.AppDomain.AppendPrivatePath(...) + - pattern: System.Xml.XmlReader.Create(...) + - pattern: new System.IO.StreamReader.ctor(...) + - pattern: new System.IO.StreamWriter.ctor(...) + - pattern: new System.IO.FileStream.ctor(...) + - pattern: new System.Web.Mvc.FilePathResult(...) + - pattern: new Microsoft.AspNetCore.Mvc.PhysicalFileResult(...) + - pattern: (Microsoft.AspNetCore.Mvc.RazorPages.PageModel $E).PhysicalFile(...) + - pattern: (System.Web.UI.WebControls.FileUpload $E).SaveAs(...) + - pattern: (System.Web.HttpResponse $E).TransmitFile(...) + - pattern: (System.Web.HttpResponse $E).WriteFile(...) + - pattern: (System.Web.HttpResponseBase $E).TransmitFile(...) + - pattern: (System.Web.HttpResponseBase $E).WriteFile(...) + - pattern: (System.IO.Compression.ZipFileExtensions $E).CreateEntryFromFile(...) + - pattern: (System.IO.Compression.ZipFileExtensions $E).ExtractToFile(...) + - pattern: (System.IO.Compression.ZipFileExtensions $E).ExtractToDirectory(...) + - pattern: (System.Net.WebClient $E).DownloadFile(...) + - pattern: (System.Net.WebClient $E).DownloadFileAsync(...) + - pattern: (System.Net.WebClient $E).DownloadFileTaskAsync(...) + pattern-sources: + - patterns: + - pattern-inside: | + public class $CLASS : Controller { + ... + } + - pattern: $PARAM + - pattern-either: + - patterns: + - metavariable-regex: + metavariable: $HTTP_ANNO + regex: ^(Http) + - pattern-inside: | + [$HTTP_ANNO] + public string $METHOD(...,$PARAM,...){...} + - pattern-inside: | + public IActionResult $METHOD(...,$PARAM,...){...} + severity: WARNING + - id: csharp_validation_rule-InputValidation + languages: + - csharp + message: | + By using the `[ValidateInput(false)]` attribute in a controller + class, the application will disable request validation for that + method. This disables ASP.NET from examining requests for injection + attacks such as Cross-Site-Scripting (XSS). + + If possible, re-enable validation by using `ValidateInput(true)`. + In some cases this may not be possible, in which case ensure how the + request data used is validated and this method does not + output user input directly into the view. + + For more information on protecting ASP.NET Core applications from XSS see: + https://learn.microsoft.com/en-us/aspnet/core/security/cross-site-scripting + + Example of enabling `ValidateInput` attribute: + ``` + class ControllerClass + { + [ValidateInput(true)] + public void SomeActionMethod() + { + } + } + ``` + + For more information on ASP.NET request validation see OWASP: + https://owasp.org/www-community/ASP-NET_Request_Validation + metadata: + category: security + cwe: CWE-554 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Info + shortDescription: ASP.NET input validation disabled + patterns: + - pattern: | + [ValidateInput(false)] + public $RET $FOO(...) + { + ... + } + severity: WARNING + - id: csharp_xss_rule-HtmlElementXss + languages: + - csharp + message: | + Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat + user input + as markup or script code. It is important to encode the data depending on the specific context + it + is used in. There are at least six context types: + + - Inside HTML tags `
context 1
` + - Inside attributes: `
` + - Inside event attributes `` + - Inside script blocks: `` + - Unsafe element HTML assignment: `element.innerHTML = "context 5"` + - Inside URLs: `
link` + User input that is displayed within the application must be encoded, sanitized or validated + to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be + taken + to not mix server-side templating with client-side templating, as the server-side templating + will + not encode things like {{ 7*7 }} which may execute client-side templating features. + + It is _NOT_ advised to encode user input prior to inserting into a data store. The data will + need to be + encoded depending on context of where it is output. It is much safer to force the displaying + system to + handle the encoding and not attempt to guess how it should be encoded. + + Consider using built-in framework capabilities for automatically encoding user input. + Depending + on output context, consider using the following `System.Text.Encodings.Web` encoders: + + - [HtmlEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.htmlencoder) + - [JavaScriptEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.javascriptencoder) + - [UrlEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.urlencoder) + + For more information on protecting ASP.NET Core applications from XSS see: + https://learn.microsoft.com/en-us/aspnet/core/security/cross-site-scripting#accessing-encoders-in-code + metadata: + category: security + cwe: CWE-79 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + mode: taint + pattern-sanitizers: + - patterns: + - metavariable-regex: + metavariable: $FUNC + regex: (SerializeObject|HtmlAttributeEncode|HtmlEncode|HtmlFormUrlEncode|UrlEncode|UrlPathEncode|XmlAttributeEncode|XmlEncode|Encode) + - pattern: $CLASS.$FUNC(...) + pattern-sinks: + - pattern: (System.Web.Mvc.HtmlHelper $E).Raw(...) + - pattern: (Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper $E).Raw(...) + - pattern: Response.Write(...) + - pattern: (System.Web.UI.HtmlTextWriter $E).AddAttribute(...) + - pattern: (System.Web.UI.HtmlTextWriter $E).AddStyleAttribute(...) + - pattern: (System.Web.UI.HtmlTextWriter $E).RenderBeginTag(...) + - pattern: (System.Web.UI.HtmlTextWriter $E).Write(...) + - pattern: (System.Web.UI.HtmlTextWriter $E).WriteAttribute(...) + - pattern: (System.Web.UI.HtmlTextWriter $E).WriteBeginTag(...) + - pattern: (System.Web.UI.HtmlTextWriter $E).WriteEndTag(...) + - pattern: (System.Web.UI.HtmlTextWriter $E).WriteFullBeginTag(...) + - pattern: (System.Web.UI.HtmlTextWriter $E).WriteStyleAttribute(...) + pattern-sources: + - patterns: + - pattern: $PARAM + - pattern-inside: | + $RET $METHOD(...,$PARAM,...){...} + - pattern: Request.Cookies[...] + - pattern: Request.Cookies.Get(...) + - pattern: Request.Form[...] + - pattern: Request.Form.Get(...) + - pattern: Request.Headers[...] + - pattern: Request.Headers.Get(...) + - pattern: Request.QueryString[...] + - pattern: Request.QueryString.Get(...) + - pattern: Request.Params[...] + - pattern: Request.RawUrl + - pattern: Request.Url + - pattern: Request.Path + - pattern: Request.Body + - pattern: $CTX.Request.Cookies[...] + - pattern: $CTX.Request.Cookies.Get(...) + - pattern: $CTX.Request.Form[...] + - pattern: $CTX.Request.Form.Get(...) + - pattern: $CTX.Request.Headers[...] + - pattern: $CTX.Request.Headers.Get(...) + - pattern: $CTX.Request.QueryString[...] + - pattern: $CTX.Request.QueryString.Get(...) + - pattern: $CTX.Request.Body + severity: WARNING + - id: csharp_xss_rule-ScriptXss + languages: + - csharp + message: | + Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat + user input + as markup or script code. It is important to encode the data depending on the specific context + it + is used in. + + User input that is used within the application scripts must be encoded, sanitized or validated + to ensure it cannot change the behavior of the Javascript code. + + It is _NOT_ advised to encode user input prior to inserting into a data store. The data will + need to be + encoded depending on context of where it is output. It is much safer to force the displaying + system to + handle the encoding and not attempt to guess how it should be encoded. + + Consider using built-in framework capabilities for automatically encoding user input. + Depending + on output context, consider using the following `System.Text.Encodings.Web` encoders: + + - [HtmlEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.htmlencoder) + - [JavaScriptEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.javascriptencoder) + - [UrlEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.urlencoder) + + For more information on protecting ASP.NET Core applications from XSS see: + https://learn.microsoft.com/en-us/aspnet/core/security/cross-site-scripting#accessing-encoders-in-code + metadata: + category: security + cwe: CWE-79 + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + mode: taint + pattern-propagators: + - from: $IN + pattern: (StringBuilder $OUT).Append($IN) + to: $OUT + pattern-sanitizers: + - patterns: + - metavariable-regex: + metavariable: $FUNC + regex: (SerializeObject|HtmlAttributeEncode|HtmlEncode|HtmlFormUrlEncode|UrlEncode|UrlPathEncode|XmlAttributeEncode|XmlEncode|Encode) + - pattern: $CLASS.$FUNC(...) + pattern-sinks: + - pattern: $SCRIPTMANAGER.RegisterStartupScript(...) + - pattern: $SCRIPTMANAGER.RegisterClientScriptBlock(...) + - pattern: System.Web.UI.RegisterStartupScript(...) + - pattern: System.Web.UI.RegisterClientScriptBlock(...) + pattern-sources: + - patterns: + - pattern: $PARAM + - pattern-inside: | + $RET $METHOD(...,$PARAM,...){...} + - pattern: Request.Cookies[...] + - pattern: Request.Cookies.Get(...) + - pattern: Request.Form[...] + - pattern: Request.Form.Get(...) + - pattern: Request.Headers[...] + - pattern: Request.Headers.Get(...) + - pattern: Request.QueryString[...] + - pattern: Request.QueryString.Get(...) + - pattern: Request.Params[...] + - pattern: Request.RawUrl + - pattern: Request.Url + - pattern: Request.Path + - pattern: Request.Body + - pattern: $CTX.Request.Cookies[...] + - pattern: $CTX.Request.Cookies.Get(...) + - pattern: $CTX.Request.Form[...] + - pattern: $CTX.Request.Form.Get(...) + - pattern: $CTX.Request.Headers[...] + - pattern: $CTX.Request.Headers.Get(...) + - pattern: $CTX.Request.QueryString[...] + - pattern: $CTX.Request.QueryString.Get(...) + - pattern: $CTX.Request.Body + - pattern: $ELE.Text + severity: WARNING + - id: go_blocklist_rule-blocklist-des + languages: + - go + message: | + The DES algorithm has not been recommended for over 15 years and was withdrawn from NIST (FIPS + 46-3) in 2005. It is recommended that an algorithm that provides message integrity be used + instead. Consider using `XChaCha20Poly1305` or `AES-256-GCM`. + + For older applications, `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `XChaCha20Poly1305` + - Smaller nonce value size compared to `XChaCha20Poly1305` + - Catastrophic failure if nonce values are re-used + + Example using + [XChaCha20Poly1305](https://pkg.go.dev/golang.org/x/crypto/chacha20poly1305#NewX): + ``` + key := make([]byte, chacha20poly1305.KeySize) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + log.Fatal(err) + } + + // NewX is a variant that uses longer nonce values for better security + aead, err := chacha20poly1305.NewX(key) + if err != nil { + log.Fatal(err) + } + + var encrypted = []byte{} + var nonce = []byte{} + + // Encryption routine + { + msg := []byte("Some secret message") + nonce = make([]byte, aead.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + log.Fatal("failed to generate nonce") + } + + encrypted = aead.Seal(nil, nonce, msg, nil) + } + + // Decryption routine + { + if len(encrypted) < aead.NonceSize() { + log.Fatal("incorrect ciphertext length") + } + + msg, err := aead.Open(nil, nonce, encrypted, nil) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Decrypted: %s\n", msg) + } + ``` + + Example using [AES-256-GCM](https://pkg.go.dev/crypto/cipher#NewGCM): + ``` + // 32 byte keys will configure AES-256 + key := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + log.Fatal(err) + } + + blockCipher, err := aes.NewCipher(key) + if err != nil { + log.Fatal(err) + } + + aead, err := cipher.NewGCM(blockCipher) + if err != nil { + log.Fatal(err) + } + + var encrypted = []byte{} + var nonce = []byte{} + // Encryption routine + { + msg := []byte("Some secret message") + // note that the key must be rotated every 2^32 random nonces used otherwise + // cipher text could be repeated + nonce = make([]byte, 12) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + log.Fatal(err) + } + encrypted = aead.Seal(nil, nonce, msg, nil) + } + + // Decryption routine + { + msg, err := aead.Open(nil, nonce, encrypted, nil) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Decrypted: %s\n", msg) + } + ``` + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern: | + import "crypto/des" + severity: WARNING + - id: go_blocklist_rule-blocklist-md5 + languages: + - go + message: | + The MD5 message-digest algorithm has been cryptographically broken and is unsuitable for + further use. The MD5 hash algorithm has been found to be vulnerable to producing collisions. + This means that two different values, when hashed, can lead to the same hash value. It is + recommended that the SHA-3 or BLAKE2 family of algorithms be used for non-password based + cryptographic hashes instead. For password based cryptographic hashes, consider using the + bcrypt or Argon2id family of cryptographic hashes. + + Hashing values using [BLAKE2](https://pkg.go.dev/golang.org/x/crypto/blake2b): + ``` + fileContents := []byte("some file contents to create hash for") + blake2bHasher, err := blake2b.New512(nil) + if err != nil { + log.Fatal(err) + } + hashedValue := blake2bHasher.Sum(fileContents) + fmt.Printf("%s\n", hex.EncodeToString(hashedValue)) + ``` + + Hashing and securely comparing passwords using + [Argon2id](https://pkg.go.dev/golang.org/x/crypto/argon2#hdr-Argon2id): + ``` + type argonParameters struct { + variant string + version int + memory uint32 + iterations uint32 + parallelism uint8 + saltLength uint32 + keyLength uint32 + } + + func (a argonParameters) StringFormat(salt, derivedKey []byte) string { + encodedSalt := base64.RawStdEncoding.EncodeToString(salt) + encodedKey := base64.RawStdEncoding.EncodeToString(derivedKey) + + return fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", + argon2.Version, + a.memory, + a.iterations, + a.parallelism, + encodedSalt, + encodedKey, + ) + } + + func main() { + // Initialize Argon2id parameters + p := argonParameters{ + memory: 64 * 1024, + iterations: 3, + parallelism: 2, + saltLength: 16, + keyLength: 32, + } + + // Generate random salt (to be stored alongside derived hash key) + salt := make([]byte, p.saltLength) + if _, err := io.ReadFull(rand.Reader, salt); err != nil { + log.Fatal(err) + } + + usersPassword := []byte("User's Very S3cur3P4ss@rd@#$%") + + var derivedKey []byte + // Create key hash derived from user's password + { + derivedKey = argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, + p.keyLength) + // store p.StringFormat(...) result in a data store... + fmt.Printf("%s\n", p.StringFormat(salt, derivedKey)) + } + + // Verify a user's password against key + { + keyToCompare := argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, + p.keyLength) + + // Use subtle.ConstantTimeCompare(..., ...) to ensure no side channel leaks used in timing + attacks + if subtle.ConstantTimeCompare(derivedKey, keyToCompare) == 1 { + fmt.Printf("Passwords match\n") + } else { + fmt.Printf("Passwords do not match\n") + } + } + } + ``` + + For more information on password storage see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern: | + import "crypto/md5" + severity: WARNING + - id: go_blocklist_rule-blocklist-rc4 + languages: + - go + message: | + The RC4 stream-cipher has been cryptographically broken and is unsuitable + for use in production. It is recommended that ChaCha20 or Advanced Encryption + Standard (AES) be used instead. Consider using `XChaCha20Poly1305` or `AES-256-GCM`. + + For older applications, `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `XChaCha20Poly1305` + - Smaller nonce value size compared to `XChaCha20Poly1305` + - Catastrophic failure if nonce values are re-used + + Example using + [XChaCha20Poly1305](https://pkg.go.dev/golang.org/x/crypto/chacha20poly1305#NewX): + ``` + key := make([]byte, chacha20poly1305.KeySize) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + log.Fatal(err) + } + + // NewX is a variant that uses longer nonce values for better security + aead, err := chacha20poly1305.NewX(key) + if err != nil { + log.Fatal(err) + } + + var encrypted = []byte{} + var nonce = []byte{} + + // Encryption routine + { + msg := []byte("Some secret message") + nonce = make([]byte, aead.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + log.Fatal("failed to generate nonce") + } + + encrypted = aead.Seal(nil, nonce, msg, nil) + } + + // Decryption routine + { + if len(encrypted) < aead.NonceSize() { + log.Fatal("incorrect ciphertext length") + } + + msg, err := aead.Open(nil, nonce, encrypted, nil) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Decrypted: %s\n", msg) + } + ``` + + Example using [AES-256-GCM](https://pkg.go.dev/crypto/cipher#NewGCM): + ``` + // 32 byte keys will configure AES-256 + key := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + log.Fatal(err) + } + + blockCipher, err := aes.NewCipher(key) + if err != nil { + log.Fatal(err) + } + + aead, err := cipher.NewGCM(blockCipher) + if err != nil { + log.Fatal(err) + } + + var encrypted = []byte{} + var nonce = []byte{} + // Encryption routine + { + msg := []byte("Some secret message") + // note that the key must be rotated every 2^32 random nonces used otherwise + // cipher text could be repeated + nonce = make([]byte, 12) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + log.Fatal(err) + } + encrypted = aead.Seal(nil, nonce, msg, nil) + } + + // Decryption routine + { + msg, err := aead.Open(nil, nonce, encrypted, nil) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Decrypted: %s\n", msg) + } + ``` + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern: | + import "crypto/rc4" + severity: WARNING + - id: go_blocklist_rule-blocklist-sha1 + languages: + - go + message: | + The SHA-1 message-digest algorithm has been cryptographically broken and + is unsuitable for further use. It is + recommended that the SHA-3, or BLAKE2 family of algorithms be used for non-password based + cryptographic hashes instead. For password based cryptographic hashes, consider using the + bcrypt or Argon2id family of cryptographic hashes. + + Hashing values using [BLAKE2](https://pkg.go.dev/golang.org/x/crypto/blake2b): + ``` + fileContents := []byte("some file contents to create hash for") + blake2bHasher, err := blake2b.New512(nil) + if err != nil { + log.Fatal(err) + } + hashedValue := blake2bHasher.Sum(fileContents) + fmt.Printf("%s\n", hex.EncodeToString(hashedValue)) + ``` + + Hashing and securely comparing passwords using + [Argon2id](https://pkg.go.dev/golang.org/x/crypto/argon2#hdr-Argon2id): + ``` + type argonParameters struct { + variant string + version int + memory uint32 + iterations uint32 + parallelism uint8 + saltLength uint32 + keyLength uint32 + } + + func (a argonParameters) StringFormat(salt, derivedKey []byte) string { + encodedSalt := base64.RawStdEncoding.EncodeToString(salt) + encodedKey := base64.RawStdEncoding.EncodeToString(derivedKey) + + return fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", + argon2.Version, + a.memory, + a.iterations, + a.parallelism, + encodedSalt, + encodedKey, + ) + } + + func main() { + // Initialize Argon2id parameters + p := argonParameters{ + memory: 64 * 1024, + iterations: 3, + parallelism: 2, + saltLength: 16, + keyLength: 32, + } + + // Generate random salt (to be stored alongside derived hash key) + salt := make([]byte, p.saltLength) + if _, err := io.ReadFull(rand.Reader, salt); err != nil { + log.Fatal(err) + } + + usersPassword := []byte("User's Very S3cur3P4ss@rd@#$%") + + var derivedKey []byte + // Create key hash derived from user's password + { + derivedKey = argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, + p.keyLength) + // store p.StringFormat(...) result in a data store... + fmt.Printf("%s\n", p.StringFormat(salt, derivedKey)) + } + + // Verify a user's password against key + { + keyToCompare := argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, + p.keyLength) + + // Use subtle.ConstantTimeCompare(..., ...) to ensure no side channel leaks used in timing + attacks + if subtle.ConstantTimeCompare(derivedKey, keyToCompare) == 1 { + fmt.Printf("Passwords match\n") + } else { + fmt.Printf("Passwords do not match\n") + } + } + } + ``` + + For more information on password storage see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern: | + import "crypto/sha1" + severity: WARNING + - id: go_crypto_rule-badtlssettings + languages: + - go + message: | + Usage of a cryptographically insecure cipher suite has been detected. It is recommended that + alternative ciphers be used instead. It is strongly recommended that all TLS connections + use TLS 1.3 as Go will automatically choose the most secure cipher when negotiating the + TLS handshake with client or servers. TLS 1.3 cipher suites are configured to require Perfect + Forward Secrecy (PFS). + PFS is an important property as it will ensure that past encrypted transmissions could not be + decrypted + if the TLS certificate was compromised. + + Example using TLS 1.3 for a Go server: + ``` + cert, err := tls.LoadX509KeyPair("server.crt", "server.key") + if err != nil { + log.Fatal(err) + } + + cfg := &tls.Config{Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS13} + srv := &http.Server{ + Addr: ":8999", + TLSConfig: cfg, + ReadTimeout: time.Minute, + WriteTimeout: time.Minute, + } + log.Fatal(srv.ListenAndServeTLS("", "")) + ``` + + If TLS 1.0-1.2 must be used, then the following list of ciphers should be chosen as they + support + Perfect Forward Secrecy (PFS): + + - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 + + + Example `tls.Config` using the recommended cipher suites: + ``` + cfg := &tls.Config{ + MinVersion: tls.VersionTLS12, + CipherSuites: []uint16{ + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + }, + } + ``` + + For more information on cipher suites in Go see: https://go.dev/blog/tls-cipher-suites + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) + tls.Config{..., CipherSuites: []$SLICE{..., $CIPHERS, ...}, ...} - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseRedirect(..., $STR % $DATA, ...) + tls.CipherSuite{..., ID: $CIPHERS, ...} + - metavariable-regex: + metavariable: $CIPHERS + regex: ((?!tls.TLS_AES_128_GCM_SHA256)|(?!tls.TLS_AES_256_GCM_SHA384)|(?!tls.TLS_CHACHA20_POLY1305_SHA256)| (?!tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)|(?!tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)| (?!tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)|(?!tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)| (?!tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305)|(?!tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)| (?!tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305)|(?!tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)| (?!tls.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)|(?!tls.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384)) + severity: WARNING + - id: go_crypto_rule-insecure-ignore-host-key + languages: + - go + message: | + The application was found to ignore host keys. Host keys are important as + they provide assurance that the client can prove that the host is trusted. + By ignoring these host keys, it is impossible for the client to validate the + connection is to a trusted host. + + For the `ssh.ClientConfig` `HostKeyCallback` property, consider using the + [knownhosts](https://pkg.go.dev/golang.org/x/crypto/ssh/knownhosts) package that + parses OpenSSH's `known_hosts` key database. + + Example configuration connecting to a known, trusted host: + ``` + knownHostCallback, err := knownhosts.New("/home/user/.ssh/known_hosts") + if err != nil { + log.Fatal(err) + } + + // Create client config using the knownHost callback function + config := &ssh.ClientConfig{ + ... + HostKeyCallback: knownHostCallback, + } + + // Connect to ssh server + conn, err := ssh.Dial("tcp", "localhost:22", config) + if err != nil { + log.Fatal("unable to connect: ", err) + } + defer conn.Close() + ``` + metadata: + category: security + cwe: CWE-322 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: Medium + shortDescription: Key exchange without entity authentication + patterns: + - pattern: ssh.InsecureIgnoreHostKey(...) + severity: WARNING + - id: go_crypto_rule-tlsversion + languages: + - go + message: "TLS versions 1.1 and 1.0 were deprecated by the IETF in June 2018 due to \na number of attacks against the vulnerable versions. Use of a deprecated \nTLS version may result in the unauthorized retrieval of sensitive \ninformation. It is strongly recommended that all TLS connections\nuse TLS 1.3 as Go will automatically choose the most secure cipher when \nnegotiating the TLS handshake with client or servers. TLS 1.3 cipher suites \nare configured to require Perfect Forward Secrecy (PFS). PFS is an important \nproperty as it will ensure that past encrypted transmissions could not be\ndecrypted if the TLS certificate was compromised.\n\nExample using TLS 1.3 for a Go server:\n```\ncert, err := tls.LoadX509KeyPair(\"server.crt\", \"server.key\")\nif err != nil {\n log.Fatal(err)\n}\n\ncfg := &tls.Config{Certificates: []tls.Certificate{cert}, \n MinVersion: tls.VersionTLS13}\n\nsrv := &http.Server{\n Addr: \":8999\",\n TLSConfig: cfg,\n ReadTimeout: time.Minute,\n WriteTimeout: time.Minute,\n}\nlog.Fatal(srv.ListenAndServeTLS(\"cert.pem\", \"key.pem\"))\n```\n" + metadata: + category: security + cwe: CWE-310 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of deprecated TLS version + pattern-either: + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + tls.Config{...} + - pattern: | + MinVersion: $VAL + - patterns: + - pattern-inside: | + $VAR = uint16($VAL) + ... + - pattern-inside: | + tls.Config{...} + - pattern: | + MinVersion: $VAR + - metavariable-pattern: + metavariable: $VAL + pattern-either: + - pattern: tls.VersionTLS11 + - pattern: tls.VersionTLS10 + - patterns: + - pattern-inside: | + tls.Config{...} - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) + MaxVersion: $ANYVAL + - pattern-not-inside: | + tls.Config{..., MinVersion: ..., ...} + severity: WARNING + - id: go_crypto_rule-weakkeystrength + languages: + - go + message: | + The application is generating an RSA key that is less than the recommended 2048 bits. + The National Institute of Standards and Technology (NIST) deprecated signing Digital + Certificates that contained RSA Public Keys of 1024 bits in December 2010. While + 1024-bit RSA keys have not been factored yet, advances in compute may make it possible + in the near future. + + To generate an RSA key of 2048 pass the number of bits as the second parameter to + the `rsa.GenerateKey` function: + ``` + import ( + "crypto/rand" + "crypto/rsa" + ) + + func generate() { + key, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + log.Fatal(err) + } + } + ``` + metadata: + category: security + cwe: CWE-326 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Inadequate encryption strength + patterns: + - pattern-either: - pattern: | - $DATA = request.$W[...] + rsa.GenerateKey(..., $ARG) + - metavariable-comparison: + comparison: $ARG < 2048 + metavariable: $ARG + severity: WARNING + - id: go_crypto_rule-weakrandsource + languages: + - go + message: | + Go's `math/rand` is not meant for use in generating random numbers for any cryptographic or + security sensitive context. This includes generating random numbers that could be used in + user specific identifiers or where the random number that is generated is considered to + be secret. + + Replace all imports of `math/rand` with `crypto/rand`. + metadata: + category: security + cwe: CWE-338 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of cryptographically weak Pseudo-Random Number Generator (PRNG) + patterns: + - patterns: + - pattern-inside: | + import $IMPORT "math/rand" ... - django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) + - pattern-not-inside: | + import "crypto/rand" + - pattern-either: + - pattern: $IMPORT.$METHOD(...) + - pattern: rand.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (Float32|Float64|Int31|Int31n|Int63|Int63n|NormalFloat64|Uint32|Uint64) + severity: WARNING + - id: go_file-permissions_rule-fileperm + languages: + - go + message: | + The application was found setting file permissions to overly permissive values. Consider + using the following values if the application user is the only process to access + the file: + + - 0400 - read only access to the file + - 0200 - write only access to the file + - 0600 - read/write access to the file + + Example creating a file with read/write permissions for the application user: + ``` + f, err := os.OpenFile("file.txt", os.O_CREATE, 0600) + if err != nil { + log.Fatal(err) + } + defer f.Close() + // continue to work with file here + ``` + + For all other values please see: + https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation + metadata: + category: security + cwe: CWE-732 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Incorrect permission assignment for critical resource + patterns: + - pattern-either: + - pattern: os.Chmod(...,$MASK) + - pattern: os.OpenFile(...,$MASK) + - pattern: os.WriteFile(...,$MASK) + - metavariable-comparison: + base: 8 + comparison: $MASK > 0o640 + metavariable: $MASK + severity: WARNING + - id: go_file-permissions_rule-mkdir + languages: + - go + message: | + The application was found setting directory permissions to overly permissive values. Consider + using the following values if the application user is the only process to access + files in the directory specified: + - 0700 - read/write access to the files in the directory + + Another common value is `0750` which allows the application user read/write access and group + users to read the files contained in the directory. + + Example creating a directory with read/write permissions for only the application user: + ``` + err := os.Mkdir("directory", 0700) + if err != nil { + log.Fatal(err) + } + ``` + + For all other values please see: + https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation + metadata: + category: security + cwe: CWE-732 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Incorrect permission assignment for critical resource + patterns: + - pattern-either: + - pattern: os.Mkdir(...,$MASK) + - pattern: os.MkdirAll(...,$MASK) + - metavariable-comparison: + base: 8 + comparison: $MASK > 0o750 + metavariable: $MASK + severity: WARNING + - id: go_filesystem_rule-decompression-bomb + languages: + - go + message: | + Directly decompressing files or buffers may lead to a potential Denial of Service (DoS) + due to a decompression bomb. Decompression bombs are maliciously compressed files + or data that decompresses to extremely large sizes. This can cause the process to run + out of memory, or the disk to fill up. + + To protect against decompression bombs, an + [io.LimitReader(...)](https://pkg.go.dev/io#LimitReader) + should be used to limit how much can be read during the decompression routine. + + Example using `io.LimitReader` to protect against a decompression bomb: + ``` + f, err := os.Open("some.gz") + if err != nil { + log.Fatal(err) + } + + r, err := gzip.NewReader(f) + if err != nil { + log.Fatal(err) + } + + const oneMegabyte = 1024 * 1024 + limitedReader := io.LimitReader(r, oneMegabyte) + + // use limitedReader to stop copying after 1 MB + if _, err := io.Copy(os.Stdout, limitedReader); err != nil { + log.Fatal(err) + } + ``` + metadata: + category: security + cwe: CWE-409 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper handling of highly compressed data + mode: taint + pattern-sanitizers: + - patterns: + - pattern: io.LimitReader($TAINTED, ...) + - focus-metavariable: $TAINTED + pattern-sinks: + - patterns: + - pattern: io.Copy($DST, $TAINTED) + - focus-metavariable: $TAINTED + - patterns: + - pattern: io.CopyBuffer($DST, $TAINTED, $BUF) + - focus-metavariable: $TAINTED + pattern-sources: + - pattern: gzip.NewReader(...) + - pattern: zlib.NewReader(...) + - pattern: bzip2.NewReader(...) + - pattern: flate.NewReader(...) + - pattern: lzw.NewReader(...) + - pattern: tar.NewReader(...) + - pattern: zip.NewReader(...) + - pattern: zlib.NewReaderDict(...) + - pattern: flate.NewReaderDict(...) + - pattern: zip.OpenReader(...) + severity: WARNING + - id: go_filesystem_rule-fileread + languages: + - go + message: | + The application dynamically constructs file or path information. If the path + information comes from user input, it could be abused to read sensitive files, + access other users data or aid in exploitation to gain further system access. + + User input should never be used in constructing paths or files for interacting + with the filesystem. This includes filenames supplied by user uploads or downloads. + If possible, consider hashing user input or replacing it with unique values. + Additionally, use `filepath.Base` to only use the filename and not path information. + Always validate the full path prior to opening or writing to any file. + + Example using `filepath.Base`, generating a unique filename without using + user input to construct filepath information: + ``` + type userData struct { + id string + userFilename string + } + + func newUserData(userFilename string) userData { + return userData{ + id: randomFileID(), // random id as the filename + userFilename: userFilename, + } + } + + // randomFileID generates a random id, to be used as a filename + func randomFileID() string { + id := make([]byte, 16) + if _, err := io.ReadFull(rand.Reader, id); err != nil { + log.Fatal(err) + } + return hex.EncodeToString(id) + } + + func main() { + + // user input, saved only as a reference + data := newUserData("../../possibly/malicious") + + // restrict all file access to this path + const basePath = "/tmp/" + + // resolve the full path, but only use our random generated id + resolvedPath, err := filepath.Join(basePath, filepath.Base(data.id)) + if err != nil { + log.Fatal(err) + } + + // verify the path is prefixed with our basePath + if !strings.HasPrefix(resolvedPath, basePath) { + log.Fatal("path does not start with basePath") + } + // process / work with file + } + ``` + + For more information on path traversal issues see OWASP: + https://owasp.org/www-community/attacks/Path_Traversal + metadata: + category: security + cwe: CWE-22 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: | + $CLEAN := $PKG.Clean(...) + ... + if !strings.HasPrefix($CLEAN, "...") {...} + - pattern: | + $CLEAN := $PKG.Clean(...) + ... + if strings.HasPrefix($CLEAN, "...") {...} + - pattern: | + $CLEAN := $PKG.Clean(...) + ... + if strings.HasPrefix($CLEAN, "...") == false {...} + - metavariable-regex: + metavariable: $PKG + regex: ^((file)?path)$ + pattern-sinks: + - pattern: os.OpenFile(...) + - pattern: os.Open(...) + - pattern: os.ReadFile(...) + - pattern: ioutil.ReadFile(...) + pattern-sources: + - pattern: os.Getenv(...) + - pattern: fmt.Sprintf(...) + - pattern: filepath.Join(...) + - pattern: path.Join(...) + - patterns: + - pattern-either: + - pattern: '... + $TAINTED' + - pattern: '... + $TAINTED + ...' + - pattern: $TAINTED + ... + - pattern-not: '"..." + $TAINTED' + - pattern-not: '"..." + $TAINTED + "..."' + - pattern-not: $TAINTED + "..." + - pattern-not: fmt.Sprintf("...", "...") + - patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$SOURCE_METHOD + - pattern: | + ($REQUEST : http.Request).$SOURCE_METHOD + - metavariable-regex: + metavariable: $SOURCE_METHOD + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + severity: WARNING + - id: go_filesystem_rule-httprootdir + languages: + - go + message: | + The application is potentially exposing the entire filesystem by mounting the root + directory `/` to an HTTP handler function. Anyone who is able to access this HTTP + server may be able to access any file that the HTTP server has access to. + + Restrict the `http.Dir` path to only a specific folder instead of the entire + filesystem. + + Example server only allowing directory listing on a public directory: + ``` + const path = "/var/www/html/public" + fs := http.FileServer(http.Dir(path)) + log.Fatal(http.ListenAndServe(":9000", fs)) + ``` + metadata: + category: security + cwe: CWE-552 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Files or directories accessible to external parties + patterns: + - pattern-either: - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." + import $NET "net/http" ... - django.http.HttpResponseRedirect(..., $INTERM, ...) + $NET.Dir("/") - pattern: | - $DATA = request.$W[...] + import "net/http" ... - django.http.HttpResponseRedirect(..., $STR + $DATA, ...) + http.Dir("/") + severity: WARNING + - id: go_filesystem_rule-poorwritepermissions + languages: + - go + message: | + The application was found setting file permissions to overly permissive values. Consider + using the following values if the application user is the only process to access + the file: + + - 0400 - read only access to the file + - 0200 - write only access to the file + - 0600 - read/write access to the file + + Example writing file contents with read/write permissions for the application user: + ``` + dat := []byte("sensitive data") + if err := os.WriteFile("file.txt", dat, 0600); err != nil { + log.Fatal(err) + } + ``` + + For all other values please see: + https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation + metadata: + category: security + cwe: CWE-276 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Incorrect default permissions + patterns: + - pattern-either: - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., request.$W[...], ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) - - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) - - pattern: return django.http.HttpResponseRedirect(..., request.$W[...], ...) - - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) - - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) - - pattern: django.http.HttpResponseRedirect(..., request.$W, ...) - - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S % request.$W, ...) - - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) + ioutil.WriteFile(..., ..., $ARG) + - metavariable-comparison: + base: 8 + comparison: $ARG > 0o600 + metavariable: $ARG + severity: WARNING + - id: go_filesystem_rule-tempfiles + languages: + - go + message: | + The application was found creating files in shared system temporary directories + (`/tmp` or `/var/tmp`) without using the `os.CreateTemp` function. Depending + on how the application uses this temporary file, an attacker may be able to create + symlinks that point to other files prior to the application creating or writing + to the target file, leading to unintended files being created or overwritten. + + Example using `os.CreateTemp` in an application restricted directory: + ``` + // assumes /opt/appdir/ is chown'd to the running application user + if err := os.MkdirAll("/opt/appdir/restricted", 0700); err != nil { + log.Fatal(err) + } + + // create a temporary file in the restricted directory in the form of temp-952569059.txt + f, err := os.CreateTemp("/opt/appdir/restricted", "temp-*.txt") + if err != nil { + log.Fatal(err) + } + + defer f.Close() + // clean up on exit + defer os.Remove(f.Name()) + // work with file + ``` + metadata: + category: security + cwe: CWE-378 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Creation of temporary file with insecure permissions + patterns: + - pattern-either: - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseRedirect(..., $DATA, ...) + os.WriteFile("$ARG", ...) - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) + ioutil.WriteFile("$ARG", ...) - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) + os.OpenFile("$ARG", <... os.O_CREATE ...>, ...) - pattern: | - $DATA = request.$W + os.Create("$ARG") + - metavariable-regex: + metavariable: $ARG + regex: (/tmp/.*|/var/tmp/.*) + severity: WARNING + - id: go_filesystem_rule-ziparchive + languages: + - go + message: | + The application may be vulnerable to a path traversal if it extracts untrusted archive files. + This vulnerability is colloquially known as 'Zip Slip'. Archive files may contain folders + which, + when extracted, may write outside of the intended directory. This is exploited by including + path traversal characters such as `../../other/directory` to overwrite or place files in system + or application directories. + + Extra care must be taken when extracting archive files as there are numerous concerns: + + - Limit the size of the zip archive as it may contain "Zip Bombs", files that extract to + extremely + large sizes. + - If possible, generate unique filenames instead of using the archives file names, as it may be + possible for users to overwrite files if the filenames are the same. + - Validate file paths are written with a prefixed, known trusted directory. + - Only process regular files and not symbolic links, as some applications may attempt to + read/follow + the symbolic link, leading to arbitrary file read / write vulnerabilities. + + + Example of securely processing an archive file: + ``` + r, err := zip.OpenReader("trusted.zip") + if err != nil { + log.Fatal(err) + } + + // Ensure archive contains only the expected number of files + const expectedFileCount = 10 + if len(r.File) > expectedFileCount { + log.Fatalf("too many files in archive: %d\n", len(r.File)) + } + + // One approach is to sum up all files before attempting to process + // them. + const totalAllowedSize = 1024 * 1024 * 10 // 10MB + var totalSize uint64 + for _, f := range r.File { + totalSize += f.UncompressedSize64 + } + + if totalSize > totalAllowedSize { + log.Fatalf("archive exceeds total allowed size: %d\n", totalSize) + } + + // configure a max size per file allowed + const maxFileSize = 1024 * 1024 // 1 MB + + // set restricted basePath + const basePath = "/var/restricted/" + + // iterate over the files in the archive + for _, f := range r.File { + + // Ensure uncompressed size does not exceed our allowed file size + if f.UncompressedSize64 > maxFileSize { + log.Printf("skipping file as it exceeds maxFileSize: %s\n", f.Name) + continue + } + + // Ensure file is a regular file and not a symbolic link or has other mode type + // bits set + if !f.Mode().IsRegular() { + log.Printf("skipping non regular file: %s\n", f.Name) + continue + } + + // if possible consider not using the name at all, but generating a random id instead. + // If the filename must be used, extract the base name and not folder path information + name := filepath.Base(f.Name) + + // Join the file name to the basePath. + resolvedPath := filepath.Join(basePath, name) + + // Application must still verify the path is prefixed by the basePath + if !strings.HasPrefix(resolvedPath, basePath) { + log.Fatal("path does not start with basePath") + } + + // process / work with file + } + ``` + + If the application must process directory names as well, use the following code: + ``` + // Join the cleaned name to the basePath, note if 'name' starts with `../../` it + // will still allow for traversal, so you _must_ verify the path prefix below + resolvedPath := filepath.Join(basePath, filepath.Clean(name)) + + // Application must still verify the path is prefixed by the basePath + if !strings.HasPrefix(resolvedPath, basePath) { + log.Fatal("path does not start with basePath") + } + + // process / work with file + ``` + metadata: + category: security + cwe: CWE-22 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: | + $CLEAN := $PKG.Clean(...) + ... + if !strings.HasPrefix($CLEAN, "...") {...} + - pattern: | + $CLEAN := $PKG.Clean(...) + ... + if strings.HasPrefix($CLEAN, "...") {...} + - pattern: | + $CLEAN := $PKG.Clean(...) + ... + if strings.HasPrefix($CLEAN, "...") == false {...} + - metavariable-regex: + metavariable: $PKG + regex: ^((file)?path)$ + pattern-sinks: + - pattern: filepath.Join(...) + pattern-sources: + - pattern: zip.OpenReader(...) + - pattern: tar.OpenReader(...) + severity: WARNING + - id: go_http_rule-http-serve + languages: + - go + message: | + Go's `net/http` serve functions may be vulnerable to resource consumption attacks if timeouts + are not properly configured + prior to starting the HTTP server. An adversary may open up thousands of connections but never + complete sending all data, + or never terminate the connections. This may lead to the server no longer accepting new + connections. + + To protect against this style of resource consumption attack, timeouts should be set in the + `net/http` server prior to calling + the listen or serve functions. What this means is that the default `http.ListenAndServe` and + `http.Serve` functions should not + be used in a production setting as they are unable to have timeouts configured. Instead a + custom `http.Server` object must be + created with the timeouts configured. + + Example setting timeouts on a `net/http` server: + ``` + // All values chosen below are dependent on application logic and + // should be tailored per use-case + srv := &http.Server{ + Addr: "localhost:8000", + // ReadHeaderTimeout is the amount of time allowed to read + // request headers. The connection's read deadline is reset + // after reading the headers and the Handler can decide what + // is considered too slow for the body. If ReadHeaderTimeout + // is zero, the value of ReadTimeout is used. If both are + // zero, there is no timeout. + ReadHeaderTimeout: 15 * time.Second, + + // ReadTimeout is the maximum duration for reading the entire + // request, including the body. A zero or negative value means + // there will be no timeout. + // + // Because ReadTimeout does not let Handlers make per-request + // decisions on each request body's acceptable deadline or + // upload rate, most users will prefer to use + // ReadHeaderTimeout. It is valid to use them both. + ReadTimeout: 15 * time.Second, + + // WriteTimeout is the maximum duration before timing out + // writes of the response. It is reset whenever a new + // request's header is read. Like ReadTimeout, it does not + // let Handlers make decisions on a per-request basis. + // A zero or negative value means there will be no timeout. + WriteTimeout: 10 * time.Second, + + // IdleTimeout is the maximum amount of time to wait for the + // next request when keep-alives are enabled. If IdleTimeout + // is zero, the value of ReadTimeout is used. If both are + // zero, there is no timeout. + IdleTimeout: 30 * time.Second, + } + + // For per request timeouts applications can wrap all `http.HandlerFunc(...)` in + // `http.TimeoutHandler`` and specify a timeout, but note the TimeoutHandler does not + // start ticking until all headers have been read. + + // Listen with our custom server with timeouts configured + if err := srv.ListenAndServe(); err != nil { + log.Fatal(err) + } + ``` + For more information on the `http.Server` timeouts, see: https://pkg.go.dev/net/http#Server + + For information on setting request based timeouts, see: + https://pkg.go.dev/net/http#TimeoutHandler + + For more information on the Slowloris attack see: + https://en.wikipedia.org/wiki/Slowloris_(computer_security) + metadata: + category: security + cwe: CWE-770 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Low + shortDescription: Allocation of resources without limits or throttling + patterns: + - pattern-inside: | + import "net/http" + ... + - pattern-either: + - pattern: http.ListenAndServe(...) + - pattern: http.ListenAndServeTLS(...) + - pattern: http.Serve(...) + - pattern: http.ServeTLS(...) + - patterns: + - pattern-not-inside: | + &http.Server{ + ..., + ReadHeaderTimeout: ..., + ..., + } + - pattern-not-inside: | + &http.Server{ + ..., + ReadTimeout: ..., + ..., + } + - pattern-not-inside: | + $S = &http.Server{ + ..., + } + $S.ReadHeaderTimeout = ... + ... + - pattern-not-inside: | + $S = &http.Server{ + ..., + } + $S.ReadTimeout = ... + ... + - pattern: | + &http.Server{ + ..., + } + severity: WARNING + - id: go_injection_rule-ssrf + languages: + - go + message: | + Server-Side-Request-Forgery (SSRF) exploits backend systems that initiate requests to third + parties. + If user input is used in constructing or sending these requests, an attacker could supply + malicious + data to force the request to other systems or modify request data to cause unwanted actions. + + Ensure user input is not used directly in constructing URLs or URIs when initiating requests + to third party + systems from back end systems. Care must also be taken when constructing payloads using user + input. Where + possible restrict to known URIs or payloads. Consider using a server side map where key's are + used to return + URLs such as `https://site/goto?key=1` where `{key: 1, url: 'http://some.url/', key: 2, url: + 'http://...'}`. + + If you must use user supplied input for requesting URLs, it is strongly recommended that the + HTTP client + chosen allows you to customize and block certain IP ranges at the network level. By blocking + RFC 1918 + addresses or other network address ranges, you can limit the severity of a successful SSRF + attack. Care must + also be taken to block certain protocol or address formatting such as IPv6. + + If you can not block address ranges at the client level, you may want to run the HTTP client + as a protected + user, or in a protected network where you can apply IP Table or firewall rules to block access + to dangerous + addresses. Finally, if none of the above protections are available, you could also run a + custom HTTP proxy + and force all requests through it to handle blocking dangerous addresses. + + Example HTTP client that disallows access to loopback and RFC-1918 addresses + ``` + // IsDisallowedIP parses the ip to determine if we should allow the HTTP client to continue + func IsDisallowedIP(hostIP string) bool { + ip := net.ParseIP(hostIP) + return ip.IsMulticast() || ip.IsUnspecified() || ip.IsLoopback() || ip.IsPrivate() + } + + // SafeTransport uses the net.Dial to connect, then if successful check if the resolved + // ip address is disallowed. We do this due to hosts such as localhost.lol being resolvable to + // potentially malicious URLs. We allow connection only for resolution purposes. + func SafeTransport(timeout time.Duration) *http.Transport { + return &http.Transport{ + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + c, err := net.DialTimeout(network, addr, timeout) + if err != nil { + return nil, err + } + ip, _, _ := net.SplitHostPort(c.RemoteAddr().String()) + if IsDisallowedIP(ip) { + return nil, errors.New("ip address is not allowed") + } + return c, err + }, + DialTLS: func(network, addr string) (net.Conn, error) { + dialer := &net.Dialer{Timeout: timeout} + c, err := tls.DialWithDialer(dialer, network, addr, &tls.Config{}) + if err != nil { + return nil, err + } + + ip, _, _ := net.SplitHostPort(c.RemoteAddr().String()) + if IsDisallowedIP(ip) { + return nil, errors.New("ip address is not allowed") + } + + err = c.Handshake() + if err != nil { + return c, err + } + + return c, c.Handshake() + }, + TLSHandshakeTimeout: timeout, + } + } + + func httpRequest(requestUrl string) { + const clientConnectTimeout = time.Second * 10 + httpClient := &http.Client{ + Transport: SafeTransport(clientConnectTimeout), + } + resp, err := httpClient.Get(requestUrl) + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + // work with resp + } + ``` + + For more information on SSRF see OWASP: + https://owasp.org/www-community/attacks/Server_Side_Request_Forgery + metadata: + category: security + cwe: CWE-918 + owasp: + - A1:2017-Injection + - A10:2021-Server-Side Request Forgery + security-severity: Medium + shortDescription: Server Side Request Forgery (SSRF) + mode: taint + pattern-propagators: + - from: $P + pattern: $R := $D.NewDecoder($P) + to: $R + - from: $S + pattern: $S.Decode(&$P) + to: $P + - from: $S + pattern: $S.Decode($P) + to: $P + - from: $B + pattern: $S.Unmarshal($B, &$P) + to: $P + - from: $B + pattern: $S.Unmarshal($B, $P) + to: $P + pattern-sinks: + - pattern: http.Head(...) + - pattern: http.Get(...) + - pattern: http.Post(...) + - pattern: http.PostForm(...) + - pattern: http.NewRequest($METHOD,...) + - pattern: http.DefaultClient.Head(...) + - pattern: http.DefaultClient.Get(...) + - pattern: http.DefaultClient.Post(...) + - pattern: http.DefaultClient.PostForm(...) + - pattern: http.NewRequestWithContext($CONTEXT, $METHOD, ...) + - pattern: ftp.Dial(...) + - pattern: ldap.DialURL(...) + - pattern: smtp.Dial(...) + - pattern: retryablehttp.NewRequest($METHOD, ..., $BODY) + - patterns: + - pattern-inside: | + $C := retryablehttp.NewClient() ... - $INTERM = $STR.format(..., $DATA, ...) + - pattern-either: + - pattern: $C.Get(...) + - pattern: $C.Post(..., $BODYTYPE, $BODY) + - pattern: $C.PostForm(..., $VALS) + - pattern: $C.Head(...) + pattern-sources: + - patterns: + - pattern-not-inside: | + import "testing" ... - django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern-either: + - pattern: os.Stdin + - pattern: os.Getenv(...) + - pattern: | + ($REQ: *http.Request).$ANY + - pattern: | + ($REQ: http.Request).$ANY + - patterns: + - pattern: '($REQ : *http.Request)' + - pattern-inside: | + func $FUNC( $W http.ResponseWriter, $R *http.Request, ...) { + ... + } + severity: WARNING + - id: go_injection_rule-template-injection + languages: + - go + message: | + Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat + user input + as markup or script code. It is important to encode the data depending on the specific context + it + is used in. There are at least six context types: + + - Inside HTML tags `
context 1
` + - Inside attributes: `
` + - Inside event attributes `` + - Inside script blocks: `` + - Unsafe element HTML assignment: `element.innerHTML = "context 5"` + - Inside URLs: `link` + + Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if + user input + is ever output inside of script tags. + + User input that is displayed within the application must be encoded, sanitized or validated + to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be + taken + to not mix server-side templating with client-side templating, as the server-side templating + will + not encode things like {{ 7*7 }} which may execute client-side templating features. + + It is _NOT_ advised to encode user input prior to inserting into a data store. The data will + need to be + encoded depending on context of where it is output. It is much safer to force the displaying + system to + handle the encoding and not attempt to guess how it should be encoded. + + Use of the following template types with user input denotes a security risk: + + - [template.HTML](https://pkg.go.dev/html/template#HTML) + - [template.JS](https://pkg.go.dev/html/template#JS) + - [template.URL](https://pkg.go.dev/html/template#URL) + - [template.HTMLAttr](https://pkg.go.dev/html/template#HTMLAttr) + + Either remove these types from the application or hardcode as const strings prior + to conversion: + ``` + testTemplate, err := template.New("testTemplate").Funcs(template.FuncMap{ + "SafeHTML": func() template.HTML { + const safeHTML = "
hardcoded, safe html
" + return template.HTML(safeHTML) + }, + }).Parse(`{{ SafeHTML }}`) + if err != nil { + log.Fatal(err) + } + + if err := testTemplate.Execute(os.Stdout, nil); err != nil { + log.Fatal(err) + } + ``` + metadata: + category: security + cwe: CWE-79 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + patterns: + - pattern-either: + - patterns: + - pattern: template.HTML($IN) + - pattern-not: template.HTML("...") + - patterns: + - pattern: template.JS($IN) + - pattern-not: template.JS("...") + - patterns: + - pattern: template.URL($IN) + - pattern-not: template.URL("...") + - patterns: + - pattern: template.HTMLAttr($IN) + - pattern-not: template.HTMLAttr("...") + severity: WARNING + - id: go_leak_rule-pprof-endpoint + languages: + - go + message: | + Go has a built in profiling service that is enabled by starting an HTTP server with + `net/http/pprof` imported. The `/debug/pprof` endpoint does not require any + authentication and can be accessed by anonymous users. This profiling endpoint + can leak sensitive information and should not be enabled in production. + + To remediate this, remove the `net/http/pprof` import from the file. + metadata: + category: security + cwe: CWE-489 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Medium + shortDescription: Active debug code (pprof enabled) + patterns: + - pattern-inside: | + import ( + "net/http/pprof" + ) + ... + - pattern-either: + - pattern: http.ListenAndServe(...) + - pattern: http.ListenAndServeTLS(...) + - pattern: http.Serve(...) + - pattern: http.ServeTLS(...) + severity: ERROR + - id: go_memory_rule-integer-overflow + languages: + - go + message: | + Golang's `int` type size depends on the architecture of where the application is running. For + 32-bit systems, `int` is + 32-bit, for 64-bit systems, `int` will be 64-bit. By calling `strconv.Atoi` with a large + number, the integer may overflow + if the `int` return value is type converted into a smaller type (`int32` or `int16`). This + could cause unexpected application + behavior depending on how the resultant value is used. + + Prior to running any type conversion, check that the value returned from `strconv.Atoi` will + fit in the resulting integer. + + Example of checking the return value before type conversion: + ``` + bigValue, _ := strconv.Atoi("32768") + if bigValue > math.MaxInt16 { + log.Fatal("value too large to fit in int16") + } + value := int16(bigValue) + fmt.Println(value) + ``` + + For more information on integer min/max constants see: https://pkg.go.dev/math#pkg-constants + metadata: + category: security + cwe: CWE-190 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Integer overflow or wraparound + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $X, ... := strconv.Atoi(...) + ... + - pattern-either: + - pattern: int32($X) + - pattern: int16($X) + severity: ERROR + - id: go_memory_rule-memoryaliasing + languages: + - go + message: | + Go's `for ... range` statements create an iteration variable for each iteration of the loop. + By taking the address of this iteration variable, the value of the address will be re-used + and always point to the same location in memory. This can have unexpected behavior if the + address is stored or re-used. + + This can be fixed by: + - Not referencing the address of the variable + - Re-assigning the iteration variable to a new variable + - Using the address of the indexed variable + + Example not referencing the address: + ``` + type someStruct struct { + x int + } + + for _, n := range []someStruct{{1}, {2}, {3}, {4}} { + fmt.Printf("%d\n", n.x) + } + ``` + + Example reassigning the iteration variable to a new variable: + ``` + type someStruct struct { + x int + } + + for _, n := range []someStruct{{1}, {2}, {3}, {4}} { + p := n + fmt.Printf("%p\n", &p) + } + ``` + + Example using the address of the indexed variable: + ``` + type someStruct struct { + x int + } + + structData := []someStruct{{1}, {2}, {3}, {4}} + for idx := range structData { + fmt.Printf("%p\n", &structData[idx]) + } + ``` + + For more information on how the `for ... range` statement works see: + https://go.dev/ref/spec#For_statements + metadata: + category: security + cwe: CWE-118 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Info + shortDescription: Incorrect access of indexable resource ('Range Error') + patterns: + - pattern-either: - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseRedirect(..., $STR % $DATA, ...) + for ..., $ARG := range $SLICE { + <... &($ARG) ...> + } - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) + for ..., $ARG := range $SLICE { + <... func() { <... &$ARG ...> } ...> + } - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) + for ..., $ARG := range $SLICE { + <... $X(..., <... &$ARG ...>, ...) ...> + } + - pattern-not: | + for ..., $ARG := range $SLICE { + <... *$ARG ...> + } + - pattern-not-inside: for ..., $ARG := range $SLICE { return ... } + severity: WARNING + - id: go_network_rule-bind-to-all-interfaces + languages: + - go + message: | + Binding to all network interfaces can potentially open up a service to + traffic on unintended interfaces, that may not be properly documented or + secured. By passing "0.0.0.0" as the address to the `Listen` family of functions, + the application will bind to all interfaces. + + Consider passing in the interface ip address through an environment variable, + configuration file, or by determining the primary interface(s) IP address. + + Example getting the IP address from an environment variable `IP_ADDRESS`: + ``` + addr := os.Getenv("IP_ADDRESS") + listener, err := net.Listen("tcp", addr) + if err != nil { + log.Fatal(err) + } + ``` + metadata: + category: security + cwe: CWE-1327 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Low + shortDescription: Binding to an unrestricted IP address + patterns: + - pattern-either: + - pattern: net.Listen(..., "$ADDR") + - pattern: tls.Listen(..., "$ADDR", ...) + - metavariable-regex: + metavariable: $ADDR + regex: ^(0\.0\.0\.0|\[::\])?(:[0-9]*)?$ + severity: WARNING + - id: go_sql_rule-concat-sqli + languages: + - go + message: | + SQL Injection is a critical vulnerability that can lead to data or system compromise. By + dynamically generating SQL query strings, user input may be able to influence the logic of + the SQL statement. This could lead to an adversary accessing information they should + not have access to or in some circumstances, being able to execute OS functionality or code. + + Replace all dynamically generated SQL queries with parameterized queries. In situations where + dynamic queries must be created, never use direct user input, but instead use a map or + dictionary of valid values and resolve them using a user supplied key. + + For example, some database drivers do not allow parameterized queries for `>` or `<` comparison + operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the + user + supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` + values to be used in the construction of the dynamic query. The same goes for other queries + where + column or table names are required but cannot be parameterized. + + Example using parameterized queries with `sql.Query`: + ``` + rows, err := db.Query("SELECT * FROM users WHERE userName = ?", userName) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + // ... process rows + } + ``` + + For more information on SQL Injection see OWASP: + https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-89 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an SQL command ('SQL Injection') + mode: taint + pattern-sinks: + - patterns: + - pattern: $DB.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Exec(Context)?|Query(Context)?|QueryRow(Context)?)$ + pattern-sources: + - patterns: + - pattern: fmt.Sprintf(...) + - pattern-not: | + fmt.Sprintf("...", "...") + - patterns: - pattern: | - $DATA = request.$W + "..." + $X + - pattern-not: | + "..." + "..." + - pattern: | + ($SB : strings.Builder).String() + severity: WARNING + - id: go_subproc_rule-subproc + languages: + - go + message: | + OS command injection is a critical vulnerability that can lead to a full system + compromise as it may allow an adversary to pass in arbitrary commands or arguments + to be executed. + + User input should never be used in constructing commands or command arguments + to functions which execute OS commands. This includes filenames supplied by + user uploads or downloads. + + Ensure your application does not: + + - Use user-supplied information in the process name to execute. + - Use user-supplied information in an OS command execution function which does + not escape shell meta-characters. + - Use user-supplied information in arguments to OS commands. + + The application should have a hardcoded set of arguments that are to be passed + to OS commands. If filenames are being passed to these functions, it is + recommended that a hash of the filename be used instead, or some other unique + identifier. It is strongly recommended that a native library that implements + the same functionality be used instead of using OS system commands, due to the + risk of unknown attacks against third party commands. + + If operating in Windows environments, when specifying the OS command, ensure + the application uses the full path + information, otherwise the OS may attempt to look up which process to execute + and could be vulnerable to untrusted search path vulnerabilities (CWE-426). + + Example of safely executing an OS command: + ``` + userData := []byte("user data") + // create a temporary file in the application specific directory + f, err := ioutil.TempFile("/var/app/restricted", "temp-*.dat") + if err != nil { + log.Fatal(err) + } + + if _, err := f.Write(userData); err != nil { + log.Fatal(err) + } + + if err := f.Close(); err != nil { + log.Fatal(err) + } + + // pass the full path to the binary and the name of the temporary file + // instead of any user supplied filename + out, err := exec.Command("/bin/cat", f.Name()).Output() + if err != nil { + log.Fatal(err) + } + ``` + + For more information on OS command injection, see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-78 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + patterns: + - pattern-either: + - patterns: + - pattern: exec.CommandContext($CTX, $EXE, ...) + - pattern-not: exec.CommandContext($CTX, "...", ...) + - patterns: + - pattern: exec.Command($EXE, ...) + - pattern-not: exec.Command("...", ...) + - patterns: + - pattern: syscall.ForkExec($EXE, ...) + - pattern-not: syscall.ForkExec("...", ...) + - patterns: + - pattern: syscall.StartProcess($EXE, ...) + - pattern-not: syscall.StartProcess("...", ...) + severity: WARNING + - id: go_unsafe_rule-unsafe + languages: + - go + message: | + The `unsafe` package in Go allows low-level access to memory management features. + This includes pointers and direct access to memory. The Go compiler will no longer + be able to enforce type safety when working with the `unsafe` pointer types. + + While powerful, access to these functions can lead to many security related issues + such as: + + - [Buffer overflows](https://owasp.org/www-community/vulnerabilities/Buffer_Overflow) which + can lead to code execution. + - [Use after free](https://owasp.org/www-community/vulnerabilities/Using_freed_memory) which + can lead to code execution. + - [Information/Memory leaks](https://owasp.org/www-community/vulnerabilities/Memory_leak) + which can leak sensitive information, including data which can + defeat other protection mechanisms or cause the system to run out of memory. + + Unless required, all calls to the `unsafe` package should be removed. + metadata: + category: security + cwe: CWE-242 + owasp: + - A9:2017-Using Components with Known Vulnerabilities + - A06:2021-Vulnerable and Outdated Components + security-severity: High + shortDescription: Use of inherently dangerous function (unsafe package) + patterns: + - pattern-either: + - pattern: unsafe.Alignof(...) + - pattern: unsafe.Offsetof(...) + - pattern: unsafe.Sizeof(...) + - pattern: unsafe.Pointer(...) + severity: INFO + - id: java_cookie_rule-CookieInsecure + languages: + - java + message: | + The `Secure` attribute when set to `true` protects the cookie value from being being + transmitted over clear text + communication paths such as HTTP. By enabling this protection, the cookie will only be sent + over HTTPS. + + Example of protecting a `Cookie`: + ``` + // Create an Secure cookie. + Cookie someCookie = new Cookie("SomeCookieName", "SomeValue"); + // Set Secure flag to true + someCookie.setSecure(true); + ``` + + For more information see: + https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/http/cookie#setSecure-boolean- + + Session cookies should be configured with the following security directives: + + - [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) + - [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) + - [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) + metadata: + category: security + cwe: CWE-614 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Low + shortDescription: Sensitive cookie in HTTPS session without 'Secure' attribute + technology: + - java + patterns: + - pattern: | + $X.servlet.http.Cookie $C = new $X.servlet.http.Cookie(..., ...); + ... + ($X.servlet.http.HttpServletResponse $RESP).addCookie($C); + - pattern-not-inside: | + $X.servlet.http.Cookie $C = new $X.servlet.http.Cookie(..., ...); + ... + $C.setSecure(true); + ... + ($X.servlet.http.HttpServletResponse $RESP).addCookie($C); + severity: WARNING + - id: java_cookie_rule-HttpResponseSplitting + languages: + - java + message: | + HTTP Response Splitting is a vulnerability where Carriage Return (CR `\r`) and Line Feed (LF + `\n`) + characters are introduced into an HTTP header from user-supplied input. By injecting the + `\r\n` + character sequence, an adversary could potentially modify how the response is interpreted by + the + client or any downstream caching services. This could allow an adversary to poison the cache + data or execute Cross-Site Scripting (XSS) attacks. + + Some Java application servers such as [Apache Tomcat](https://tomcat.apache.org/) as of version + 8.0, newer versions of Jetty and other servers that implement the [RFC 6265 Standard](https://datatracker.ietf.org/doc/html/rfc6265) will + disallow `\r' and '\n` characters characters from being set in cookies. If your application server does not + automatically provide this functionality, user-supplied input that is used in cookie keys or + values must be validated. + + Example of validating cookies to only allow valid characters: + ``` + // throws an IllegalArgumentException if the provided value contains invalid characters + public void validateRfc6265CookieValue(String value) throws IllegalArgumentException { + char[] chars = value.toCharArray(); + + // iterate over every character + for (int i = 0; i < chars.length; i++) { + char c = chars[i]; + + // check for any characters below 0x21 as well as: '"' ',' ';' '\' and 0x7f. + if (c < 0x21 || c == '"' || c == ',' || c == ';' || c == '\\' || c == 0x7f) { + throw new IllegalArgumentException("Invalid character in cookie detected: + {0}".format(Integer.toString(c))); + } + } + } + ``` + + Alternatively, you could use a string escape package such as + [Apache Commons Text](https://commons.apache.org/proper/commons-text/) to escape the input: + ``` + public String escapeValue(String value) { + return StringEscapeUtils.escapeJava(value); + } + ``` + + For more information on response splitting attacks see OWASP: + https://owasp.org/www-community/attacks/HTTP_Response_Splitting + metadata: + category: security + cwe: CWE-113 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') + technology: + - java + mode: taint + pattern-sanitizers: + - patterns: + - pattern-inside: | + $STR.replaceAll($REPLACER, "..."); ... - $INTERM = f"...{$DATA}..." + - pattern: $STR + - metavariable-regex: + metavariable: $REPLACER + regex: .*\[(?=.*\\r)(?=.*\\n).*\]\+ + - pattern: org.apache.commons.text.StringEscapeUtils.escapeJava($STR); + pattern-sinks: + - pattern: new javax.servlet.http.Cookie("$KEY", ...); + - patterns: + - pattern-inside: | + $C = new javax.servlet.http.Cookie("$KEY", ...); ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W + - pattern: $C.setValue(...); + pattern-sources: + - pattern: (javax.servlet.http.HttpServletRequest $REQ).getParameter(...); + - pattern: (javax.servlet.http.HttpServletRequest $REQ).getParameterNames(); + - pattern: (javax.servlet.http.HttpServletRequest $REQ).getParameterValues(...); + - pattern: (javax.servlet.http.HttpServletRequest $REQ).getParameterMap(); + - pattern: (javax.servlet.http.HttpServletRequest $REQ).getHeader(...); + - pattern: (javax.servlet.http.HttpServletRequest $REQ).getPathInfo(); + severity: WARNING + - id: java_cookie_rule-RequestParamToHeader + languages: + - java + message: | + HTTP Response Splitting is a vulnerability where Carriage Return (CR `\r`) and Line Feed (LF + `\n`) + characters are introduced into an HTTP header from user-supplied input. By injecting the + `\r\n` + character sequence, an adversary could potentially modify how the response is interpreted by + the + client or any down stream caching services. This could allow an adversary to poison the cache + data or execute Cross-Site Scripting (XSS) attacks. + + Some Java application servers such as [Apache Tomcat](https://tomcat.apache.org/) will + automatically encode + characters from being set in response headers as a space `0x20` character. If your application + server does + not automatically provide this functionality, user-supplied input that is used in header keys + or values must be + validated. + + Example of validating headers to only allow valid characters: + ``` + // throws an IllegalArgumentException if the provided value contains invalid characters + public void validateHeader(String value) throws IllegalArgumentException { + char[] chars = value.toCharArray(); + + // iterate over every character + for (int i = 0; i < chars.length; i++) { + char c = chars[i]; + + // check for any characters below 0x21 as well as: '"' ',' ';' '\' and 0x7f. + if (c < 0x21 || c == '"' || c == ',' || c == ';' || c == '\\' || c == 0x7f) { + throw new IllegalArgumentException("Invalid character in cookie detected: + {0}".format(Integer.toString(c))); + } + } + } + ``` + + Alternatively, you could use a string escape package such as + [Apache Commons Text](https://commons.apache.org/proper/commons-text/) to escape the input: + ``` + public String escapeValue(String value) { + return StringEscapeUtils.escapeJava(value); + } + ``` + + For more information on response splitting attacks see OWASP: + https://owasp.org/www-community/attacks/HTTP_Response_Splitting + metadata: + category: security + cwe: CWE-113 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') + technology: + - java + mode: taint + pattern-sanitizers: + - patterns: + - pattern-inside: | + $STR.replaceAll("$INPUT", "..."); ... - django.http.HttpResponseRedirect(..., $STR + $DATA, ...) + - pattern: $STR + - metavariable-regex: + metavariable: $INPUT + regex: .*\[(?=.*\\r)(?=.*\\n).*\]\+ + - pattern: org.apache.commons.text.StringEscapeUtils.unescapeJava(...); + pattern-sinks: + - pattern: ($X.servlet.http.HttpServletResponse $RES).setHeader("$KEY", ...); + - pattern: ($X.servlet.http.HttpServletResponse $RES).addHeader("$KEY", ...); + - pattern: ($X.servlet.http.HttpServletResponseWrapper $WRP).setHeader("$KEY", ...); + - pattern: ($X.servlet.http.HttpServletResponseWrapper $WRP).addHeader("$KEY", ...); + pattern-sources: + - pattern: ($X.servlet.http.HttpServletRequest $REQ).getParameter(...); + - pattern: ($X.servlet.http.HttpServletRequest $REQ).getParameterNames(); + - pattern: ($X.servlet.http.HttpServletRequest $REQ).getParameterValues(...); + - pattern: ($X.servlet.http.HttpServletRequest $REQ).getParameterMap(); + - pattern: ($X.servlet.http.HttpServletRequest $REQ).getHeader(...); + - pattern: ($X.servlet.http.HttpServletRequest $REQ).getPathInfo(); + severity: ERROR + - id: java_cors_rule-PermissiveCORSInjection + languages: + - java + message: | + This application potentially allows user-supplied input into the value of the + `Access-Control-Allow-Origin` response header. This header is part of the + [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) CORS + specification. By allowing user input to specify which domains can communicate with this + server, + an adversary could exploit a weakness in this server to force clients to send credentials (such + as session + identifiers) to the adversary's server. + + For the above attack to work, the application would need to suffer from an additional + vulnerability, + such as Cross-Site Scripting (XSS). + + To remediate this issue, do not use user-supplied information when calling + `HttpServletResponse.setHeader` or `HttpServletResponse.addHeader` + for the `Access-Control-Allow-Origin` header's value. Instead, hardcode the allowed domain(s) + and reference them in a lookup + table: + Example allowing dynamic but safe domains in `Access-Control-Allow-Origin`: + + ``` + // this data should be in the class constructor or taken from a trusted datasource + Map allowedDomains = new HashMap(); + allowedDomains.put("sub1", "sub1.example.com"); + allowedDomains.put("sub2", "sub2.example.com"); + + // extract the allowedDomain parameters value as a key to look up which domain to provide + via the allowedDomains map + // if not found, sets sub1 as the default + String headerValue = allowedDomains.getOrDefault(request.getParameter("allowedDomain"), + allowedDomains.get("sub1")); + + // add the header with our trusted sub1.example.com or sub2.example.com domains. + response.addHeader("Access-Control-Allow-Origin", headerValue); + } + ``` + + For more information on `Access-Control-Allow-Origin` see: + https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin + metadata: + category: security + cwe: CWE-942 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Low + shortDescription: Permissive cross-domain policy with untrusted domains + technology: + - java + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: (HttpServletResponse $RES).setHeader("$HEADER", ...) + - pattern: (HttpServletResponse $RES).addHeader("$HEADER", ...) + - metavariable-regex: + metavariable: $HEADER + regex: (?i)(Access-Control-Allow-Origin) + pattern-sources: + - pattern: (HttpServletRequest $REQ).getParameter(...) + - pattern: (HttpServletRequest $REQ).getHeader(...) + - pattern: (HttpServletRequest $REQ).getPathInfo() + - pattern: (HttpServletRequest $REQ).getQueryString() + - pattern: (HttpServletRequest $REQ).getAttribute(...) + - pattern: (HttpServletRequest $REQ).getSession().getAttribute(...) + - pattern: (HttpServletRequest $REQ).getServletContext().getAttribute(...) + - pattern: (HttpServletRequest $REQ).getParameterValues(...) + - pattern: (HttpServletRequest $REQ).getParameterNames() + - pattern: (HttpServletRequest $REQ).getParameterMap() + severity: ERROR + - id: java_crypto_rule-BlowfishKeySize + languages: + - java + message: | + The Blowfish encryption algorithm was meant as a drop-in replacement for DES and was created in + 1993. Smaller key sizes may make the ciphertext vulnerable to [birthday + attacks](https://en.wikipedia.org/wiki/Birthday_attack). While no known attacks against + Blowfish + exist, it should never be used to encrypt files over 4GB in size. If possible consider + using AES as the instance of `KeyGenerator` instead of Blowfish. + + To remediate the small key size, pass a value such as 256 to the `KeyGenerator.init(keySize)` + method. + + Example setting a larger key size and changing to `KeyGenerator` to AES: + ``` + public static void aesKeyGenerator() throws java.security.NoSuchAlgorithmException { + // Use the AES algorithm for key generation + KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); + + // Set the key size here + keyGenerator.init(256); + + // get the raw bytes of the key + byte[] key = keyGenerator.generateKey().getEncoded(); + + // pass the key bytes to create a SecretKeySpec + SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); + } + ``` + + Example setting a larger key size for Blowfish: + ``` + public static void blowFishKeyGenerator() throws java.security.NoSuchAlgorithmException { + // Use the Blowfish algorithm for key generation + KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish"); + + // Set the key size here + keyGenerator.init(256); + + // get the raw bytes of the key + byte[] key = keyGenerator.generateKey().getEncoded(); + + // pass the key bytes to create a SecretKeySpec + SecretKeySpec secretKeySpec = new SecretKeySpec(key, "Blowfish"); + } + ``` + + For more information on Java Cryptography see: + https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html + metadata: + category: security + cwe: CWE-326 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Inadequate encryption strength + technology: + - java + patterns: + - pattern-inside: | + $KEYGEN = javax.crypto.KeyGenerator.getInstance("Blowfish", ...); + ... + - pattern: $KEYGEN.init($KEY_SIZE) + - metavariable-comparison: + comparison: int($KEY_SIZE) < 128 + metavariable: $KEY_SIZE + severity: WARNING + - id: java_crypto_rule-CipherDESInsecure + languages: + - java + message: | + DES, TripleDES and RC2 are all considered broken or insecure cryptographic algorithms. + Newer algorithms apply message integrity to validate ciphertext has not been tampered + with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the + alternatives such as `AES-256-GCM`. + + For older applications that don't have support for `ChaCha20Poly1305`, + `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Example using `ChaCha20Poly1305`: + ``` + public encrypt() throws Exception { + chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); + } + + public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { + // Use DRBG according to + http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf + return SecureRandom.getInstance("DRBG", + // Security strength in bits (default is 128) + DrbgParameters.instantiation(256, + // Set prediction resistance and re-seeding + DrbgParameters.Capability.PR_AND_RESEED, + // Set the personalization string (optional, not necessary) + "some_personalization_string".getBytes() + ) + ); + } + + public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws + NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create a ChaCha20-Poly1305 cipher instance + Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); + // Create our parameterSpec using our ivKey + AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey); + // Create a SecretKeySpec using our secretKey + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); + // Initialize and return the cipher for the provided mode + chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); + return chaChaCipher; + } + + public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create secretKey + byte[] secretKey = new byte[32]; + random.nextBytes(secretKey); + // Create an IV Key + byte[] ivKey = new byte[12]; + random.nextBytes(ivKey); + + // Create a chaCha encryption cipher instance + Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey); + + // Encrypt the text using ChaCha20Poly1305 + byte[] cipherText = null; + try { + cipherText = chaChaEncryptor.doFinal(plainText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to encrypt text"); + return; + } + System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); + + // Create a chaCha decryption cipher instance + Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey); + + // Decrypt the text + byte[] decryptedText = null; + try { + decryptedText = chaChaDecryptor.doFinal(cipherText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to decrypt text"); + return; + } + System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); + } + ``` + + For more information on Java Cryptography see: + https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html + metadata: + category: security + cwe: CWE-326 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Inadequate encryption strength + technology: + - java + patterns: + - pattern-either: + - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA + $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., request.$W, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) - - pattern: return django.http.HttpResponseRedirect(..., request.$W, ...) - - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W, ...) - - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) + javax.crypto.Cipher.getInstance($PROP, ...); - metavariable-regex: - metavariable: $W - regex: (?!get_full_path) + metavariable: $ALG + regex: ^DES(/|$) severity: WARNING - - id: python.django.security.injection.path-traversal.path-traversal-open.path-traversal-open + - id: java_crypto_rule-CipherDESedeInsecure languages: - - python - message: Found request data in a call to 'open'. Ensure the request data is validated or sanitized, otherwise it could result in path traversal attacks and therefore sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or the pathlib library. + - java + message: | + DES, TripleDES and RC2 are all considered broken or insecure cryptographic algorithms. + Newer algorithms apply message integrity to validate ciphertext has not been tampered + with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the + alternatives such as `AES-256-GCM`. + + For older applications that don't have support for `ChaCha20Poly1305`, + `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Example using `ChaCha20Poly1305`: + ``` + public encrypt() throws Exception { + chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); + } + + public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { + // Use DRBG according to + http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf + return SecureRandom.getInstance("DRBG", + // Security strength in bits (default is 128) + DrbgParameters.instantiation(256, + // Set prediction resistance and re-seeding + DrbgParameters.Capability.PR_AND_RESEED, + // Set the personalization string (optional, not necessary) + "some_personalization_string".getBytes() + ) + ); + } + + public Cipher getChaCha20Poly1305(int mode, byte[] nonceKey, byte[] secretKey) throws + NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create a ChaCha20-Poly1305 cipher instance + Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); + // Create our parameterSpec using our nonceKey + AlgorithmParameterSpec parameterSpec = new IvParameterSpec(nonceKey); + // Create a SecretKeySpec using our secretKey + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); + // Initialize and return the cipher for the provided mode + chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); + return chaChaCipher; + } + + public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create secretKey + byte[] secretKey = new byte[32]; + random.nextBytes(secretKey); + // Create an IV nonceKey + byte[] nonceKey = new byte[12]; + random.nextBytes(nonceKey); + // Create a chaCha encryption cipher instance + Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, nonceKey, secretKey); + // Encrypt the text using ChaCha20Poly1305 + byte[] cipherText = null; + try { + cipherText = chaChaEncryptor.doFinal(plainText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to encrypt text"); + return; + } + System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); + // Create a chaCha decryption cipher instance + Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, nonceKey, secretKey); + // Decrypt the text + byte[] decryptedText = null; + try { + decryptedText = chaChaDecryptor.doFinal(cipherText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to decrypt text"); + return; + } + System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); + } + ``` + + For more information on Java Cryptography see: + https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-327 owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - subcategory: - - vuln + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm technology: - - django + - java patterns: - - pattern-inside: | - def $FUNC(...): - ... - pattern-either: - - pattern: open(..., request.$W.get(...), ...) - - pattern: open(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: open(..., $S % request.$W.get(...), ...) - - pattern: open(..., f"...{request.$W.get(...)}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - open(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W.get(...) - ... - open(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W.get(...) - ... - open(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W.get(...) - ... - open(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W.get(...) - ... - open(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: $A = open(..., request.$W.get(...), ...) - - pattern: $A = open(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $A = open(..., $S % request.$W.get(...), ...) - - pattern: $A = open(..., f"...{request.$W.get(...)}...", ...) - - pattern: return open(..., request.$W.get(...), ...) - - pattern: return open(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: return open(..., $S % request.$W.get(...), ...) - - pattern: return open(..., f"...{request.$W.get(...)}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - with open(..., $DATA, ...) as $FD: - ... - - pattern: open(..., request.$W(...), ...) - - pattern: open(..., $S.format(..., request.$W(...), ...), ...) - - pattern: open(..., $S % request.$W(...), ...) - - pattern: open(..., f"...{request.$W(...)}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - open(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W(...) - ... - open(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W(...) - ... - open(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W(...) - ... - open(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W(...) - ... - open(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: $A = open(..., request.$W(...), ...) - - pattern: $A = open(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $A = open(..., $S % request.$W(...), ...) - - pattern: $A = open(..., f"...{request.$W(...)}...", ...) - - pattern: return open(..., request.$W(...), ...) - - pattern: return open(..., $S.format(..., request.$W(...), ...), ...) - - pattern: return open(..., $S % request.$W(...), ...) - - pattern: return open(..., f"...{request.$W(...)}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - with open(..., $DATA, ...) as $FD: - ... - - pattern: open(..., request.$W[...], ...) - - pattern: open(..., $S.format(..., request.$W[...], ...), ...) - - pattern: open(..., $S % request.$W[...], ...) - - pattern: open(..., f"...{request.$W[...]}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - open(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W[...] - ... - open(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W[...] - ... - open(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W[...] - ... - open(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W[...] - ... - open(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: $A = open(..., request.$W[...], ...) - - pattern: $A = open(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $A = open(..., $S % request.$W[...], ...) - - pattern: $A = open(..., f"...{request.$W[...]}...", ...) - - pattern: return open(..., request.$W[...], ...) - - pattern: return open(..., $S.format(..., request.$W[...], ...), ...) - - pattern: return open(..., $S % request.$W[...], ...) - - pattern: return open(..., f"...{request.$W[...]}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - with open(..., $DATA, ...) as $FD: - ... - - pattern: open(..., request.$W, ...) - - pattern: open(..., $S.format(..., request.$W, ...), ...) - - pattern: open(..., $S % request.$W, ...) - - pattern: open(..., f"...{request.$W}...", ...) - - pattern: | - $DATA = request.$W - ... - open(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W - ... - open(..., $STR.format(..., $DATA, ...), ...) + - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W - ... - open(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W - ... - open(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W + $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); ... - open(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - open(..., $INTERM, ...) + javax.crypto.Cipher.getInstance($PROP, ...); + - metavariable-regex: + metavariable: $ALG + regex: DESede(/|$) + severity: WARNING + - id: java_crypto_rule-CipherECBMode + languages: + - java + message: | + Cryptographic algorithms provide many different modes of operation, only some of which provide + message integrity. Without message integrity it could be possible for an adversary to attempt + to tamper with the ciphertext which could lead to compromising the encryption key. Newer + algorithms + apply message integrity to validate ciphertext has not been tampered with. + + Instead of using an algorithm that requires configuring a cipher mode, an algorithm + that has built-in message integrity should be used. Consider using `ChaCha20Poly1305` or + `AES-256-GCM` instead. + + For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is + recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Example using `ChaCha20Poly1305`: + ``` + public encrypt() throws Exception { + chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); + } + + public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { + // Use DRBG according to + http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf + return SecureRandom.getInstance("DRBG", + // Security strength in bits (default is 128) + DrbgParameters.instantiation(256, + // Set prediction resistance and re-seeding + DrbgParameters.Capability.PR_AND_RESEED, + // Set the personalization string (optional, not necessary) + "some_personalization_string".getBytes() + ) + ); + } + + public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws + NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create a ChaCha20-Poly1305 cipher instance + Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); + // Create our parameterSpec using our ivKey + AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey); + // Create a SecretKeySpec using our secretKey + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); + // Initialize and return the cipher for the provided mode + chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); + return chaChaCipher; + } + + public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create secretKey + byte[] secretKey = new byte[32]; + random.nextBytes(secretKey); + // Create an IV Key + byte[] ivKey = new byte[12]; + random.nextBytes(ivKey); + + // Create a chaCha encryption cipher instance + Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey); + + // Encrypt the text using ChaCha20Poly1305 + byte[] cipherText = null; + try { + cipherText = chaChaEncryptor.doFinal(plainText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to encrypt text"); + return; + } + System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); + + // Create a chaCha decryption cipher instance + Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey); + + // Decrypt the text + byte[] decryptedText = null; + try { + decryptedText = chaChaDecryptor.doFinal(cipherText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to decrypt text"); + return; + } + System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); + } + ``` + + For more information on Java Cryptography see: + https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + technology: + - java + patterns: + - pattern-either: + - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) - pattern: | - $DATA = request.$W + $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); ... - $INTERM = $STR + $DATA + javax.crypto.Cipher.getInstance($PROP, ...); + - metavariable-comparison: + comparison: | + $ALG in ( + "AES/ECB/NoPadding" "AES/ECB/PKCS5Padding" + "DES/ECB/NoPadding" "DES/ECB/PKCS5Padding" + "DESede/ECB/NoPadding" "DESede/ECB/PKCS5Padding" + "AES/ECB/PKCS7Padding" + ) + metavariable: $ALG + severity: ERROR + - id: java_crypto_rule-CipherIntegrity + languages: + - java + message: | + Cryptographic algorithms provide many different modes of operation, only some of which provide + message integrity. Without message integrity it could be possible for an adversary to attempt + to tamper with the ciphertext which could lead to compromising the encryption key. Newer + algorithms + apply message integrity to validate ciphertext has not been tampered with. + + Instead of using an algorithm that requires configuring a cipher mode, an algorithm + that has built-in message integrity should be used. Consider using `ChaCha20Poly1305` or + `AES-256-GCM` instead. + + For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is + recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Example using `ChaCha20Poly1305`: + ``` + public encrypt() throws Exception { + chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); + } + + public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { + // Use DRBG according to + http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf + return SecureRandom.getInstance("DRBG", + // Security strength in bits (default is 128) + DrbgParameters.instantiation(256, + // Set prediction resistance and re-seeding + DrbgParameters.Capability.PR_AND_RESEED, + // Set the personalization string (optional, not necessary) + "some_personalization_string".getBytes() + ) + ); + } + + public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws + NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create a ChaCha20-Poly1305 cipher instance + Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); + // Create our parameterSpec using our ivKey + AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey); + // Create a SecretKeySpec using our secretKey + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); + // Initialize and return the cipher for the provided mode + chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); + return chaChaCipher; + } + + public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create secretKey + byte[] secretKey = new byte[32]; + random.nextBytes(secretKey); + // Create an IV Key + byte[] ivKey = new byte[12]; + random.nextBytes(ivKey); + + // Create a chaCha encryption cipher instance + Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey); + + // Encrypt the text using ChaCha20Poly1305 + byte[] cipherText = null; + try { + cipherText = chaChaEncryptor.doFinal(plainText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to encrypt text"); + return; + } + System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); + + // Create a chaCha decryption cipher instance + Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey); + + // Decrypt the text + byte[] decryptedText = null; + try { + decryptedText = chaChaDecryptor.doFinal(cipherText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to decrypt text"); + return; + } + System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); + } + ``` + + For more information on Java Cryptography see: + https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + technology: + - java + patterns: + - pattern-either: + - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) + - pattern: | + $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: $A = open(..., request.$W, ...) - - pattern: $A = open(..., $S.format(..., request.$W, ...), ...) - - pattern: $A = open(..., $S % request.$W, ...) - - pattern: $A = open(..., f"...{request.$W}...", ...) - - pattern: return open(..., request.$W, ...) - - pattern: return open(..., $S.format(..., request.$W, ...), ...) - - pattern: return open(..., $S % request.$W, ...) - - pattern: return open(..., f"...{request.$W}...", ...) + javax.crypto.Cipher.getInstance($PROP, ...); + - metavariable-comparison: + comparison: | + $ALG in ( + "AES" + "AES/CBC/NoPadding" "AES/CBC/PKCS5Padding" "AES/CBC/PKCS7Padding" + "AES/CFB/NoPadding" "AES/CFB/PKCS5Padding" "AES/CFB/PKCS7Padding" + "AES/CTR/NoPadding" + "AES/ECB/NoPadding" "AES/ECB/PKCS5Padding" "AES/ECB/PKCS7Padding" + "AES/OFB/NoPadding" "AES/OFB/PKCS5Padding" "AES/OFB/PKCS7Padding" + "ARCFOUR" + "DES" + "DES/CBC/NoPadding" "DES/CBC/PKCS5Padding" + "DES/ECB/NoPadding" "DES/ECB/PKCS5Padding" + "DESede" + "DESede/CBC/NoPadding" "DESede/CBC/PKCS5Padding" + "DESede/ECB/NoPadding" "DESede/ECB/PKCS5Padding" + "RC4" + ) + metavariable: $ALG + severity: ERROR + - id: java_crypto_rule-CipherPaddingOracle + languages: + - java + message: | + Cryptographic block ciphers can be configured to pad individual blocks if there is not enough + input data to match the size of the block. This specific mode of CBC used in combination with + PKCS5Padding is susceptible to padding oracle attacks. An adversary could potentially decrypt + the message if the system exposed the difference between plaintext with invalid padding or + valid padding. The distinction between valid and invalid padding is usually revealed through + distinct error messages being returned for each condition. + + Consider switching to a more secure cipher that doesn't require padding and builds in message + authentication integrity directly into the algorithm. + + Consider using `ChaCha20Poly1305` or + `AES-256-GCM` instead. + + For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is + recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Example using `ChaCha20Poly1305`: + ``` + public encrypt() throws Exception { + chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); + } + + public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { + // Use DRBG according to + http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf + return SecureRandom.getInstance("DRBG", + // Security strength in bits (default is 128) + DrbgParameters.instantiation(256, + // Set prediction resistance and re-seeding + DrbgParameters.Capability.PR_AND_RESEED, + // Set the personalization string (optional, not necessary) + "some_personalization_string".getBytes() + ) + ); + } + + public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws + NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create a ChaCha20-Poly1305 cipher instance + Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); + // Create our parameterSpec using our ivKey + AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey); + // Create a SecretKeySpec using our secretKey + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); + // Initialize and return the cipher for the provided mode + chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); + return chaChaCipher; + } + + public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create secretKey + byte[] secretKey = new byte[32]; + random.nextBytes(secretKey); + // Create an IV Key + byte[] ivKey = new byte[12]; + random.nextBytes(ivKey); + + // Create a chaCha encryption cipher instance + Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey); + + // Encrypt the text using ChaCha20Poly1305 + byte[] cipherText = null; + try { + cipherText = chaChaEncryptor.doFinal(plainText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to encrypt text"); + return; + } + System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); + + // Create a chaCha decryption cipher instance + Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey); + + // Decrypt the text + byte[] decryptedText = null; + try { + decryptedText = chaChaDecryptor.doFinal(cipherText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to decrypt text"); + return; + } + System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); + } + ``` + + For more information on padding oracle attacks see: + https://en.wikipedia.org/wiki/Padding_oracle_attack + + For more information on Java Cryptography see: + https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + technology: + - java + patterns: + - pattern-either: + - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) - pattern: | - $DATA = request.$W + $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); ... - with open(..., $DATA, ...) as $FD: - ... + javax.crypto.Cipher.getInstance($PROP, ...); + - metavariable-comparison: + comparison: | + $ALG in ( + "AES/CBC/PKCS5Padding" "DES/CBC/PKCS5Padding" "DESede/CBC/PKCS5Padding" "AES/CBC/PKCS7Padding" + ) + metavariable: $ALG + severity: ERROR + - id: java_crypto_rule-CustomMessageDigest + languages: + - java + message: | + The application was found implementing a custom `java.security.MessageDigest`. It is + strongly recommended that a standard Digest algorithm be chosen instead as implementing + a digest by hand is error-prone. The National Institute of Standards and + Technology (NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or + SHA-512/256. + + Example of creating a SHA-384 hash: + ``` + // Create a MessageDigest using the SHA-384 algorithm + MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384"); + // Call update with your data + sha384Digest.update(input); + // Only call digest once all data has been fed into the update sha384digest instance + byte[] output = sha384Digest.digest(); + // output base64 encoded version of the hash + System.out.println("hash: " + Base64.getEncoder().encodeToString(output)); + ``` + metadata: + category: security + cwe: CWE-327 + owasp: + - A6:2017-Security Misconfiguration + - A04:2021-Insecure Design + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + technology: + - java + patterns: + - pattern: | + class $CLAZZ extends java.security.MessageDigest { + ... + } severity: WARNING - - id: python.django.security.injection.raw-html-format.raw-html-format + - id: java_crypto_rule-HazelcastSymmetricEncryption languages: - - python - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates (`django.shortcuts.render`) which will safely render HTML instead. + - java + message: | + The network communications for Hazelcast is configured to use a deprecated symmetric cipher. + Consider using TLS/SSL when establishing communications across the Hazelcast cluster. + + For more information on configuring TLS/SSL for Hazelcast see: + https://docs.hazelcast.com/imdg/4.2/security/tls-ssl metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + cwe: CWE-326 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.2/topics/http/shortcuts/#render - - https://docs.djangoproject.com/en/3.2/topics/security/#cross-site-scripting-xss-protection - subcategory: - - vuln + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Inadequate encryption strength technology: - - django - mode: taint - pattern-sanitizers: - - pattern: django.utils.html.escape(...) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: '"$HTMLSTR" % ...' - - pattern: '"$HTMLSTR".format(...)' - - pattern: '"$HTMLSTR" + ...' - - pattern: f"$HTMLSTR{...}..." - - patterns: - - pattern-inside: | - $HTML = "$HTMLSTR" - ... - - pattern-either: - - pattern: $HTML % ... - - pattern: $HTML.format(...) - - pattern: $HTML + ... - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - pattern-sources: - - patterns: - - pattern: request.$ANYTHING - - pattern-not: request.build_absolute_uri + - java + patterns: + - pattern: new com.hazelcast.config.SymmetricEncryptionConfig() severity: WARNING - - id: python.django.security.injection.reflected-data-httpresponse.reflected-data-httpresponse + - id: java_crypto_rule-InsufficientKeySizeRsa languages: - - python - message: Found user-controlled request data passed into HttpResponse. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed. + - java + message: | + The application is generating an RSA key that is less than the recommended 2048 bits. + The National Institute of Standards and Technology (NIST) deprecated signing Digital + Certificates that contained RSA Public Keys of 1024 bits in December 2010. While + 1024-bit RSA keys have not been factored yet, advances in compute may make it possible + in the near future. + + Consider upgrading to the newer asymmetric algorithm such as `Ed25519` which handles + the complexities of generating key pairs and choosing correct key sizes for you: + ``` + public static KeyPair generateEd25519() throws NoSuchAlgorithmException { + // Choose Ed25519 for KeyPairGenerator Instance + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Ed25519"); + // Generate a KeyPair and return + return keyPairGenerator.generateKeyPair(); + } + ``` + + Otherwise use a key size greater than 2048 when generating RSA keys: + ``` + public static KeyPair generateRSA() throws NoSuchAlgorithmException { + // Choose RSA for KeyPairGenerator Instance + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + // Initialize with 2048 key size + keyPairGenerator.initialize(2048); + // Generate a KeyPair and return + return keyPairGenerator.generateKeyPair(); + } + ``` + + For more information on Ed25519 see: http://ed25519.cr.yp.to/ + + For more information on Java Cryptography see: + https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-326 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss - subcategory: - - vuln + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Inadequate encryption strength + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $GEN = KeyPairGenerator.getInstance($ALG, ...); + ... + - pattern-either: + - pattern: $VAR.initialize($SIZE, ...); + - pattern: new java.security.spec.RSAKeyGenParameterSpec($SIZE,...); + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE + - metavariable-regex: + metavariable: $ALG + regex: '"(RSA|DSA)"' + severity: WARNING + - id: java_crypto_rule-NullCipher + languages: + - java + message: | + The application was found creating a `NullCipher` instance. `NullCipher` implements the + `Cipher` interface by returning ciphertext identical to the supplied plaintext. This means + any data passed to the `doFinal(...)` or `update(...)` methods will not actually encrypt + the input. + + Remove the NullCipher reference and replace with a legitimate `Cipher` instance such as + `ChaCha20-Poly1305` + + Example using `ChaCha20Poly1305`: + ``` + public encrypt() throws Exception { + chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); + } + + public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { + // Use DRBG according to + http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf + return SecureRandom.getInstance("DRBG", + // Security strength in bits (default is 128) + DrbgParameters.instantiation(256, + // Set prediction resistance and re-seeding + DrbgParameters.Capability.PR_AND_RESEED, + // Set the personalization string (optional, not necessary) + "some_personalization_string".getBytes() + ) + ); + } + + public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws + NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create a ChaCha20-Poly1305 cipher instance + Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); + // Create our parameterSpec using our ivKey + AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey); + // Create a SecretKeySpec using our secretKey + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); + // Initialize and return the cipher for the provided mode + chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); + return chaChaCipher; + } + + public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { + // Get a DRBG random number generator instance + SecureRandom random = getSecureRandomDRBG(); + // Create secretKey + byte[] secretKey = new byte[32]; + random.nextBytes(secretKey); + // Create an IV Key + byte[] ivKey = new byte[12]; + random.nextBytes(ivKey); + + // Create a chaCha encryption cipher instance + Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey); + + // Encrypt the text using ChaCha20Poly1305 + byte[] cipherText = null; + try { + cipherText = chaChaEncryptor.doFinal(plainText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to encrypt text"); + return; + } + System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); + + // Create a chaCha decryption cipher instance + Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey); + + // Decrypt the text + byte[] decryptedText = null; + try { + decryptedText = chaChaDecryptor.doFinal(cipherText); + } catch (IllegalBlockSizeException | BadPaddingException e) { + System.out.println("failed to decrypt text"); + return; + } + System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); + } + ``` + + For more information on Java Cryptography see: + https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm technology: - - django + - java + pattern: new javax.crypto.NullCipher() + severity: WARNING + - id: java_crypto_rule-RsaNoPadding + languages: + - java + message: | + The software uses the RSA algorithm but does not incorporate Optimal Asymmetric + Encryption Padding (OAEP). By not enabling padding, the algorithm maybe vulnerable + to [chosen plaintext attacks](https://en.wikipedia.org/wiki/Chosen-plaintext_attack). + + To enable OAEP mode, pass `RSA/ECB/OAEPWithSHA-256AndMGF1Padding` to the `Cipher.getInstance` + method. + + Example encrypting and decrypting a message using RSA with OAEP: + ``` + public static void encryptWithRSA() throws InvalidKeyException, NoSuchAlgorithmException, + NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { + // Generate an RSA Public and Private Key Pair + KeyPair keyPair = generateRSAKeys(); + // Create a Cipher instance using RSA, ECB with OAEP + Cipher rsaEncryptor = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); + // Initialize to ENCRYPT_MODE with the public key + rsaEncryptor.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); + // Encrypt our secret message + byte[] cipherText = rsaEncryptor.doFinal("Some secret + message".getBytes(StandardCharsets.UTF_8)); + + // Create a Cipher instance using RSA, ECB with OAEP + Cipher rsaDecryptor = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); + // Initialize to DECRYPT_MODE with the private key + rsaDecryptor.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); + // Decrypt the secret message + byte[] plainText = rsaDecryptor.doFinal(cipherText); + // Debug output + System.out.println(new String(plainText)); + } + ``` + More information on Optimal asymmetric encryption padding: + https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding + + For more information on Java Cryptography see: + https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html + metadata: + category: security + cwe: CWE-780 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of RSA algorithm without OAEP patterns: - - pattern-inside: | - def $FUNC(...): - ... - pattern-either: - - pattern: django.http.HttpResponse(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: django.http.HttpResponse(..., $S % request.$W.get(...), ...) - - pattern: django.http.HttpResponse(..., f"...{request.$W.get(...)}...", ...) - - pattern: django.http.HttpResponse(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponse(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponse(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponse(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponse(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponse(..., request.$W.get(...), ...) - - pattern: return django.http.HttpResponse(..., request.$W.get(...), ...) - - pattern: django.http.HttpResponse(..., $S.format(..., request.$W(...), ...), ...) - - pattern: django.http.HttpResponse(..., $S % request.$W(...), ...) - - pattern: django.http.HttpResponse(..., f"...{request.$W(...)}...", ...) - - pattern: django.http.HttpResponse(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponse(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponse(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponse(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponse(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponse(..., request.$W(...), ...) - - pattern: return django.http.HttpResponse(..., request.$W(...), ...) - - pattern: django.http.HttpResponse(..., $S.format(..., request.$W[...], ...), ...) - - pattern: django.http.HttpResponse(..., $S % request.$W[...], ...) - - pattern: django.http.HttpResponse(..., f"...{request.$W[...]}...", ...) - - pattern: django.http.HttpResponse(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponse(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponse(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponse(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponse(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponse(..., request.$W[...], ...) - - pattern: return django.http.HttpResponse(..., request.$W[...], ...) - - pattern: django.http.HttpResponse(..., $S.format(..., request.$W, ...), ...) - - pattern: django.http.HttpResponse(..., $S % request.$W, ...) - - pattern: django.http.HttpResponse(..., f"...{request.$W}...", ...) - - pattern: django.http.HttpResponse(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponse(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponse(..., $STR % $DATA, ...) + - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA + $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); ... - django.http.HttpResponse(..., $INTERM, ...) + javax.crypto.Cipher.getInstance($PROP, ...); + - metavariable-regex: + metavariable: $ALG + regex: (?i)^RSA/.*NoPadding$ + severity: WARNING + - id: java_crypto_rule-WeakMessageDigest + languages: + - java + message: | + The application was found using an insecure or risky digest or signature algorithm. Both MD5 + and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. + strongly recommended that a standard Digest algorithm be chosen instead as implementing + a digest by hand is error-prone. + + Example of creating a SHA-384 hash: + ``` + // Create a MessageDigest using the SHA-384 algorithm + MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384"); + // Call update with your data + sha384Digest.update(input); + // Only call digest once all data has been fed into the update sha384digest instance + byte[] output = sha384Digest.digest(); + // output base64 encoded version of the hash + System.out.println("hash: " + Base64.getEncoder().encodeToString(output)); + ``` + + For more information on secure password storage see OWASP: + https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-327 + owasp: + - A6:2017-Security Misconfiguration + - A04:2021-Insecure Design + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm (SHA1/MD5) + technology: + - java + patterns: + - pattern-either: + - pattern: java.security.MessageDigest.getInstance("$ALG", ...) + - pattern: java.security.Signature.getInstance("$ALG", ...) - pattern: | - $DATA = request.$W + $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); ... - django.http.HttpResponse(..., f"...{$DATA}...", ...) - - pattern: $A = django.http.HttpResponse(..., request.$W, ...) + java.security.MessageDigest.getInstance("$ALG", ...); - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA + $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); ... - $A = django.http.HttpResponse(..., $INTERM, ...) - - pattern: return django.http.HttpResponse(..., request.$W, ...) + java.security.Signature.getInstance("$ALG", ...); + - metavariable-comparison: + comparison: | + $ALG in ( + "MD2" "MD4" "MD5" "MD5withRSA" + "SHA-1" "SHA1withRSA" "SHA1withDSA" + ) + metavariable: $ALG + severity: WARNING + - id: java_crypto_rule-WeakTLSProtocol-DefaultHttpClient + languages: + - java + message: | + The `org.apache.http.impl.client.DefaultHttpClient` does not verify the hostnames upon connection. + + This allows for an adversary who is in between the application and the target host to intercept + potentially sensitive information or transmit malicious data. + + Do not use the `org.apache.http.impl.client.DefaultHttpClient();` as it is deprecated. Instead + use the new `java.net.http.HttpClient` that was introduced in Java 9. + + Example connecting to a host that will automatically do TLS validation: + ``` + // Create a new java.net.http.HttpClient + HttpClient httpClient = HttpClient.newHttpClient(); + // Create a HttpRequest builder + HttpRequest request = HttpRequest.newBuilder() + // Create a URI for a website which requires TLS + .uri(URI.create("https://www.example.com/")) + // Build the request + .build(); + + // Use the httpClient to send the request and use an HttpResponse.BodyHandlers String type + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + // Debug print + System.out.println(response); + ``` + metadata: + category: security + cwe: CWE-295 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Improper certificate validation + patterns: + - pattern: new org.apache.http.impl.client.DefaultHttpClient(); + severity: WARNING + - id: java_crypto_rule-WeakTLSProtocol-SSLContext + languages: + - java + message: | + Avoid initializing SSLContext with insecure protocols like `SSL`, `SSLv2`, or `SSLv3`. + These protocols are outdated and do not validate certificates by default. Additionally, + these older `SSL` versions have many known security issues. + + Instead, use secure protocols like `TLSv1.2` or `TLSv1.3`. + ``` + SSLContext context = SSLContext.getInstance("TLSv1.3"); + ``` + For more information on see OWASP: + - https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/09-Testing_for_Weak_Cryptography/01-Testing_for_Weak_SSL_TLS_Ciphers_Insufficient_Transport_Layer_Protection + metadata: + category: security + cwe: CWE-295 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Improper certificate validation + patterns: + - pattern-either: + - pattern: javax.net.ssl.SSLContext.getInstance("$PROTO", ...) - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." + $PROP = (java.util.Properties $P).getProperty(..., "$PROTO"); ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W + javax.net.ssl.SSLContext.getInstance($PROP, ...); + - metavariable-comparison: + comparison: | + $PROTO not in ("TLS" "TLSv1.2" "TLSv1.3" "DTLSv1.2" "DTLSv1.3") + metavariable: $PROTO + severity: WARNING + - id: java_crypto_rule-WeakTLSProtocolVersion + languages: + - java + message: | + The application was found enabling insecure TLS protocol versions. When enabling protocol + versions for an `SSLContext`, only the following versions should be allowed: + - TLSv1.2 + - TLSv1.3 + - DTLSv1.2 + - DTLSv1.3 + + To mitigate potential security risks, it is strongly advised to enforce TLS 1.2 as the minimum + protocol version and disallow older versions such as TLS 1.0. Do note that newer versions of + Java do not even support TLS 1.0 and will throw `NoSuchAlgorithmException`. Versions of TLS + prior to 1.2 could expose the connection to downgrade attacks, where an adversary intercepts + the + connection and alters the requested protocol version to be a less secure one. + + In many scenarios, relying on the default system configuration does not meet compliance + standards. This is due to the application being deployed across diverse systems with varying + configurations and Java versions. While the default value may be secure on modern and + up-to-date systems, it may not hold true for older systems. Consequently, it is highly + recommended to explicitly define a secure configuration in all cases. + + Example configuring an SSLContext with TLSv1.2: + ``` + // Create an SSLContext with TLSv1.2 explicitly + SSLContext tlsContext = SSLContext.getInstance("TLSv1.2"); // or TLSv1.3, DTLSv1.2, DTLSv1.3 + + // Alternatively, set the enabled protocols + SSLContext serverSslContext = SSLContext.getInstance("TLS"); + SSLEngine serverEngine = serverSslContext.createSSLEngine(); + // Calling setEnabledProtocols will override the original context's configured protocol version + serverEngine.setEnabledProtocols(new String[]{ "TLSv1.2" }); + ``` + + For more information on `SSLContext` see: + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/javax/net/ssl/SSLContext.html + + For more information on MiTM attacks see: + - https://owasp.org/www-community/attacks/Manipulator-in-the-middle_attack + metadata: + category: security + cwe: CWE-326 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Inadequate encryption strength + patterns: + - pattern-either: + - pattern-inside: | + import javax.net.ssl.*; ... - django.http.HttpResponse(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W + - pattern-inside: | + import javax.net.ssl.SSLContext; ... - $INTERM = $STR + $DATA + - pattern-either: + - pattern-inside: | + SSLContext.getInstance("$UNSAFE_VERSION"); + - pattern-inside: | + SSLContext.getInstance(...); ... - django.http.HttpResponse(..., $INTERM, ...) + $ENGINE.setEnabledProtocols(new String[]{...,"$UNSAFE_VERSION",...}); + - pattern-not-inside: | + $C = SSLContext.getInstance(...); + ... + $ENGINE.setEnabledProtocols(new String[]{...,"TLSv1.2",...}); + - pattern-not-inside: | + $C = SSLContext.getInstance(...); + ... + $ENGINE.setEnabledProtocols(new String[]{...,"TLSv1.3",...}); + - pattern-not-inside: | + $C = SSLContext.getInstance(...); + ... + $ENGINE.setEnabledProtocols(new String[]{...,"DTLSv1.2",...}); + - pattern-not-inside: | + $C = SSLContext.getInstance(...); + ... + $ENGINE.setEnabledProtocols(new String[]{...,"DTLSv1.3",...}); + - metavariable-regex: + metavariable: $UNSAFE_VERSION + regex: ^(TLS|(D)?TLSv1.(0|1))$ severity: WARNING - - id: python.django.security.injection.reflected-data-httpresponsebadrequest.reflected-data-httpresponsebadrequest + - id: java_endpoint_rule-HostnameVerifier languages: - - python - message: Found user-controlled request data passed into a HttpResponseBadRequest. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed. + - java + message: "The `HostnameVerifier` has been set to always return `true`. This effectively \ndisables the validation of server or client certificates. This could allow an \nadversary who is in between the application and the target host to launch a Man \nin the middle attack (MITM) i.e intercept potentially sensitive information or \ninject malicious content into the communication stream.\n\nTo mitigate this vulnerability and enhance the security of your application, it is \nstrongly advised to adhere to the default HostnameVerifier settings. This ensures \nthat the validation mechanism remains intact, providing a crucial layer of security \nagainst unauthorized interception and data manipulation.\n\nImplementing the default HostnameVerifier can be achieved with the following code \nsnippet:\n```\n// Use the default HostnameVerifier\nHttpsURLConnection connection = (HttpsURLConnection) url.openConnection();\nconnection.setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier());\n```\nFor more information on TLS security, refer the following OWASP documentation:\nhttps://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + cwe: CWE-295 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss - subcategory: - - vuln - technology: - - django + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Improper certificate validation patterns: - pattern-inside: | - def $FUNC(...): + class $V implements HostnameVerifier { ... + } - pattern-either: - - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W.get(...), ...) - - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W.get(...)}...", ...) - - pattern: django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseBadRequest(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) - - pattern: return django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W(...), ...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W(...), ...) - - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W(...)}...", ...) - - pattern: django.http.HttpResponseBadRequest(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseBadRequest(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W(...), ...) - - pattern: return django.http.HttpResponseBadRequest(..., request.$W(...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W[...], ...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W[...], ...) - - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W[...]}...", ...) - - pattern: django.http.HttpResponseBadRequest(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseBadRequest(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W[...], ...) - - pattern: return django.http.HttpResponseBadRequest(..., request.$W[...], ...) - - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W, ...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W, ...) - - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W}...", ...) - - pattern: django.http.HttpResponseBadRequest(..., request.$W, ...) + boolean verify(...) { + ... + return true; + ... + } + - pattern-not: + patterns: + - pattern: | + boolean verify(...) { + ... + return $VAR; + ... + } + - metavariable-regex: + metavariable: $VAR + regex: ^((?!true).)*$ + - pattern-not: | + boolean verify(...) { + $VAR = true; + ... + return $VAR; + ... + } + severity: WARNING + - id: java_endpoint_rule-UnvalidatedRedirect + languages: + - java + message: "Unvalidated redirects occur when an application redirects a user to a\ndestination URL specified by a user supplied parameter that is not validated.\nSuch vulnerabilities can be used to facilitate phishing attacks.\n\nTo avoid open redirect vulnerabilities in Java, one effective strategy is to\nonly allow redirection to URLs that are pre-defined in a safe list. This safe\nlist can be implemented using a collection like a Map, List, or Dictionary,\nwhere you store all the valid URLs or URL patterns. When a redirect request is\nmade, you can check if the requested URL is in this safe list before proceeding \nwith the redirection. For example:\n\n```\n protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {\n private List safeUrls = new ArrayList<>();\n safeUrls.add(\"/home\");\n safeUrls.add(\"/user/profile\");\n safeUrls.add(\"/dashboard\");\n \n String redirectUrl = request.getParameter(\"url\");\n\n if (safeUrls.contains(redirectUrl)) {\n response.sendRedirect(redirectUrl);\n } else {\n response.sendRedirect(\"/errorPage\");\n }\n }\"\n``` \n" + metadata: + category: security + cwe: CWE-601 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Info + shortDescription: URL redirection to untrusted site ('Open Redirect') + mode: taint + pattern-sanitizers: + - patterns: + - pattern-inside: | + if ($SAFE.contains($URL)){ + ... + } + - pattern-either: + - pattern: | + ($X.servlet.http.HttpServletResponse $RES).sendRedirect($URL) + - pattern: | + ($X.servlet.http.HttpServletResponse $RES).addHeader("Location", $URL) + pattern-sinks: + - pattern-either: - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseBadRequest(..., $DATA, ...) + ($X.servlet.http.HttpServletResponse $RES).sendRedirect($URL) - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) + ($X.servlet.http.HttpServletResponse $RES).addHeader("Location", $URL) + pattern-sources: + - patterns: - pattern: | - $DATA = request.$W + $URL = ($X.servlet.http.HttpServletRequest $REQ).$M(...); + - metavariable-regex: + metavariable: $M + regex: (getParameter|getCookies|getHeader|getHeaders|getHeaderNames|getPathInfo|getPathTranslated|getContextPath|getQueryString|getRemoteUser|getRequestedSessionId|getRequestURI|getRequestURL|getServletPath|getParts|getPart|getReader) + severity: ERROR + - id: java_endpoint_rule-X509TrustManager + languages: + - java + message: "The `X509TrustManager` has been configured to return null. This effectively disables the\nvalidation of server or client certificates. This could allow an adversary who is in \nbetween the application and the target host to launch a Man in the middle attack (MITM) i.e \nintercept potentially sensitive information or inject malicious content into the \ncommunication stream.\n\nConsider using the \ndefault `TrustManager` instead of implementing a custom one. If you must override\nthe default verification process, implement proper TrustManager verification for\n`checkServerTrusted` and `checkClientTrusted` by throwing `CertificateException` if \nthe certificate is invalid.\n\nFor most applications, using the default TrustManager provided by the Java runtime is \nsufficient and recommended. Following is an example using the built in `TrustManagerFactory` \nto manage validating certificate chains:\n```\n// Use the default TrustManagerFactory\nTrustManagerFactory trustManagerFactory =\nTrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());\n// Use default system KeyStore, alternatively pass in your own keystore.\ntrustManagerFactory.init((KeyStore) null);\n// Create SSLContext for TLS connections\nSSLContext tlsContext = SSLContext.getInstance(\"TLS\");\n// Initialize the tlsContext with our trust manager and a SecureRandom number generator.\ntlsContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());\n```\nFor more information on TLS security, refer the following OWASP documentation:\nhttps://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html\n" + metadata: + category: security + cwe: CWE-295 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Improper certificate validation + patterns: + - pattern-inside: | + class $V implements X509TrustManager { + ... + } + - pattern-either: + - pattern: public void checkClientTrusted(...) {} + - pattern: public void checkServerTrusted(...) {} + - patterns: + - pattern-either: + - pattern: | + X509Certificate[] getAcceptedIssuers() { + ... + return null; + ... + } + - pattern-not: + patterns: + - pattern: | + X509Certificate[] getAcceptedIssuers() { + ... + return $VAR; + ... + } + - metavariable-regex: + metavariable: $VAR + regex: ^((?!null).)*$ + - pattern-not: | + X509Certificate[] getAcceptedIssuers() { + $VAR = null; + ... + return $VAR; + ... + } + severity: WARNING + - id: java_file_rule-FileUploadFileName + languages: + - java + message: | + The filename provided by the FileUpload API can be tampered with + which could lead to unauthorized access or file inclusion vulnerabilities. + To mitigate this risk, it is essential to conduct rigorous validation of the + filenames provided by clients. This validation should ensure that the filename + adheres to a predefined structure, is devoid of potentially dangerous characters + (such as forward slashes / and backslashes \), and corresponds to an authorized + file only. + + For example, as a remediation strategy, the application could: + 1. Sanitize Filenames: Create a function to sanitize filenames by removing + or replacing unauthorized characters, including path traversal sequences (../ or ..\). + 2. Allowlist Validation: Implement a allowlist approach, allowing only filenames + that match a specific pattern or are part of a predefined list. + 3. Use Server-Generated Filenames: Rather than relying on client-provided filenames, + generate unique names server-side for storing files. + 4. Verify File Paths: Ensure files are being saved in the correct, + intended directory, and prevent redirection to unauthorized directories. + + Example remediation: + ``` + public class FileUploadHandler { + + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + Part filePart = request.getPart("file"); + String fileName = filePart.getSubmittedFileName(); + + // removes any path information from the filename + String sanitizedFileName = sanitizeFileName(fileName); + if (!isFileNameAllowed(sanitizedFileName)) { + throw new SecurityException("Invalid file name"); + } + + // Generate a unique file name for storage + String storedFileName = UUID.randomUUID().toString() + ".txt"; + + Path targetPath = Paths.get("uploads").resolve(storedFileName); + Files.copy(fileContent, targetPath, StandardCopyOption.REPLACE_EXISTING); + } + + private String sanitizeFileName(String fileName) { + return Paths.get(fileName).getFileName().toString(); + } + + private boolean isFileNameAllowed(String fileName) { + return fileName.matches("[a-zA-Z0-9._-]+"); + } + } + ``` + metadata: + category: security + cwe: CWE-22 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Info + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + technology: + - java + pattern-either: + - patterns: + - pattern-inside: | + $FILES = (ServletFileUpload $SFU).parseRequest(($X.servlet.http.HttpServletRequest $REQ)); ... - django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) + for(FileItem $ITEM : $FILES) { + ... + } + - pattern: $ITEM.getName() + - pattern: ($X.servlet.http.Part $PART).getSubmittedFileName() + severity: WARNING + - id: java_file_rule-FilenameUtils + languages: + - java + message: "The filename provided by the FileUpload API can be tampered with by the client to reference\nunauthorized files. The provided filename should be properly validated to ensure it's properly\nstructured, contains no unauthorized path characters (e.g., / \\), and refers to an authorized\nfile.\n\nThe application was found to take a parameter from user input to construct a path name. If an\nunfiltered parameter is passed to this file API, files from an arbitrary filesystem location\ncould be read. When data from an unstrusted source is untrusted source is used to construct\na file path, an attacker could potentially gain access to restrcited files locations outside\nthe relevant context.\n\nFor example, if the application tries to access the users profile picture based on their user\nname by concatenating the username to the filepath:\n\n\"images/userprofiles/\" + username\n\nThe expected result of this would be \"images/userprofiles/alice\", however an attacker could\nuse a malicious input such as \"../../../etc/passwd\" to gain access to and/or manipulate\nsensitive information\n\nAssume all input is malicious. Use an \"accept known good\" input validation strategy.\n\nInputs can be sanitized by using the getName() method with concat() method to remove the \npotentially malicious path traversal and limit the scope to a restricted directory. Or \ninput can also be sanitized by using resolve() method alongwith startsWith() method to \nverify that the base path of the file is safe and expected.\n\nExample of limiting path traversal using getName:\n\n```\nprotected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {\n\n String input = req.getHeader(\"input\");\n\n input = getName(input);\n \n String safePath = concat(basePath, input);\n\n // Read the contents of the file\n File file = new File(safePath);\n}\n```\n" + metadata: + category: security + cwe: CWE-22 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Info + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + technology: + - java + mode: taint + pattern-sanitizers: + - pattern: | + $NAME = org.apache.commons.io.FilenameUtils.getName(...); + ... + $SAFE = concat($BASE, $NAME); + - pattern: | + $RET $FUN(...){ + ... + $PATH = $BP.resolve(...); + ... + if(!$PATH.startsWith(...)) { + throw new $EXC(...); + } + ... + } + pattern-sinks: + - pattern: org.apache.commons.io.FilenameUtils.concat(...) + - pattern: org.apache.commons.io.FilenameUtils.getFullPath(...) + - pattern: org.apache.commons.io.FilenameUtils.getFullPathNoEndSeparator(...) + - pattern: org.apache.commons.io.FilenameUtils.getPath(...) + - pattern: org.apache.commons.io.FilenameUtils.getPathNoEndSeparator(...) + - pattern: org.apache.commons.io.FilenameUtils.normalize(...) + - pattern: org.apache.commons.io.FilenameUtils.normalizeNoEndSeparator(...) + - pattern: org.apache.commons.io.FilenameUtils.normalizeNoEndSeparator(...) + - pattern: org.apache.commons.io.FilenameUtils.removeExtension(...) + - pattern: org.apache.commons.io.FilenameUtils.separatorsToSystem(...) + - pattern: org.apache.commons.io.FilenameUtils.separatorsToUnix(...) + - pattern: org.apache.commons.io.FilenameUtils.separatorsToWindows(...) + pattern-sources: + - pattern: (HttpServletRequest $REQ) + severity: WARNING + - id: java_inject_rule-CommandInjection + languages: + - java + message: | + OS command injection is a critical vulnerability that can lead to a full system + compromise as it may allow an adversary to pass in arbitrary commands or arguments + to be executed. + + User input should never be used in constructing commands or command arguments + to functions which execute OS commands. This includes filenames supplied by + user uploads or downloads. + + Ensure your application does not: + + - Use user-supplied information in the process name to execute. + - Use user-supplied information in an OS command execution function which does + not escape shell meta-characters. + - Use user-supplied information in arguments to OS commands. + + The application should have a hardcoded set of arguments that are to be passed + to OS commands. If filenames are being passed to these functions, it is + recommended that a hash of the filename be used instead, or some other unique + identifier. It is strongly recommended that a native library that implements + the same functionality be used instead of using OS system commands, due to the + risk of unknown attacks against third party commands. + + When specifying the OS command, ensure the application uses the full path + information, otherwise the OS may attempt to look up which process to execute + and could be vulnerable to untrusted search path vulnerabilities (CWE-426). + + Example of safely executing an OS command: + ``` + public static void executeCommand(String userFileData) throws java.io.IOException { + // Generate a random filename, do not use user input + String fileName = UUID.randomUUID().toString(); + // Create a Buffered/FileWriter + BufferedWriter writer = new BufferedWriter(new FileWriter(fileName)); + // Write the user content to our random file + writer.write(userFileData); + // Close the file to flush contents + writer.close(); + // Create the process builder with a hardcoded path to the binary, and our randomly + generated filename + ProcessBuilder processBuilder = new ProcessBuilder("/opt/app/path", fileName); + // Start the process + Process process = processBuilder.start(); + // Handle/redirect output of process here + // ... + } + ``` + + For more information on OS command injection, see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-78 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + technology: + - java + mode: taint + pattern-propagators: + - from: $X + pattern: $LIST.add($X) + to: $LIST + - from: $X + pattern: $MAP.put(..., $X) + to: $MAP + - from: $X + pattern: $STR.concat($X) + to: $STR + - from: $X + pattern: $STR = String.format(..., $X, ...) + to: $STR + - from: $X + pattern: $STR = String.join(..., $X, ...) + to: $STR + pattern-sinks: + - pattern: (ProcessBuilder $PB).command(...) + - pattern: new ProcessBuilder(...) + - pattern: (Runtime $R).exec(...) + pattern-sources: + - pattern: (javax.servlet.http.HttpServletRequest $R).$METHOD(...) + - pattern: (java.util.Scanner $S).$METHOD(...) + - pattern: (java.util.stream.Stream).$METHOD(...) + - pattern: (java.util.StringJoiner $SJ).toString(...) + - pattern: (java.sql.ResultSet.getString $R).$METHOD(...) + - pattern: (java.lang.System $S).getProperty(...) + - pattern: (java.lang.System $S).getenv(...) + - pattern: (java.lang.StringBuilder $SB).toString(...) + - pattern: (java.io.FileInputStream $F).read(...) + - pattern: (java.io.FileReader $F).read(...) + - pattern: (java.net.Socket $S).getInputStream(...) + - pattern: (java.net.Socket $S).getOutputStream(...) + - pattern: (java.net.DatagramSocket $S).receive(...) + - pattern: (java.net.DatagramSocket $S).getInputStream(...) + - pattern: java.nio.file.Files.readAllBytes(...) + - pattern: java.nio.file.Files.readAllLines(...) + - pattern: java.nio.file.Files.lines(...) + - pattern: java.nio.file.Files.newBufferedReader(...) + - pattern: org.apache.commons.io.IOUtils.toString(...) + - pattern: org.apache.commons.io.IOUtils.readLines(...) + - pattern: org.apache.commons.io.IOUtils.toByteArray(...) + - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).readValue(...) + - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).treeToValue(...) + - pattern: $CLASS.$METHOD(..., (javax.servlet.http.HttpServletRequest $R), ...) + - pattern: $FUNC(..., (javax.servlet.http.HttpServletRequest $R), ...) + - patterns: + - pattern-inside: $FUNC(..., String $X, ...) { ... } + - focus-metavariable: $X + severity: WARNING + - id: java_inject_rule-ELInjection + languages: + - java + message: "This rule identifies potential Expression Language (EL) injection vulnerabilities within Java applications. \nThe rule targets use of `createValueExpression`, `createMethodExpression`, `ELProcessor.eval`, `getValue`, \nand `setValue` methods, particularly when input to these methods is not a hardcoded string, indicating dynamic \nevaluation of potentially untrusted input. \n\n`createValueExpression` creates a `ValueExpression` object which gets evaluated upon calling methods like \n`getValue()` and `setValue()` or a Lambda `invoke()` i.e. it evaluates the expression passed to the \n`createValueExpression` method.\n\nSimilarly, `createMethodExpression` creates a `MethodExpression` object which gets evaluated upon calling \nmethods like `invoke()` and `getMethodInfo()`.\n`ELProcessor.eval`, `getValue()`, and `setValue()` methods all evaluate their expressions which are passed \nas parameters.\n\nCalling these method directly with user-supplied input may allow an adversary to execute arbitrary Java \ncode, including OS system commands. Never call these methods directly with user-supplied input. Consider \nalternate methods such as a lookup table to take user input and resolve hardcoded values.\n\nSecure example:\n\n```\nimport javax.el.ELProcessor;\nimport java.util.Set;\n\npublic class SafeELHandling {\n private static final Set ALLOWED_VALUES = Set.of(\"value1\", \"value2\", \"value3\");\n\n public void processInput(String userInput) {\n // Validate user input against the allowlist\n if (!ALLOWED_VALUES.contains(userInput)) {\n throw new IllegalArgumentException(\"Invalid input\");\n }\n \n ELProcessor elProcessor = new ELProcessor();\n elProcessor.defineBean(\"userInput\", userInput);\n \n // Example EL expression using the safe, predefined input\n String result = (String) elProcessor.eval(userInput);\n }\n}\n```\n" + metadata: + category: security + cwe: CWE-917 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Info + shortDescription: Improper neutralization of special elements used in an expression language statement ('Expression Language Injection') + technology: + - java + pattern-either: + - patterns: - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) + (ExpressionFactory $EXP).createValueExpression((ELContext $CTX), $EXPR, + ...) + - pattern-not: | + (ExpressionFactory $EXP).createValueExpression((ELContext $CTX), "...", + ...) + - patterns: - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) + (ExpressionFactory $EXP).createMethodExpression((ELContext $CTX), $EXPR, + ...) + - pattern-not: | + (ExpressionFactory $EXP).createMethodExpression((ELContext $CTX), "...", + ...) + - patterns: - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) + ($X.el.ELProcessor $P).eval(...) + - pattern-not: | + ($X.el.ELProcessor $P).eval("...", ...) + - patterns: - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) + ($X.el.ELProcessor $P).getValue(...) + - pattern-not: | + ($X.el.ELProcessor $P).getValue("...", ...) + - patterns: - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." + ($X.el.ELProcessor $P).setValue(...) + - pattern-not: "($X.el.ELProcessor $P).setValue(\"...\", \"...\") \n" + severity: WARNING + - id: java_inject_rule-FileDisclosureRequestDispatcher + languages: + - java + message: | + The `HttpRequest.getRequestDispatcher()`'s `include` and `forward` methods will return + any file that is resolvable within the web application context. This includes the `web.xml` + file, any compiled classes, `jsp` files, and additional JAR or WAR libraries that are + accessible. + + Never pass user-supplied input directly to any of these methods. Use a lookup table or + hardcode + which views or paths the user should be directed to. Another option is to use a simple HTTP + redirect by returning an empty response body with a 301 status code and a `Location` redirect + header. In Java servlets, this can be done by using the `response.sendRedirect(...)` method. + + Example using a redirect instead of a `RequestDispatcher`: + ``` + // Create a look up table or pull from a data source + HashMap lookupTable = new HashMap<>(); + lookupTable.put("key1", "/Resource1"); + lookupTable.put("key2", "/Resource2"); + // Get user input + String userInput = request.getParameter("key"); + // Look up resource to redirect to from the user input + String redirectValue = lookupTable.getOrDefault(userInput, "/Resource1"); + // Redirect the user + response.sendRedirect(redirectValue); + ``` + metadata: + category: security + cwe: CWE-552 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: HIGH + shortDescription: Files or directories accessible to external parties + mode: taint + pattern-sinks: + - patterns: + - pattern-not-inside: | + $VAL = $MAP.getOrDefault(..., "..."); ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W + - pattern-inside: | + $REQ = $HTTP.getRequestDispatcher(...); ... - django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W + - pattern-either: + - pattern: $REQ.include($FST, $SND) + - pattern: $REQ.forward($FST, $SND) + pattern-sources: + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameter(...) + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterNames(); + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterValues(...); + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterMap(); + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getHeader(...); + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getPathInfo(); + severity: ERROR + - id: java_inject_rule-FileDisclosureSpringFramework + languages: + - java + message: | + The `org.springframework.web.servlet.ModelAndView` class may + potentially allow access to restricted files if called with user-supplied input. + + The ModelAndView class looks up a view by name to resolve a `.jsp` + file. If this view name comes from user-supplied input, it could be abused to attempt + to return a JSP view that the user should not have access to. + + Use a lookup table or hardcode which views or paths the user should be directed to. + + Example using a lookup table to resolve a view from a Spring MVC application: + ``` + @RequestMapping(value="/mvc", method=RequestMethod.GET) + public ModelAndView mvc(HttpServletRequest request, HttpServletResponse response, Model model) + { + // Create a look up table or pull from a data source + HashMap lookupTable = new HashMap<>(); + lookupTable.put("key1", "view1"); + lookupTable.put("key2", "view2"); + // Get user input + String userInput = request.getParameter("key"); + // Look up view from the user input + String viewValue = lookupTable.getOrDefault(userInput, "Resource1"); + // return the new model and view + return new ModelAndView(viewValue); + } + ``` + + Example using a redirect instead of a `RequestDispatcher` in Spring: + ``` + @RequestMapping(value="/mvc", method=RequestMethod.GET) + public void mvc(HttpServletRequest request, HttpServletResponse response, Model model) + { + // Create a look up table or pull from a data source + HashMap lookupTable = new HashMap<>(); + lookupTable.put("key1", "view1"); + lookupTable.put("key2", "view2"); + // Get user input + String userInput = request.getParameter("key"); + // Look up resource to redirect to from the user input + String redirectValue = lookupTable.getOrDefault(userInput, "/Resource1"); + // return the new model and view + response.sendRedirect(redirectValue); + } + ``` + metadata: + category: security + cwe: CWE-552 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: HIGH + shortDescription: Files or directories accessible to external parties + mode: taint + pattern-sinks: + - patterns: + - pattern-not-inside: | + $FST = $MAP.getOrDefault(..., "..."); + ... + - pattern: new org.springframework.web.servlet.ModelAndView($FST, ...); + - focus-metavariable: $FST + - patterns: + - pattern-not-inside: | + $FST = $MAP.getOrDefault(..., "..."); ... - $INTERM = $STR + $DATA + - pattern-inside: | + $MVC = new org.springframework.web.servlet.ModelAndView(); ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W, ...) - - pattern: return django.http.HttpResponseBadRequest(..., request.$W, ...) + - pattern: $MVC.setViewName(...); + pattern-sources: + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameter(...) + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterNames(); + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterValues(...); + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterMap(); + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getHeader(...); + - pattern: (javax.servlet.http.HttpServletRequest $VAR).getPathInfo(); + severity: ERROR + - id: java_inject_rule-HttpParameterPollution + languages: + - java + message: | + The application was found including unvalidated user input into a URL, which could lead to + HTTP Parameter Pollution (HPP) or worse, Server Side Request Forgery (SSRF). This could + allow an adversary to override the value of a URL or a request parameter. HTTP Parameter + Pollution + (HPP) attacks consist of injecting encoded query string delimiters into other existing + parameters. If a web + application does not properly sanitize the user input, an adversary may modify the logic of + these + requests to other applications. + + To remediate this issue, never allow user input directly into creation of a URL or URL + parameter. Consider + using a map to look up user-supplied information and return exact values to be used in the + generation of + requests. + + Example using a map to look up a key to be used in a HTTP request: + ``` + HashMap lookupTable = new HashMap<>(); + lookupTable.put("key1", "value1"); + lookupTable.put("key2", "value2"); + String userInput = request.getParameter("key"); + + // Create a CloseableHttpClient, ideally any requests issued should be done + // out-of-band from the servlet request itself (such as using a separate thread/scheduler + system) + try (final CloseableHttpClient httpClient = HttpClients.createDefault()) { + // Lookup the value from our user input from our lookupTable + String value = lookupTable.getOrDefault(userInput, "value1"); + // Construct the url, with the hardcoded url and only pass in the value from the + lookupTable, + // not direct user input + final HttpGet httpget = new HttpGet("https://example.com/getId?key="+value); + // Execute the request + CloseableHttpResponse clientResponse = httpClient.execute(httpget); + // Read the response + byte[] responseData = clientResponse.getEntity().getContent().readAllBytes(); + // Handle the response + // ... + } + ``` + + If using a map is not possible, the user-supplied input must be encoded prior to use, and + never allow full + URLs: + ``` + // Get user input + String userInput = request.getParameter("key"); + // Encode the string using java.net.URLEncoder with the UTF-8 character set + String encodedString = java.net.URLEncoder.encode(userInput, StandardCharsets.UTF_8); + // Create a CloseableHttpClient, ideally any requests issued should be done + // out-of-band from the servlet request itself (such as using a separate thread/scheduler + system) + try (final CloseableHttpClient httpClient = HttpClients.createDefault()) { + // Construct the url, with the hardcoded url and only pass in the encoded value, never a + full URL + final HttpGet httpget = new HttpGet("https://example.com/getId?key="+encodedString); + // Execute the request + CloseableHttpResponse clientResponse = httpClient.execute(httpget); + // Read the response + byte[] responseData = clientResponse.getEntity().getContent().readAllBytes(); + // handle the response + } + ``` + + For more information on SSRF see OWASP: + https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + + For more information on HTTP Parameter Pollution see: + https://en.wikipedia.org/wiki/HTTP_parameter_pollution + metadata: + category: security + cwe: CWE-88 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of argument delimiters in a command ('Argument Injection') + technology: + - java + mode: taint + pattern-sanitizers: + - pattern: java.net.URLEncoder.encode(...) + - pattern: com.google.common.net.UrlEscapers.urlPathSegmentEscaper().escape(...) + pattern-sinks: + - pattern: new org.apache.http.client.methods.HttpGet(...) + - pattern: new org.apache.commons.httpclient.methods.GetMethod(...) + - pattern: (org.apache.commons.httpclient.methods.GetMethod $GM).setQueryString(...) + pattern-sources: + - pattern: (HttpServletRequest $REQ).getParameter(...) + severity: ERROR + - id: java_inject_rule-LDAPInjection + languages: + - java + message: | + LDAP injection attacks exploit LDAP queries to influence how data is returned by + the LDAP server. + + Later versions of Java's `InitialDirContext.search` introduced a four argument method, one of + which is the `filterArg` parameter. The `filterArg` will be automatically encoded when + querying + the LDAP server. If this method signature is not available, the application must encode the + LDAP strings manually. + + More details on the four argument `search` method can be found here: + https://docs.oracle.com/en/java/javase/20/docs/api/java.naming/javax/naming/directory/InitialDirContext.html#search(javax.naming.Name,java.lang.String,java.lang.Object[],javax.naming.directory.SearchControls) + + To encode the string manually, it is recommended that all input passed to LDAP querying + systems + encode the following values: + + - Any occurrence of the null character must be escaped as “\00”. + - Any occurrence of the open parenthesis character must be escaped as “\28”. + - Any occurrence of the close parenthesis character must be escaped as “\29”. + - Any occurrence of the asterisk character must be escaped as “\2a”. + - Any occurrence of the backslash character must be escaped as “\5c”. + + Example function that safely encodes user-supplied input to be used in an LDAP query. + ``` + public static String encodeLDAPString(String input) { + // Note the \ character is replaced first + CharSequence[] chars = new CharSequence[] { "\\", "\0", "(", ")", "*" }; + CharSequence[] encoded = new CharSequence[] { "\\5c", "\\00", "\\28", "\\29", "\\2a" }; + // Iterate over each character sequence, replacing the raw value with an encoded version of + it + for (int i = 0; i < chars.length; i++) + { + // re-assign to input + input = input.replace(chars[i], encoded[i]); + } + // return our modified input string + return input; + } + ``` + + Example code that using the `filterArgs` parameter which automatically encodes for us: + ``` + // Create a properties to hold the ldap connection details + Properties props = new Properties(); + // Use the com.sun.jndi.ldap.LdapCtxFactory factory provider + props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + // The LDAP server URL + props.put(Context.PROVIDER_URL, "ldap://ldap.example.org:3889"); + // User details for the connection + props.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=example,dc=org"); + // LDAP account password + String ldapAccountPassword = getAccountPasswordFromSecureStoreOrKMS(); + // Pass in the LDAP password + props.put(Context.SECURITY_CREDENTIALS, ldapAccountPassword); + + // Create the LDAPContext + InitialDirContext ldapContext = new InitialDirContext(props); + // Example using SUBTREE_SCOPE SearchControls + SearchControls searchControls = new SearchControls(); + searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + // Get user input for query + String userQuery = someUserInput; + // Use searchArguments to hold the user-supplied input + Object[] searchArguments = new Object[]{userQuery}; + // Hardcode the BaseDN, use the {0} format specifier to use the searchArguments array value, + and pass in the search controls. + // searchArguments automatically encode + NamingEnumeration answer = ldapContext.search("dc=example,dc=org", "(cn={0})", + searchArguments, searchControls); + // Process the response answer + while (answer.hasMoreElements()) { + ... + } + ``` + + For more information on LDAP Injection see OWASP: + https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-90 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of special elements used in an LDAP query ('LDAP Injection') + technology: + - java + mode: taint + pattern-sinks: + - pattern: javax.naming.ldap.LdapName(...) + - pattern: (javax.naming.directory.Context $C).lookup(...) + - pattern: (javax.naming.Context $C).lookup(...) + - patterns: + - pattern-inside: (com.unboundid.ldap.sdk.LDAPConnection $C).search($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-either: + - pattern: $CTX.lookup(...) + - patterns: + - pattern-inside: $CTX.search($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.search($NAME, $FILTER, ...) + - pattern: $FILTER + - metavariable-pattern: + metavariable: $CTX + pattern-either: + - pattern: (DirContext $C) + - pattern: (InitialDirContext $IDC) + - pattern: (LdapContext $LC) + - pattern: (EventDirContext $EDC) + - pattern: (LdapCtx $LC) + - pattern: (javax.naming.directory.DirContext $C) + - pattern: (javax.naming.directory.InitialDirContext $IDC) + - pattern: (javax.naming.ldap.LdapContext $LC) + - pattern: (javax.naming.event.EventDirContext $EDC) + - pattern: (com.sun.jndi.ldap.LdapCtx $LC) + - patterns: + - pattern-either: + - patterns: + - pattern-inside: $CTX.list($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.lookup($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.search($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.search($NAME, $FILTER, ...) + - pattern: $FILTER + - metavariable-pattern: + metavariable: $CTX + pattern-either: + - pattern: (LdapTemplate $LT) + - pattern: (LdapOperations $LO) + - pattern: (org.springframework.ldap.core.LdapTemplate $LT) + - pattern: (org.springframework.ldap.core.LdapOperations $LO) + pattern-sources: + - patterns: + - pattern-inside: | + $FUNC(..., $VAR, ...) { + ... + } + - pattern: $VAR + - patterns: + - pattern-inside: | + $FUNC(..., $X, ...) { + ... + $VAR = ... + $X; + ... + } + - pattern: $VAR severity: WARNING - - id: python.django.security.injection.request-data-fileresponse.request-data-fileresponse + - id: java_inject_rule-OgnlInjection languages: - - python - message: Found user-controlled request data being passed into a file open, which is them passed as an argument into the FileResponse. This is dangerous because an attacker could specify an arbitrary file to read, which could result in leaking important data. Be sure to validate or sanitize the user-inputted filename in the request data before using it in FileResponse. + - java + message: | + The Object Graph Navigation Language (OGNL) is an expression language that allows access to + Java objects and properties stored in an ActionContext. Usage of these low-level + functions is discouraged because they can effectively execute strings as code, leading to + remote code execution vulnerabilities. Consider using struts tags when processing + user-supplied input and templates. + + Much like the Struts security guide recommending to not use raw `${}` EL expressions, + do not call or use the following OGNL packages with user-supplied input: + + - `com.opensymphony.xwork2.ognl` + - `com.opensymphony.xwork2.util` + - `com.opensymphony.xwork2.util.reflection` + - `org.apache.struts2.util.StrutsUtil` + + For more information on Struts2 security see: + https://struts.apache.org/security/#do-not-use-incoming-untrusted-user-input-in-forced-expression-evaluation metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + cwe: CWE-917 owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss - subcategory: - - vuln + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Expression injection (OGNL) technology: - - django + - java + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: com.opensymphony.xwork2.util.TextParseUtil.translateVariables($VAL, ...) + - pattern: $VAL + - patterns: + - pattern-inside: com.opensymphony.xwork2.util.TextParseUtil.translateVariablesCollection($VAL, ...) + - pattern: $VAL + - pattern: com.opensymphony.xwork2.util.TextParseUtil.shallBeIncluded(...) + - pattern: com.opensymphony.xwork2.util.TextParseUtil.commaDelimitedStringToSet(...) + - patterns: + - pattern-inside: (com.opensymphony.xwork2.util.TextParser $P).evaluate($VAR, $VAL, ...) + - pattern: $VAL + - patterns: + - pattern-inside: (com.opensymphony.xwork2.util.OgnlTextParser $P).evaluate($VAR, $VAL, ...) + - pattern: $VAL + - pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getGetMethod($CLZ, ...) + - pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getSetMethod($CLZ, ...) + - pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getField($CLZ, ...) + - patterns: + - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setProperties($MAP, ...) + - pattern: $MAP + - patterns: + - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setProperty($VAL, ...) + - pattern: $VAL + - patterns: + - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getValue($VAL, ...) + - pattern: $VAL + - patterns: + - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setValue($VAL, ...) + - pattern: $VAL + - pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getGetMethod($CLZ, ...) + - pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getSetMethod($CLZ, ...) + - pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getField($CLZ, ...) + - patterns: + - pattern-inside: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).setProperties($MAP, ...) + - pattern: $MAP + - patterns: + - pattern-inside: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).setProperty($VAR, ...) + - pattern: $VAR + - patterns: + - pattern-inside: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getValue($VAR, ...) + - pattern: $VAR + - patterns: + - pattern-inside: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).setValue($VAR, ...) + - pattern: $VAR + - patterns: + - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).setProperties($MAP, ...) + - pattern: $MAP + - patterns: + - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).setProperty($VAR, ...) + - pattern: $VAR + - patterns: + - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).getValue($VAR, ...) + - pattern: $VAR + - patterns: + - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).setValue($VAR, ...) + - pattern: $VAR + - patterns: + - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).callMethod($VAR, ...) + - pattern: $VAR + - patterns: + - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).compile($VAR, ...) + - pattern: $VAR + - pattern: (org.apache.struts2.util.VelocityStrutsUtil $P).evaluate(...) + - pattern: org.apache.struts2.util.StrutsUtil.findString(...) + - pattern: org.apache.struts2.util.StrutsUtil.findValue(..., $VAL) + - pattern: org.apache.struts2.util.StrutsUtil.getText(...) + - pattern: org.apache.struts2.util.StrutsUtil.translateVariables(...) + - patterns: + - pattern-inside: org.apache.struts2.util.StrutsUtil.makeSelectList($VAR, ...) + - pattern: $VAR + - patterns: + - pattern-inside: (org.apache.struts2.views.jsp.ui.OgnlTool $T).findValue($VAR, ...) + - pattern: $VAR + - pattern: (com.opensymphony.xwork2.util.ValueStack $V).findString(...) + - patterns: + - pattern-inside: (com.opensymphony.xwork2.util.ValueStack $V).findValue($VAR, ...) + - pattern: $VAR + - patterns: + - pattern-inside: (com.opensymphony.xwork2.util.ValueStack $V).setValue($VAR, ...) + - pattern: $VAR + - patterns: + - pattern-inside: (com.opensymphony.xwork2.util.ValueStack $V).setParameter($VAR, ...) + - pattern: $VAR + pattern-sources: + - patterns: + - pattern-inside: | + $FUNC(..., $VAR, ...) { + ... + } + - metavariable-pattern: + metavariable: $VAR + pattern-either: + - pattern: (String $S) + - pattern: (Map $M) + - pattern: (Map $M) + - pattern: (Map $M) + - pattern: $VAR + severity: WARNING + - id: java_inject_rule-SpotbugsPathTraversalAbsolute + languages: + - java + message: | + The application dynamically constructs file or path information. If the path + information comes from user input, it could be abused to read sensitive files, + access other users' data, or aid in exploitation to gain further system access. + + User input should never be used in constructing paths or files for interacting + with the filesystem. This includes filenames supplied by user uploads or downloads. + If possible, consider hashing user input or replacing it with unique values and + use `Path.resolve` to resolve and validate the path information + prior to processing any file functionality. + + Example using `Path.resolve` and not allowing direct user input: + ``` + // Class to store our user data along with a randomly generated file name + public static class UserData { + private String userFileNameUnsafe; + private String fileName; + public UserData(String userFileName) { + this.userFileNameUnsafe = userFileName; + // Generate a random ID for the filename + this.fileName = UUID.randomUUID().toString(); + } + public String getUserFileNameUnsafe() { return userFileNameUnsafe; }; + public String getFileName() { return fileName; }; + } + + public static void main(String[] args) throws Exception { + // User input, saved only as a reference + UserData userData = new UserData("..\\test.txt"); + // Restrict all file processing to this directory only + String base = "/var/app/restricted"; + Path basePath = Paths.get(base); + // Resolve the full path, but only use our random generated filename + Path fullPath = basePath.resolve(userData.getFileName()); + // verify the path is contained within our basePath + if (!fullPath.startsWith(base)) { + throw new Exception("Invalid path specified!"); + } + // process / work with file + } + ``` + + For more information on path traversal issues see OWASP: + https://owasp.org/www-community/attacks/Path_Traversal + metadata: + category: security + cwe: CWE-22 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + technology: + - java + mode: taint + pattern-propagators: + - from: $X + pattern: $LIST.add($X) + to: $LIST + - from: $X + pattern: $MAP.put(..., $X) + to: $MAP + - from: $X + pattern: $STR.concat($X) + to: $STR + - from: $X + pattern: $STR = String.format(..., $X, ...) + to: $STR + - from: $X + pattern: $STR = String.join(..., $X, ...) + to: $STR + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: + - patterns: + - pattern-inside: | + $U = new java.net.URI($VAR) + - pattern-either: + - pattern-inside: new java.io.File($U) + - pattern-inside: java.nio.file.Paths.get($U) + - pattern: $VAR + - patterns: + - pattern-inside: new java.io.RandomAccessFile($INPUT,...) + - pattern: $INPUT + - pattern: new java.io.FileReader(...) + - pattern: new javax.activation.FileDataSource(...) + - pattern: new java.io.FileInputStream(...) + - pattern: new java.io.FileOutputStream(...) + - pattern: new java.io.File(...) + - pattern: java.nio.file.Paths.get(...) + - pattern: java.io.File.createTempFile(...) + - pattern: java.io.File.createTempDirectory(...) + - pattern: java.nio.file.Files.createTempFile(...) + - pattern: java.nio.file.Files.createTempDirectory(...) + - patterns: + - pattern: $SRC.$METHOD(...) + - metavariable-pattern: + metavariable: $SRC + pattern-either: + - pattern: getClass() + - pattern: getClass().getClassLoader() + - pattern: (ClassLoader $C) + - pattern: (Class $C) + - pattern: $CLZ.getClassLoader() + - metavariable-pattern: + metavariable: $METHOD + pattern-either: + - pattern: getResourceAsStream + - pattern: getResource + - patterns: + - pattern-inside: new java.io.FileWriter($PATH, ...) + - pattern: $PATH + - patterns: + - pattern-inside: new java.io.FileOutputStream($PATH, ...) + - pattern: $PATH + pattern-sources: + - pattern: (javax.servlet.http.HttpServletRequest $R).$METHOD(...) + - pattern: (java.util.Scanner $S).$METHOD(...) + - pattern: (java.util.stream.Stream).$METHOD(...) + - pattern: (java.util.StringJoiner $SJ).toString(...) + - pattern: (java.sql.ResultSet.getString $R).$METHOD(...) + - pattern: (java.lang.System $S).getProperty(...) + - pattern: (java.lang.System $S).getenv(...) + - pattern: (java.lang.StringBuilder $SB).toString(...) + - pattern: (java.io.FileInputStream $F).read(...) + - pattern: (java.io.FileReader $F).read(...) + - pattern: (java.net.Socket $S).getInputStream(...) + - pattern: (java.net.Socket $S).getOutputStream(...) + - pattern: (java.net.DatagramSocket $S).receive(...) + - pattern: (java.net.DatagramSocket $S).getInputStream(...) + - pattern: java.nio.file.Files.readAllBytes(...) + - pattern: java.nio.file.Files.readAllLines(...) + - pattern: java.nio.file.Files.lines(...) + - pattern: java.nio.file.Files.newBufferedReader(...) + - pattern: org.apache.commons.io.IOUtils.toString(...) + - pattern: org.apache.commons.io.IOUtils.readLines(...) + - pattern: org.apache.commons.io.IOUtils.toByteArray(...) + - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).readValue(...) + - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).treeToValue(...) + - pattern: $CLASS.$METHOD(..., (javax.servlet.http.HttpServletRequest $R), ...) + - pattern: $FUNC(..., (javax.servlet.http.HttpServletRequest $R), ...) + - patterns: + - pattern-inside: $FUNC(..., @RequestParam String $X, ...) { ... } + - focus-metavariable: $X + severity: WARNING + - id: java_ldap_rule-AnonymousLDAP + languages: + - java + message: | + The application does not provide authentication when communicating an LDAP + server. It is strongly recommended that the LDAP server be configured with + authentication and restrict what queries users can execute. + + Example code that authenticates with a remote LDAP server and encodes any + user-supplied input: + ``` + // Create a properties to hold the ldap connection details + Properties props = new Properties(); + // Use the com.sun.jndi.ldap.LdapCtxFactory factory provider + props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + // The LDAP server URL + props.put(Context.PROVIDER_URL, "ldap://ldap.example.org:3889"); + // User details for the connection + props.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=example,dc=org"); + // LDAP account password + String ldapAccountPassword = getAccountPasswordFromSecureStoreOrKMS(); + // Pass in the LDAP password + props.put(Context.SECURITY_CREDENTIALS, ldapAccountPassword); + + // Create the LDAPContext + InitialDirContext ldapContext = new InitialDirContext(props); + // Example using SUBTREE_SCOPE SearchControls + SearchControls searchControls = new SearchControls(); + searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + // Get user input for query + String userQuery = someUserInput; + // Use searchArguments to hold the user-supplied input + Object[] searchArguments = new Object[]{userQuery}; + // Hardcode the BaseDN, use the {0} format specifier to use the searchArguments array value, + and pass in the search controls. + // searchArguments automatically encode + NamingEnumeration answer = ldapContext.search("dc=example,dc=org", "(cn={0})", + searchArguments, searchControls); + // Process the response answer + while (answer.hasMoreElements()) { + ... + } + ``` + + For information on enabling authentication, please see your LDAP server's + documentation. + + For more information on LDAP Injection see OWASP: + https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-306 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: High + shortDescription: Missing authentication for critical function (LDAP) patterns: - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: django.http.FileResponse(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.FileResponse(..., open($DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = open($DATA, ...) - ... - django.http.FileResponse(..., $INTERM, ...) - - pattern: $A = django.http.FileResponse(..., request.$W.get(...), ...) - - pattern: return django.http.FileResponse(..., request.$W.get(...), ...) - - pattern: django.http.FileResponse(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.FileResponse(..., open($DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = open($DATA, ...) - ... - django.http.FileResponse(..., $INTERM, ...) - - pattern: $A = django.http.FileResponse(..., request.$W(...), ...) - - pattern: return django.http.FileResponse(..., request.$W(...), ...) - - pattern: django.http.FileResponse(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.FileResponse(..., open($DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = open($DATA, ...) - ... - django.http.FileResponse(..., $INTERM, ...) - - pattern: $A = django.http.FileResponse(..., request.$W[...], ...) - - pattern: return django.http.FileResponse(..., request.$W[...], ...) - - pattern: django.http.FileResponse(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - django.http.FileResponse(..., open($DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = open($DATA, ...) - ... - django.http.FileResponse(..., $INTERM, ...) - - pattern: $A = django.http.FileResponse(..., request.$W, ...) - - pattern: return django.http.FileResponse(..., request.$W, ...) + import javax.naming.Context; + ... + - pattern: $ENV.put(Context.SECURITY_AUTHENTICATION, "none"); severity: WARNING - - id: python.django.security.injection.request-data-write.request-data-write + - id: java_password_rule-ConstantDBPassword languages: - - python - message: Found user-controlled request data passed into '.write(...)'. This could be dangerous if a malicious actor is able to control data into sensitive files. For example, a malicious actor could force rolling of critical log files, or cause a denial-of-service by using up available disk space. Instead, ensure that request data is properly escaped or sanitized. + - java + message: | + A potential hard-coded password was identified in a database connection string. + Passwords should not be stored directly in code + but loaded from secure locations such as a Key Management System (KMS). + + The purpose of using a Key Management System is so access can be audited and keys easily + rotated + in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine + when or if, a key is compromised. + + The recommendation on which KMS to use depends on the environment the application is running + in: + + - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) + - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) + - For on premise or other alternatives to cloud providers, consider [Hashicorp's + Vault](https://www.vaultproject.io/) + - For other cloud providers, please see their documentation metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-93: Improper Neutralization of CRLF Sequences (''CRLF Injection'')' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-259 owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: Critical + shortDescription: Use of hard-coded password technology: - - django + - java + patterns: + - pattern: java.sql.DriverManager.getConnection($URI, $USR, "..."); + severity: ERROR + - id: java_password_rule-EmptyDBPassword + languages: + - java + message: | + The application does not provide authentication when communicating a database + server. It is strongly recommended that the database server be configured with + authentication and restrict what queries users can execute. + + Please see your database server's documentation on how to configure a password. + + Additionally, passwords should not be stored directly in code + but loaded from secure locations such as a Key Management System (KMS). + + The purpose of using a Key Management System is so access can be audited and keys easily + rotated + in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine + when or if, a key is compromised. + + The recommendation on which KMS to use depends on the environment the application is running + in: + + - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) + - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) + - For on premise or other alternatives to cloud providers, consider [Hashicorp's + Vault](https://www.vaultproject.io/) + - For other cloud providers, please see their documentation + metadata: + category: security + cwe: CWE-306 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: Critical + shortDescription: Missing authentication for critical function (database) + technology: + - java + patterns: + - pattern: java.sql.DriverManager.getConnection($URI, $USR, ""); + severity: ERROR + - id: java_password_rule-HardcodePassword + languages: + - java + message: | + A potential hard-coded password was identified in a hard-coded string. + Passwords should not be stored directly in code + but loaded from secure locations such as a Key Management System (KMS). + + The purpose of using a Key Management System is so access can be audited and keys easily + rotated + in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine + when or if, a key is compromised. + + The recommendation on which KMS to use depends on the environment the application is running + in: + + - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) + - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) + - For on premise or other alternatives to cloud providers, consider [Hashicorp's + Vault](https://www.vaultproject.io/) + - For other cloud providers, please see their documentation + metadata: + category: security + cwe: CWE-259 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: High + shortDescription: Use of hard-coded password + technology: + - java + pattern-either: + - pattern: new java.security.KeyStore.PasswordProtection("...".toCharArray()) + - pattern: java.security.KeyStore.getInstance(...).load(..., "...".toCharArray()) + - pattern: (java.security.KeyStore $KS).load(..., "...".toCharArray()) + - pattern: KeyManagerFactory.getInstance(...).init(..., "...".toCharArray()) + - pattern: (KeyManagerFactory $KMF).init(..., "...".toCharArray()) + - pattern: PBEKeySpec("...", ...) + - pattern: PasswordAuthentication("...", "...") + - pattern: (PasswordCallback $CB).setPassword("...") + - pattern: KerberosKey(...,"...",...) + - pattern: java.sql.DriverManager.getConnection(..., "...") + - pattern: io.vertx.ext.web.handler.CSRFHandler.create(..., "...") + - pattern: $S.setPassword("...") + severity: ERROR + - id: java_perm_rule-DangerousPermissions + languages: + - java + message: | + The application was found to permit the `RuntimePermission` of `createClassLoader`, + `ReflectPermission` of `suppressAccessChecks`, or both. + + By granting the `RuntimePermission` of `createClassLoader`, a compromised application + could instantiate their own class loaders and load arbitrary classes. + + By granting the `ReflectPermission` of `suppressAccessChecks` an application will no longer + check Java language access checks on fields and methods of a class. This will effectively + grant access to protected and private members. + + For more information on `RuntimePermission` see: + https://docs.oracle.com/javase/8/docs/api/java/lang/RuntimePermission.html + + For more information on `ReflectPermission` see: + https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/ReflectPermission.html + metadata: + category: security + confidence: HIGH + cwe: CWE-732 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Incorrect permission assignment for critical resource pattern-either: - - pattern: $F.write(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $F.write(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $F.write(..., $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $F.write(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $F.write(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - $F.write(..., $INTERM, ...) - - pattern: $A = $F.write(..., request.$W.get(...), ...) - - pattern: return $F.write(..., request.$W.get(...), ...) - - pattern: $F.write(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $F.write(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $F.write(..., $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $F.write(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $F.write(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - $F.write(..., $INTERM, ...) - - pattern: $A = $F.write(..., request.$W(...), ...) - - pattern: return $F.write(..., request.$W(...), ...) - - pattern: $F.write(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $F.write(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $F.write(..., $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $F.write(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $F.write(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - $F.write(..., $INTERM, ...) - - pattern: $A = $F.write(..., request.$W[...], ...) - - pattern: return $F.write(..., request.$W[...], ...) - - pattern: $F.write(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - $F.write(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $F.write(..., $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $F.write(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $F.write(..., f"...{$DATA}...", ...) - pattern: | - $DATA = request.$W + $RUNVAR = new RuntimePermission("createClassLoader"); ... - $INTERM = f"...{$DATA}..." + (PermissionCollection $PC).add($RUNVAR); + - pattern: | + $REFVAR = new ReflectPermission("suppressAccessChecks"); ... - $F.write(..., $INTERM, ...) - - pattern: $A = $F.write(..., request.$W, ...) - - pattern: return $F.write(..., request.$W, ...) + (PermissionCollection $PC).add($REFVAR); + - pattern: (PermissionCollection $PC).add(new ReflectPermission("suppressAccessChecks")) + - pattern: (PermissionCollection $PC).add(new RuntimePermission("createClassLoader")) severity: WARNING - - id: python.django.security.injection.sql.sql-injection-extra.sql-injection-using-extra-where + - id: java_perm_rule-OverlyPermissiveFilePermissionInline languages: - - python - message: User-controlled data from a request is passed to 'extra()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use parameterized queries or escape the user-controlled data by using `params` and not using quote placeholders in the SQL string. + - java + message: | + The application was found setting file permissions to overly permissive values. Consider + using the following values if the application user is the only process to access + the file: + + - `r--` - read only access to the file + - `w--` - write only access to the file + - `rw-` - read/write access to the file + + Example setting read/write permissions for only the owner of a `Path`: + ``` + // Get a reference to the path + Path path = Paths.get("/tmp/somefile"); + // Create a PosixFilePermission set from java.nio.file.attribute + Set permissions = + java.nio.file.attribute.PosixFilePermissions.fromString("rw-------"); + // Set the permissions + java.nio.file.Files.setPosixFilePermissions(path, permissions); + ``` + + For all other values please see: + https://en.wikipedia.org/wiki/File-system_permissions#Symbolic_notation metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + confidence: HIGH + cwe: CWE-732 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.0/ref/models/expressions/#.objects.extra - subcategory: - - vuln - technology: - - django + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Incorrect permission assignment for critical resource patterns: - - pattern-inside: | - def $FUNC(...): - ... - pattern-either: - - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W.get(...), ...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W.get(...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W.get(...)}...", ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) - - pattern: return $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W(...), ...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W(...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W(...)}...", ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) - - pattern: return $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W[...], ...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W[...], ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W[...]}...", ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) - - pattern: return $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W, ...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W, ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W}...", ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) - - pattern: return $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) + - pattern: java.nio.file.Files.setPosixFilePermissions(..., java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING")); - pattern: | - $DATA = request.$W.get(...) + $PERMISSIONS = java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING"); ... - $INTERM = $STR % (..., $DATA, ...) + java.nio.file.Files.setPosixFilePermissions(..., $PERMISSIONS); + - metavariable-regex: + metavariable: $PERM_STRING + regex: '[rwx-]{6}[rwx]{1,}' + severity: WARNING + - id: java_script_rule-ScriptInjection + languages: + - java + message: | + The application executes an argument using a `ScriptEngine`'s `eval` method. This + may allow for direct OS commands to be executed as it's possible to pass in strings + such as `java.lang.Runtime.getRuntime().exec('/bin/sh ...');`. + + Never pass user-supplied input directly to the `eval` function. If possible hardcode all + JavasScript code or use a lookup table to resolve user input to known values. If none of these + techniques are possible, use `javax.script.Bindings` to pass input to the script engine. + + Example using `Binding` to safely pass in string values: + ``` + // Get ECMAScript engine + ScriptEngine engine = new ScriptEngineManager().getEngineByName("ECMAScript"); + + // User input, consisting of first and last name + String userFirstName = "John"; + String userLastName = "Snow"; + + // Create bindings to pass into our script, forcing the values to be String. + Bindings bindings = engine.createBindings(); + bindings.put("fname", new String(userFirstName)); + bindings.put("lname", new String(userLastName)); + + // Example script that concatenates a greeting with the user-supplied input first/last name + String script = "var greeting='Hello ';" + + // fname and lname variables will be resolved by our bindings defined above + "greeting += fname + ' ' + lname;" + + // prints greeting + "greeting"; + + try { + // Execute the script, passing in the bindings + Object bindingsResult = engine.eval(script, bindings); + // Work with result + // ... + } catch (ScriptException e) { + // Handle exception + e.printStackTrace(); + } + ``` + metadata: + category: security + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper control of generation of code ('Code Injection') + mode: taint + pattern-sinks: + - patterns: + - pattern: (javax.script.ScriptEngine $ENGINE).eval($ARG, ...); + - pattern-not: (javax.script.ScriptEngine $ENGINE).eval("..."); + - pattern-not: (javax.script.ScriptEngine $ENGINE).eval("...", (javax.script.Bindings $BINDING)); + - patterns: + - pattern-either: + - pattern: (javax.script.Invocable $INVC).invokeFunction(..., $ARG) + - pattern: (javax.script.Invocable $INVC).invokeMethod(..., $ARG) + pattern-sources: + - patterns: + - pattern-inside: $FUNC(..., $VAR, ...) { ... } + - pattern: $VAR + severity: ERROR + - id: java_script_rule-SpringSpelExpressionParser + languages: + - java + message: | + The application was found calling SpringFramework's `SpelExpressionParser.parseExpression`. + Calling this method directly with user-supplied input may allow an adversary to + execute arbitrary Java code including OS system commands. + + Never call `parseExpression` or `parseRaw` directly with user-supplied input. Consider + alternate + methods such as a lookup table to take user input and resolve hardcoded values. + + Later versions of SpringFramework introduced a `SimpleEvaluationContext` which can be + used to access bound data when calling the `getValue` result of `parseExpression`. This + `SimpleEvaluationContext` has a reduced set of functionality and can restrict data binding + to read-only or read-write contexts. An adversary could still access public properties + or fields on custom types that have been provided to the evaluation context. Use with caution. + + Example using `SimpleEvaluationContext` with a read-write data binding context: + ``` + @RequestMapping(value="/spel", method=RequestMethod.POST) + public String spel(@Validated User user, Model model) { + // Create the Expression Parser + SpelExpressionParser parser = new SpelExpressionParser(); + // Parse the expression + Expression parsedExpression = parser.parseExpression(model.getPossiblyUnsafeData()); + // Create the read-write data binding context + SimpleEvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build(); + // Execute the expression, passing in the read-write context + Object result = parsedExpression.getValue(context); + // work with the result + // ... + return "user"; + } + ``` + + For more information on SimpleEvaluationContext see: + https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/expression/spel/support/SimpleEvaluationContext.html + metadata: + category: security + cwe: CWE-917 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an expression language statement ('Expression Language Injection') + patterns: + - pattern: ($PARSER $P).$METHOD($ARG); + - pattern-not: ($PARSER $P).$METHOD("..."); + - metavariable-pattern: + metavariable: $PARSER + pattern-either: + - pattern: org.springframework.expression.spel.standard.SpelExpressionParser + - pattern: org.springframework.expression.ExpressionParser + - metavariable-regex: + metavariable: $METHOD + regex: (parseExpression|parseRaw) + severity: ERROR + - id: java_smtp_rule-InsecureSmtp + languages: + - java + message: | + The Apache commons mail client by default does not enable TLS server identity. + This allows for an adversary who is in between the application and the target host to intercept + potentially sensitive information or transmit malicious data. + + Enable checking server identity by calling `Email.setSSLCheckServerIdentity(true)` + + Example email client that enables TLS and server identity: + ``` + // Create an email client + Email email = new SimpleEmail(); + // Configure the email hostname + email.setHostName("smtp.mail.example.com"); + // Set the port + email.setSmtpPort(465); + // Securely retrieve username and password values + String username = getUserNameFromKMSorSecretStore(); + String password = getPasswordFromKMSorSecretStore(); + // Configure the Authenticator + DefaultAuthenticator auth = new DefaultAuthenticator(username, password); + // Set the authenticator + email.setAuthenticator(auth); + // Ensure we use SSL on connect + email.setSSLOnConnect(true); + // Ensure we validate server identity + email.setSSLCheckServerIdentity(true); + // configure the rest of the email + email.setFrom("x@example.com"); + email.setSubject("TestMail"); + email.setMsg("This is a test mail ... :-)"); + email.addTo("y@example.com"); + email.send(); + ``` + metadata: + category: security + cwe: CWE-297 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Improper validation of certificate with host mismatch + patterns: + - pattern-either: + - pattern-inside: | + $E = new org.apache.commons.mail.SimpleEmail(...); ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W(...) + - pattern-inside: | + $E = new org.apache.commons.mail.Email(...); ... - $INTERM = $STR % (..., $DATA, ...) + - pattern-inside: | + $E = new org.apache.commons.mail.MultiPartEmail(...); ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W[...] + - pattern-inside: | + $E = new org.apache.commons.mail.HtmlEmail(...); ... - $INTERM = $STR % (..., $DATA, ...) + - pattern-inside: | + $E = new org.apache.commons.mail.ImageHtmlEmail(...); ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern-not: | + $E.setSSLOnConnect(true); + ... + $E.setSSLCheckServerIdentity(true); + severity: ERROR + - id: java_smtp_rule-SmtpClient + languages: + - java + message: | + The application was found calling `MimeMessage` methods without encoding + new line characters. Much like HTTP, Simple Mail Transfer Protocol (SMTP) is a + text based protocol that uses headers to convey additional directives for how + email messages should be treated. An adversary could potentially cause email + messages to be sent to unintended recipients by abusing the CC or BCC headers + if they were able to inject them. + + To mitigate this issue, `\r\n` (CRLF) character sequences must be escaped + or encoded prior to being used in any of the `MimeMessage` methods. + + Example that escapes values that come from user input with + [Apache Commons Text](https://commons.apache.org/proper/commons-text/): + ``` + // Create a MimeMessage with a javax.mail.Session + Message message = new MimeMessage(session); + // Set the from address + message.setFrom(new InternetAddress("source@example.com")); + // Set the to address + message.setRecipients(Message.RecipientType.TO,new InternetAddress[] {new + InternetAddress("destination@example.com")}); + // Example user input + String subject = "potentially malicious data"; + String headerValue = "potentially malicious data"; + // Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \\r\\n. + message.setSubject(StringEscapeUtils.escapeJava(subject)); + // Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \\r\\n. + message.addHeader("HeaderName", StringEscapeUtils.escapeJava(header)); + // Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \\r\\n. + message.setDescription(StringEscapeUtils.escapeJava("some description")); + // Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \\r\\n. + message.setDisposition(StringEscapeUtils.escapeJava("some disposition")); + // Set the mail body text + message.setText("Some email content."); + // Send the message + ``` + metadata: + category: security + cwe: CWE-77 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Low + shortDescription: Improper neutralization of special elements used in a command + patterns: + - pattern-inside: | + $M = new MimeMessage(...); + ... + - pattern-either: + - patterns: + - pattern-either: + - pattern: $M.setSubject($VAR) + - pattern: $M.addHeader($ARG, $VAR) + - pattern: $M.addHeader($VAR, $ARG) + - pattern: $M.setDescription($VAR) + - pattern: $M.setDisposition($VAR) + - metavariable-regex: + metavariable: $VAR + regex: ^[a-zA-Z_$][a-zA-Z0-9_$]*$ + - patterns: + - pattern-either: + - pattern: $M.setSubject($OBJ.$GETTER(...)) + - pattern: $M.setSubject($OBJ.$GETTER(...) + ...) + - pattern: $M.setSubject(... + $OBJ.$GETTER(...)) + - pattern: $M.setSubject(... + $OBJ.$GETTER(...) + ...) + - pattern: $M.addHeader($ARG, $OBJ.$GETTER(...)) + - pattern: $M.addHeader($ARG, $OBJ.$GETTER(...) + ...) + - pattern: $M.addHeader($ARG, ... + $OBJ.$GETTER(...)) + - pattern: $M.addHeader($ARG, ... + $OBJ.$GETTER(...) + ...) + - pattern: $M.addHeader($OBJ.$GETTER(...), $ARG) + - pattern: $M.addHeader($OBJ.$GETTER(...) + ..., $ARG) + - pattern: $M.addHeader(... + $OBJ.$GETTER(...), $ARG) + - pattern: $M.addHeader(... + $OBJ.$GETTER(...) + ..., $ARG) + - pattern: $M.setDescription($OBJ.$GETTER(...)) + - pattern: $M.setDisposition($OBJ.$GETTER(...) + ...) + - pattern: $M.setDisposition(... + $OBJ.$GETTER(...)) + - pattern: $M.setDisposition(... + $OBJ.$GETTER(...) + ...) + - metavariable-regex: + metavariable: $GETTER + regex: ^get + severity: ERROR + - id: java_ssrf_rule-SSRF + languages: + - java + message: | + Server-Side-Request-Forgery (SSRF) exploits backend systems that initiate requests to third + parties. + If user input is used in constructing or sending these requests, an attacker could supply + malicious + data to force the request to other systems or modify request data to cause unwanted actions. + + Ensure user input is not used directly in constructing URLs or URIs when initiating requests + to third party + systems from back end systems. Care must also be taken when constructing payloads using user + input. Where + possible restrict to known URIs or payloads. Consider using a server-side map where keys are + used to return + URLs such as `https://site/goto?key=1` where `{key: 1, url: 'http://some.url/', key: 2, url: + 'http://...'}`. + + If you must use user-supplied input for requesting URLs, it is strongly recommended that the + HTTP client + chosen allows you to customize and block certain IP ranges at the network level. By blocking + RFC 1918 + addresses or other network address ranges, you can limit the severity of a successful SSRF + attack. Care must + also be taken to block certain protocol or address formatting such as IPv6. + + If you cannot block address ranges at the client level, you may want to run the HTTP client + as a protected + user, or in a protected network where you can apply IP Table or firewall rules to block access + to dangerous + addresses. Finally, if none of the above protections are available, you could also run a + custom HTTP proxy + and force all requests through it to handle blocking dangerous addresses. + + Example using a map to look up a key to be used in a HTTP request: + ``` + HashMap lookupTable = new HashMap<>(); + lookupTable.put("key1", "https://example.com/"); + lookupTable.put("key2", "https://safeurl.com/"); + String userInput = request.getParameter("key"); + + // Create a CloseableHttpClient, ideally any requests issued should be done + // out-of-band from the servlet request itself (such as using a separate thread/scheduler + system) + try (final CloseableHttpClient httpClient = HttpClients.createDefault()) { + // Lookup the value from our user input from our lookupTable + String value = lookupTable.getOrDefault(userInput, "https://example.com/"); + // Construct the url, with the hardcoded url and only pass in the value from the + lookupTable, + // not direct user input + final HttpGet httpget = new HttpGet(value); + // Execute the request + CloseableHttpResponse clientResponse = httpClient.execute(httpget); + // Read the response + byte[] responseData = clientResponse.getEntity().getContent().readAllBytes(); + // Handle the response + // ... + } + ``` + + If using a map is not possible, the user-supplied input must be encoded prior to use, and + never allow full + URLs: + ``` + // Get user input + String userInput = request.getParameter("key"); + // Encode the string using java.net.URLEncoder with the UTF-8 character set + String encodedString = java.net.URLEncoder.encode(userInput, StandardCharsets.UTF_8); + // Create a CloseableHttpClient, ideally any requests issued should be done + // out-of-band from the servlet request itself (such as using a separate thread/scheduler + system) + try (final CloseableHttpClient httpClient = HttpClients.createDefault()) { + // Construct the url, with the hardcoded url and only pass in the encoded value, never a + full URL + final HttpGet httpget = new HttpGet("https://example.com/getId?key="+encodedString); + // Execute the request + CloseableHttpResponse clientResponse = httpClient.execute(httpget); + // Read the response + byte[] responseData = clientResponse.getEntity().getContent().readAllBytes(); + // handle the response + } + ``` + + For more information on SSRF see OWASP: + https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-918 + owasp: + - A1:2017-Injection + - A10:2021-Server-Side Request Forgery + security-severity: Medium + shortDescription: Server-Side Request Forgery (SSRF) + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + import java.net.*; + ... + - pattern-inside: | + import java.net.URL; + ... + - pattern-inside: | + import java.net.URI; + ... + - pattern: new $TYPE(...). ... .$FUNC + - pattern-not: new $TYPE("..."). ... .$FUNC + - metavariable-pattern: + metavariable: $FUNC + pattern-either: + - pattern: connect + - pattern: GetContent + - pattern: openConnection + - pattern: openStream + - pattern: getContent + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: URL + - pattern: java.net.URL + - pattern: URI + - pattern: java.net.URI + - patterns: + - pattern-either: + - pattern-inside: | + import java.net.*; + ... + - pattern-inside: | + import java.net.InetSocketAddress; + ... - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - severity: WARNING - - id: python.django.security.injection.sql.sql-injection-rawsql.sql-injection-using-rawsql + new InetSocketAddress(..., $PORT) + - pattern-not: | + new InetSocketAddress("...", $PORT) + severity: ERROR + - id: java_strings_rule-BadHexConversion languages: - - python - message: User-controlled data from request is passed to 'RawSQL()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use parameterized queries or escape the user-controlled data by using `params` and not using quote placeholders in the SQL string. + - java + message: | + The application is using `Integer.toHexString` on a digest array buffer which + may lead to an incorrect version of values. + + Consider using the `java.util.HexFormat` object introduced in Java 17. For older Java applications + consider using the `javax.xml.bind.DatatypeConverter`. + + Example using `HexFormat` to create a human-readable string: + ``` + // Create a MessageDigest using the SHA-384 algorithm + MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384"); + // Call update with your data + sha384Digest.update("some input".getBytes(StandardCharsets.UTF_8)); + // Only call digest once all data has been fed into the update sha384digest instance + byte[] output = sha384Digest.digest(); + // Create a JDK 17 HexFormat object + HexFormat hex = HexFormat.of(); + // Use formatHex on the byte array to create a string (note that alphabet characters are + lowercase) + String hexString = hex.formatHex(output); + ``` + + For more information on DatatypeConverter see: + https://docs.oracle.com/javase/9/docs/api/javax/xml/bind/DatatypeConverter.html#printHexBinary-byte:A- metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + confidence: HIGH + cwe: CWE-704 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.0/ref/models/expressions/#django.db.models.expressions.RawSQL - subcategory: - - vuln - technology: - - django + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Info + shortDescription: Incorrect type conversion or cast patterns: - pattern-inside: | - def $FUNC(...): - ... + $B_ARR = (java.security.MessageDigest $MD).digest(...); + ... - pattern-either: - - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W.get(...), ...) - - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W.get(...)}...", ...) - - pattern: django.db.models.expressions.RawSQL(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W.get(...), ...) - - pattern: return django.db.models.expressions.RawSQL(..., request.$W.get(...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W(...), ...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W(...), ...) - - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W(...)}...", ...) - - pattern: django.db.models.expressions.RawSQL(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) + for(...) { + ... + $B = $B_ARR[...]; + ... + Integer.toHexString($B); + } - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) + for(...) { + ... + Integer.toHexString($B_ARR[...]); + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W(...), ...) - - pattern: return django.db.models.expressions.RawSQL(..., request.$W(...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W[...], ...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W[...], ...) - - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W[...]}...", ...) - - pattern: django.db.models.expressions.RawSQL(..., request.$W[...], ...) + for(byte $B :$B_ARR) { + ... + Integer.toHexString($B); + } - pattern: | - $DATA = request.$W[...] - ... - django.db.models.expressions.RawSQL(..., $DATA, ...) + while(...) { + ... + Integer.toHexString($B_ARR[...]) + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) + do { + ... + Integer.toHexString($B_ARR[...]) + } while(...) - pattern: | - $DATA = request.$W[...] - ... - django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) + while(...) { + ... + $B = $B_ARR[...]; + ... + Integer.toHexString($B); + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) + do { + ... + $B = $B_ARR[...]; + ... + Integer.toHexString($B); + } while(...) + severity: WARNING + - id: java_strings_rule-FormatStringManipulation + languages: + - java + message: | + The application allows user input to control format string parameters. By passing invalid + format + string specifiers an adversary could cause the application to throw exceptions or possibly + leak + internal information depending on application logic. + + Never allow user-supplied input to be used to create a format string. Replace all format + string + arguments with hardcoded format strings containing the necessary specifiers. + + Example of using `String.format` safely: + ``` + // Get untrusted user input + String userInput = request.getParameter("someInput"); + // Ensure that user input is not included in the first argument to String.format + String.format("Hardcoded string expecting a string: %s", userInput); + // ... + ``` + metadata: + category: security + confidence: HIGH + cwe: CWE-134 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Use of externally-controlled format string + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + String $INPUT = (HttpServletRequest $REQ).getParameter(...); + ... + - pattern-inside: | + String $FORMAT_STR = ... + $INPUT; + ... + - patterns: + - pattern-inside: | + String $INPUT = (HttpServletRequest $REQ).getParameter(...); + ... + - pattern-inside: | + String $FORMAT_STR = ... + $INPUT + ...; + ... + - pattern-inside: | + String $FORMAT_STR = ... + (HttpServletRequest $REQ).getParameter(...) + ...; ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] + - pattern-inside: | + String $FORMAT_STR = ... + (HttpServletRequest $REQ).getParameter(...); ... - django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] + - pattern-either: + - pattern: String.format($FORMAT_STR, ...); + - pattern: String.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern: (java.util.Formatter $F).format($FORMAT_STR, ...); + - pattern: (java.util.Formatter $F).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern: (java.io.PrintStream $F).printf($FORMAT_STR, ...); + - pattern: (java.io.PrintStream $F).printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern: (java.io.PrintStream $F).format($FORMAT_STR, ...); + - pattern: (java.io.PrintStream $F).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern: System.out.printf($FORMAT_STR, ...); + - pattern: System.out.printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern: System.out.format($FORMAT_STR, ...); + - pattern: System.out.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + severity: ERROR + - id: java_strings_rule-ModifyAfterValidation + languages: + - java + message: |+ + The application was found matching a variable during a regular expression + pattern match, and then calling string modification functions after validation has occurred. + This is usually indicative of a poor input validation strategy as an adversary may attempt to + exploit the removal of characters. + + For example a common mistake in attempting to remove path characters to protect against path + traversal is to match '../' and then remove any matches. However, if an adversary were to + include in their input: '....//' then the `replace` method would replace the first `../` but + cause the leading `..` and trailing `/` to join into the final string of `../`, effectively + bypassing the check. + + To remediate this issue always perform string modifications before any validation of a string. + It is strongly recommended that strings be encoded instead of replaced or removed prior to + validation. + + + Example replaces `..` before validation. Do note this is still not a recommended method for + protecting against directory traversal, always use randomly generated IDs or filenames instead: + ``` + // This is ONLY for demonstration purpose, never use untrusted input + // in paths, always use randomly generated filenames or IDs. + String input = "test../....//dir"; + // Use replaceAll _not_ replace + input = input.replaceAll("\\.\\.", ""); + // Input would be test///dir at this point + // Create a pattern to match on + Pattern pattern = Pattern.compile("\\.\\."); + // Create a matcher + Matcher match = pattern.matcher(input); + // Call find to see if .. is still in our string + if (match.find()) { + throw new Exception(".. detected"); + } + // Use the input (but do not modify the string) + System.out.println(input + " safe"); + ``` + + For more information see Carnegie Mellon University's Secure Coding Guide: + https://wiki.sei.cmu.edu/confluence/display/java/IDS11-J.+Perform+any+string+modifications+before+validation + + metadata: + category: security + confidence: HIGH + cwe: CWE-182 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Info + shortDescription: Collapse of data into unsafe value + patterns: + - pattern: | + (java.util.regex.Pattern $Y).matcher($VAR); + ... + $VAR.$METHOD(...); + - metavariable-regex: + metavariable: $METHOD + regex: (replace|replaceAll|replaceFirst|concat) + severity: WARNING + - id: java_strings_rule-NormalizeAfterValidation + languages: + - java + message: | + The application was found matching a variable during a regular expression + pattern match, and then calling a Unicode normalize function after validation has occurred. + This is usually indicative of a poor input validation strategy as an adversary may attempt to + exploit the normalization process. + + To remediate this issue, always perform Unicode normalization before any validation of a + string. + + Example of normalizing a string before validation: + ``` + // User input possibly containing malicious unicode + String userInput = "\uFE64" + "tag" + "\uFE65"; + // Normalize the input + userInput = Normalizer.normalize(userInput, Normalizer.Form.NFKC); + // Compile our regex pattern looking for < or > characters + Pattern pattern = Pattern.compile("[<>]"); + // Create a matcher from the userInput + Matcher matcher = pattern.matcher(userInput); + // See if the matcher matches + if (matcher.find()) { + // It did so throw an error + throw new Exception("found banned characters in input"); + } + ``` + + For more information see Carnegie Mellon University's Secure Coding Guide: + https://wiki.sei.cmu.edu/confluence/display/java/IDS01-J.+Normalize+strings+before+validating+them + metadata: + category: security + confidence: HIGH + cwe: CWE-180 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Info + shortDescription: 'Incorrect behavior order: validate before canonicalize' + patterns: + - pattern: | + $Y = java.util.regex.Pattern.compile("[<>]"); + ... + $Y.matcher($VAR); + ... + java.text.Normalizer.normalize($VAR, ...); + severity: WARNING + - id: java_templateinjection_rule-TemplateInjection + languages: + - java + message: | + The application may allow control over a template string. Providing user input directly in the + template by + dynamically creating template strings may allow an adversary to execute arbitrary Java code, + including + OS system commands. + + For Velocity, never call `evaluate` with user-supplied input in the template string. Use a + `VelocityContext` + object instead to data-bind user-supplied information as it will be treated as an underlying + data type and not + template code. + + Example using Apache Velocity's `VelocityContext` and escape tools to pass in user-supplied + data to a template: + ``` + // Create a tool manager + ToolManager manager = new ToolManager(true); + // Create a context from the tool manager + Context context = manager.createContext(); + // For demonstration purposes, alternatively configure from a properties file + context.put("esc", new EscapeTool()); + // For demonstration purposes, create an output buffer + StringWriter stringWriter = new StringWriter(); + // Get userInput + String userInput = "potentially malicious data"; + // Use the context to pass in the userInput value + context.put("userInput", userInput); + // Pass in the context, the output buffer, a logtag (demo), and the template with userInput + // making sure to escape it if in the context of HTML. + Velocity.evaluate(context, stringWriter, "demo", "Hello $esc.html($userInput)"); + // Work with the output buffer + // ... + ``` + + For other templating engines, please see your framework's documentation. + metadata: + category: security + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper control of generation of code ('Code Injection') + pattern-either: + - patterns: + - pattern: org.apache.velocity.app.Velocity.evaluate(..., $VAR) + - pattern-not: org.apache.velocity.app.Velocity.evaluate(..., "...") + - patterns: + - pattern-not-inside: | + $C = (freemarker.template.Configuration $CFG).getTemplate("..."); ... - $INTERM = $STR % $DATA + - pattern-inside: | + $C = (freemarker.template.Configuration $CFG).getTemplate($IN); ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] + - pattern: $C.process(...) + - patterns: + - pattern-inside: | + import com.mitchellbosecke.pebble.PebbleEngine; ... - django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] + - pattern-inside: | + $C = $T.getTemplate($IN); ... - $INTERM = f"...{$DATA}..." + - pattern-not-inside: | + $C = $T.getTemplate("..."); ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] + - pattern: $C.evaluate(...) + severity: ERROR + - id: java_unsafe_rule-ExternalConfigControl + languages: + - java + message: | + The application was found using user-supplied input in a `java.sql.Connection`'s + `setCatalog` call. This could allow an adversary to supply a different database for the + lifetime of the connection. Allowing external control of system settings can disrupt service + or cause an application to behave in unexpected, and potentially malicious ways. Most likely + this would only cause an error by providing a nonexistent catalog name. + + It is recommended to not use user-supplied input when selecting the database for an + applications + database connection. + metadata: + category: security + cwe: CWE-15 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Low + shortDescription: External control of system or configuration setting + technology: + - java + patterns: + - pattern: | + $TAINTED = (HttpServletRequest $REQ).getParameter(...); + ... + (java.sql.Connection $CONN).setCatalog($TAINTED); + severity: WARNING + - id: java_xml_rule-SAMLIgnoreComments + languages: + - java + message: "SAML parses attestations as an XML document. By processing XML comments, comment\nfields can end up modifying the interpretation of input fields. This could allow\nan adversary to insert an XML comment to break up the attestation's username\nor other fields, allowing an attacker to bypass authorization or authentication checks.\n\nTo remediate this issue, when using `org.opensaml.xml.parse.BasicParserPool` ensure\n`setIgnoreComments(false)` is not called.\n\nThe default value of `ignoreComments` is true, which is safe. \n\nRef:\n- https://javadoc.io/doc/org.opensaml/xmltooling/latest/org/opensaml/xml/parse/BasicParserPool.html#ignoreComments\n\nFor more information on how this issue can be exploited see:\nhttps://developer.okta.com/blog/2018/02/27/a-breakdown-of-the-new-saml-authentication-bypass-vulnerability\n\nFor more information on SAML security see OWASP:\nhttps://cheatsheetseries.owasp.org/cheatsheets/SAML_Security_Cheat_Sheet.html\n" + metadata: + category: security + cwe: CWE-1390 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Weak authentication + pattern: (org.opensaml.xml.parse.BasicParserPool $POOL).setIgnoreComments(false); + severity: WARNING + - id: java_xml_rule-XmlDecoder + languages: + - java + message: | + Deserialization attacks exploit the process of reading serialized data and turning it back + into an object. By constructing malicious objects and serializing them, an adversary may + attempt to: + + - Inject code that is executed upon object construction, which occurs during the + deserialization process. + - Exploit mass assignment by including fields that are not normally a part of the serialized + data but are read in during deserialization. + + Consider safer alternatives such as serializing data in the JSON format. Ensure any format + chosen allows + the application to specify exactly which object types are allowed to be deserialized. + Additionally, when + deserializing, never deserialize to base object types like `Object` and only cast to the exact + object + type that is expected. + + To protect against mass assignment, only allow deserialization of the specific fields that are + required. If this is not easily done, consider creating an intermediary type that + can be serialized with only the necessary fields exposed. + + Do note that `XMLEncoder` and `XMLDecoder` are not recommended. If the application must + use this serialization method, use a custom ClassLoader to prevent loading of arbitrary + classes: + ``` + XMLDecoder decoder = new XMLDecoder(inputStream, null, null, new ClassLoader() { + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + if (!name.equals(NameOfBeanHere.class.getName()) && + !name.equals(XMLDecoder.class.getName())) { + throw new RuntimeException("Unauthorized deserialization attempt: " + name); + } + + return super.loadClass(name, resolve); + } + }); + ``` + + For more information on XML security see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java + + For more details on deserialization attacks in general, see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + + It should be noted that [tools exist](https://github.com/frohoff/ysoserial) to + automatically create + exploit code for these vulnerabilities. + metadata: + category: security + cwe: CWE-502 + owasp: + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: High + shortDescription: Deserialization of untrusted data + patterns: + - pattern: | + (java.beans.XMLDecoder $D).readObject(); + - pattern-not: + pattern-either: + - patterns: + - pattern-inside: | + java.beans.XMLDecoder $DEC = new java.beans.XMLDecoder(..., $CL); + ... + - pattern: $DEC.readObject(); + - metavariable-pattern: + metavariable: $CL + patterns: + - pattern: | + new ClassLoader(){ + ... + $RET loadClass(String name, boolean resolve){ + if($X){ + throw ... + } + ... + } + ... + } + - metavariable-pattern: + metavariable: $X + pattern-either: + - pattern: | + !name.equals(...) + - pattern: | + !$LIST.contains(name) + - patterns: + - pattern-inside: | + ClassLoader $CLASS_LOADER = $CL; + ... + java.beans.XMLDecoder $DEC = new java.beans.XMLDecoder(..., $CLASS_LOADER); + ... + - pattern: $DEC.readObject(); + - metavariable-pattern: + metavariable: $CL + patterns: + - pattern: | + new ClassLoader(){ + ... + $RET loadClass(String name, boolean resolve){ + if($X){ + throw ... + } + ... + } + ... + } + - metavariable-pattern: + metavariable: $X + pattern-either: + - pattern: | + !name.equals(...) + - pattern: | + !$LIST.contains(name) + severity: WARNING + - id: java_xml_rule-XsltTransform + languages: + - java + message: | + The application performs XSLT translation with potentially malicious input. An adversary who + is able to influence the + loaded + XSL document could call XSL functions or exploit External XML Entity (XXE) attacks that allow + file + retrieval or force the parser to connect to arbitrary servers to exfiltrate files. It is + strongly + recommended that an alternative approach is used to work with XML data. + + For increased security, never process user-supplied XSL style sheets. If XSLT processing is + absolutely + necessary, ensure that `FEATURE_SECURE_PROCESSING` is enabled prior to processing the XSLT + file: + ``` + // Create a new TransformerFactory instance + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + // Enable the FEATURE_SECURE_PROCESSING feature + transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + // Read in the XML Source + Source xmlSource = new StreamSource(new FileInputStream("hardcoded.xml")); + // Read in the XSL template file + Source xslSource = new StreamSource(new FileInputStream("hardcoded.xsl")); + /// Create the transformer object to do the transformation + Transformer transformer = transformerFactory.newTransformer(xslSource); + // Create a Result object for output + Result result = new StreamResult(System.out); + // Execute the transformation process + transformer.transform(xmlSource, result); + ``` + + For more information on XML security see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java + + For more information on the secure processing feature see: + - https://xml.apache.org/xalan-j/features.html#secureprocessing + metadata: + category: security + cwe: CWE-91 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: XML injection (aka Blind XPath injection) + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: (javax.xml.transform.TransformerFactory $T).newTransformer($SRC, ...) + - pattern-inside: (javax.xml.transform.Transformer $T).transform($SRC, ...) + - pattern: $SRC + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $FUNC(...,String $VAR, ...) { + ... + } + - pattern-either: + - pattern: new FileInputStream(<... $VAR ...>); + - pattern: getClass().getResourceAsStream(<... $VAR ...>) + - patterns: + - pattern-inside: | + class $CLZ { + String $X = "..."; + ... + } + - pattern-inside: | + $FUNC(...,String $Y, ...) { + ... + } + - pattern-either: + - pattern: new FileInputStream($X + $Y); + - pattern: getClass().getResourceAsStream($X + $Y) + severity: WARNING + - id: java_xss_rule-WicketXSS + languages: + - java + message: | + The application is disabling Wicket's string escaping functionality by calling + `setEscapeModelStrings(false)`. + This could lead to Cross Site Scripting (XSS) if used with user-supplied input. XSS is an + attack which exploits + a web application or system to treat user input + as markup or script code. It is important to encode the data depending on the specific context + it + is used in. There are at least six context types: + + - Inside HTML tags `
context 1
` + - Inside attributes: `
` + - Inside event attributes `` + - Inside script blocks: `` + - Unsafe element HTML assignment: `element.innerHTML = "context 5"` + - Inside URLs: `link` + + Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if + user input + is ever output inside of script tags. + + User input that is displayed within the application must be encoded, sanitized or validated + to ensure it cannot be treated as HTML or executed as JavaScript code. Care must also be + taken + to not mix server-side templating with client-side templating, as the server-side templating + will + not encode things like {{ 7*7 }} which may execute client-side templating features. + + It is _NOT_ advised to encode user input prior to inserting into a data store. The data will + need to be + encoded depending on context of where it is output. It is much safer to force the displaying + system to + handle the encoding and not attempt to guess how it should be encoded. + + Use Wicket's built in escaping feature by calling `Component.setEscapeModelStrings(true);` + + For more information on Wicket components see: + - https://nightlies.apache.org/wicket/apidocs/9.x/org/apache/wicket/Component.html + + For more information on XSS see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-79 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + patterns: + - pattern-inside: | + import org.apache.wicket.$A; + ... + - pattern: | + $OBJ.setEscapeModelStrings(false); + severity: WARNING + - id: java_xss_rule-XSSReqParamToServletWriter + languages: + - java + message: | + The application is returning user-supplied data from an HTTP request directly into an HTTP + response output + writer. This could lead to Cross Site Scripting (XSS) if the input were malicious + script code and the application server is not properly validating the output. + + XSS is an attack which exploits a web application or system to treat user input + as markup or script code. It is important to encode the data depending on the specific context + it is used in. There are at least six context types: + + - Inside HTML tags `
context 1
` + - Inside attributes: `
` + - Inside event attributes `` + - Inside script blocks: `` + - Unsafe element HTML assignment: `element.innerHTML = "context 5"` + - Inside URLs: `link` + + Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if + user input + is ever output inside of script tags. + + User input that is displayed within the application must be encoded, sanitized or validated + to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be + taken + to not mix server-side templating with client-side templating, as the server-side templating + will + not encode things like {{ 7*7 }} which may execute client-side templating features. + + It is _NOT_ advised to encode user input prior to inserting into a data store. The data will + need to be + encoded depending on context of where it is output. It is much safer to force the displaying + system to + handle the encoding and not attempt to guess how it should be encoded. + + If possible do not use user input directly in the output to the response writer. + + If the application must output user-supplied input, it will need to encode the data depending + on + the output context. + + Consider using [Apache Commons Text](https://commons.apache.org/proper/commons-text/) + `StringEscapeUtils` methods for various context. Please note there is no way to safely + output script code in most circumstances, regardless of encoding. If calling the HTTP + response writer directly, ensure that the `Content-Type` is set to `text/plain` so it will + not be accidentally interpreted by HTML by modern browsers. + ``` + // Get user input + String htmlInput = request.getParameter("userInput"); + // Encode the input using the Html4 encoder + String htmlEncoded = StringEscapeUtils.escapeHtml4(htmlInput); + // Force the HTTP response to be content type of text/plain so it is not interpreted as HTML + response.setContentType("text/plain"); + // Ensure UTF-8 + response.setCharacterEncoding("UTF-8"); + // Write response + response.getWriter().write(htmlEncoded); + ``` + + For more information on XSS see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-79 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + technology: + - java + mode: taint + pattern-propagators: + - from: $X + pattern: $LIST.add($X) + to: $LIST + - from: $X + pattern: $MAP.put(..., $X) + to: $MAP + - from: $X + pattern: $STR.concat($X) + to: $STR + - from: $X + pattern: $STR = String.format(..., $X, ...) + to: $STR + - from: $X + pattern: $STR = String.join(..., $X, ...) + to: $STR + pattern-sanitizers: + - pattern: org.owasp.encoder.Encode.forHtml(...) + - pattern: org.owasp.esapi.ESAPI.encoder().encodeForHTML(...) + - pattern: org.apache.commons.text.StringEscapeUtils.escapeHtml3(...) + - pattern: org.apache.commons.text.StringEscapeUtils.escapeHtml4(...) + - pattern: org.owasp.benchmark.helpers.Utils.encodeForHTML(...) + pattern-sinks: + - pattern: (javax.servlet.http.HttpServletResponse $R).getWriter().print(...) + - patterns: + - pattern-inside: | + $W = (javax.servlet.http.HttpServletResponse $R).getWriter(); ... - django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] + - pattern: $W.print(...); + - pattern: (javax.servlet.http.HttpServletResponse $R).getWriter().println(...) + - patterns: + - pattern-inside: | + $W = (javax.servlet.http.HttpServletResponse $R).getWriter(); ... - $INTERM = $STR + $DATA + - pattern: $W.println(...); + - pattern: (javax.servlet.http.HttpServletResponse $R).getWriter().format(...) + - patterns: + - pattern-inside: | + $W = (javax.servlet.http.HttpServletResponse $R).getWriter(); ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W[...], ...) - - pattern: return django.db.models.expressions.RawSQL(..., request.$W[...], ...) - - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W, ...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W, ...) - - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W}...", ...) - - pattern: django.db.models.expressions.RawSQL(..., request.$W, ...) - - pattern: | - $DATA = request.$W + - pattern: $W.format(...); + - pattern: (javax.servlet.http.HttpServletResponse $R).getWriter().append(...) + - patterns: + - pattern-inside: | + $W = (javax.servlet.http.HttpServletResponse $R).getWriter(); ... - django.db.models.expressions.RawSQL(..., $DATA, ...) - - pattern: | - $DATA = request.$W + - pattern: $W.append(...); + - pattern: (javax.servlet.http.HttpServletResponse $R).getWriter().write(...) + - patterns: + - pattern-inside: | + $W = (javax.servlet.http.HttpServletResponse $R).getWriter(); ... - $INTERM = $DATA + - pattern: $W.write(...); + pattern-sources: + - pattern: (javax.servlet.http.HttpServletRequest $R).$METHOD(...) + - pattern: (java.util.Scanner $S).$METHOD(...) + - pattern: (java.util.stream.Stream).$METHOD(...) + - pattern: (java.util.StringJoiner $SJ).toString(...) + - pattern: (java.sql.ResultSet.getString $R).$METHOD(...) + - pattern: (java.lang.System $S).getProperty(...) + - pattern: (java.lang.System $S).getenv(...) + - pattern: (java.lang.StringBuilder $SB).toString(...) + - pattern: (java.io.FileInputStream $F).read(...) + - pattern: (java.io.FileReader $F).read(...) + - pattern: (java.net.Socket $S).getInputStream(...) + - pattern: (java.net.Socket $S).getOutputStream(...) + - pattern: (java.net.DatagramSocket $S).receive(...) + - pattern: (java.net.DatagramSocket $S).getInputStream(...) + - pattern: java.nio.file.Files.readAllBytes(...) + - pattern: java.nio.file.Files.readAllLines(...) + - pattern: java.nio.file.Files.lines(...) + - pattern: java.nio.file.Files.newBufferedReader(...) + - pattern: org.apache.commons.io.IOUtils.toString(...) + - pattern: org.apache.commons.io.IOUtils.readLines(...) + - pattern: org.apache.commons.io.IOUtils.toByteArray(...) + - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).readValue(...) + - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).treeToValue(...) + - pattern: $CLASS.$METHOD(..., (javax.servlet.http.HttpServletRequest $R), ...) + - pattern: $FUNC(..., (javax.servlet.http.HttpServletRequest $R), ...) + - patterns: + - pattern-inside: $FUNC(..., String $X, ...) { ... } + - focus-metavariable: $X + severity: WARNING + - id: java_xxe_rule-XMLRdr + languages: + - java + message: | + External XML entities are a feature of XML parsers that allow documents to contain references + to + other documents or data. This feature can be abused to read files, communicate with external + hosts, + exfiltrate data, or cause a Denial of Service (DoS). + + The XMLReaderFactory has been deprecated. It is recommended that + [SAXParserFactory](https://docs.oracle.com/javase/9/docs/api/javax/xml/parsers/SAXParserFactory.html) + be used + instead. Additionally when using the SAXParser it must be configured to disallow doctypes, + which will + protect against the majority of XXE attacks. + + Example creating a SAXParser with disallowing the doctypes feature enabled: + ``` + // Create a SAXParserFactory + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + // Enable the feature which disallows context 1` + - Inside attributes: `
` + - Inside event attributes `` + - Inside script blocks: `` + - Unsafe element HTML assignment: `element.innerHTML = "context 5"` + - Inside URLs: `link` + + Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if + user input + is ever output inside of script tags. + + User input that is displayed within the application must be encoded, sanitized or validated + to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be + taken + to not mix server-side templating with client-side templating, as the server-side templating + will + not encode things like {{ 7*7 }} which may execute client-side templating features. + + It is _NOT_ advised to encode user input prior to inserting into a data store. The data will + need to be + encoded depending on context of where it is output. It is much safer to force the displaying + system to + handle the encoding and not attempt to guess how it should be encoded. + + Remove the call to `dangerouslySetInnerHTML` or ensure that the data used in this call does + not come from user-supplied input. + + For more information on dangerously setting inner HTML see: + - https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html + metadata: + category: security + cwe: CWE-79 + owasp: + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + pattern-either: + - pattern: | + <$X dangerouslySetInnerHTML=... /> + - pattern: | + {dangerouslySetInnerHTML: ...} + severity: WARNING + - id: javascript_require_rule-non-literal-require + languages: + - javascript + - typescript + message: | + The application was found to dynamically import a module by calling `require` using a + non-literal string. An adversary might be able to read the first line of + arbitrary files. If they had write access to the file system, they may also be able to + execute arbitrary code. + + To remediate this issue, use a hardcoded string literal when calling `require`. Never call it + it with dynamically created variables or user-supplied data. + metadata: + category: security + cwe: CWE-95 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Low + shortDescription: Improper neutralization of directives in dynamically evaluated code ('Eval Injection') + source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-require.js + patterns: + - pattern: require($OBJ) + - pattern-not: require('...') + severity: WARNING + - id: javascript_timing_rule-possible-timing-attacks + languages: + - javascript + message: | + The application was found executing string comparisons using one of `===`, `!==`, `==` or `!=` + against security sensitive values. String comparisons like this are not constant time, meaning + the + first character found not to match in the two strings will immediately exit the conditional + statement. + This allows an adversary to calculate or observe small timing differences depending on the + strings + passed to this comparison. This potentially allows an adversary the ability to brute force a + string + that will match the expected value by monitoring different character values. + + To remediate this issue, use the `crypto.timingSafeEqual` method when comparing strings. + + Example using `crypto.timingSafeEqual` to safely compare strings: + ``` + function constantTimeIsPasswordEqual(userInput) { + // Retrieve the password from a secure data store such as a KMS or Hashicorp's vault. + const password = getPasswordFromSecureDataStore(); + // Use crypto timingSafeEqual to ensure the comparison is done in constant time. + return crypto.timingSafeEqual(Buffer.from(userInput, 'utf-8'), Buffer.from(password, + 'utf-8')); + } + ``` + + For more information on constant time comparison see: + - https://nodejs.org/api/crypto.html#crypto_crypto_timingsafeequal_a_b + metadata: + category: security + cwe: CWE-208 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Observable timing discrepancy + patterns: + - pattern-not: if ($Z == null) { ... }; + - pattern-not: if ($Z === null) { ... }; + - pattern-not: if ($Z != null) { ... }; + - pattern-not: if ($Z !== null) { ... }; + - pattern-not: if ($Q != undefined) { ... }; + - pattern-not: if ($Q !== undefined) { ... }; + - pattern-not: if ($Q == undefined) { ... }; + - pattern-not: if ($Q === undefined) { ... }; + - pattern-not: return $Y == null; + - pattern-not: return $Y === null; + - pattern-not: return $Y != null; + - pattern-not: return $Y !== null; + - pattern-not: return $Y == undefined; + - pattern-not: return $Y === undefined; + - pattern-not: return $Y != undefined; + - pattern-not: return $Y !== undefined; + - pattern-either: - pattern: | - $DATA = request.$W.get(...) - ... - $CURSOR.execute(..., $STR + $DATA, ...) + if (password == $X) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: $A = $CURSOR.execute(..., request.$W.get(...), ...) - - pattern: return $CURSOR.execute(..., request.$W.get(...), ...) - - pattern: $CURSOR.execute(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $CURSOR.execute(..., $S % request.$W(...), ...) - - pattern: $CURSOR.execute(..., f"...{request.$W(...)}...", ...) - - pattern: $CURSOR.execute(..., request.$W(...), ...) + if ($X == password) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute(..., $DATA, ...) + if (password === $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X === password) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) + if (pass == $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X == pass) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute(..., $STR % $DATA, ...) + if (pass === $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X === pass) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute(..., f"...{$DATA}...", ...) + if (secret == $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X == secret) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute(..., $STR + $DATA, ...) + if (secret === $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: $A = $CURSOR.execute(..., request.$W(...), ...) - - pattern: return $CURSOR.execute(..., request.$W(...), ...) - - pattern: $CURSOR.execute(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $CURSOR.execute(..., $S % request.$W[...], ...) - - pattern: $CURSOR.execute(..., f"...{request.$W[...]}...", ...) - - pattern: $CURSOR.execute(..., request.$W[...], ...) + if ($X === secret) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute(..., $DATA, ...) + if (api == $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X == api) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) + if (api === $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X === api) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute(..., $STR % $DATA, ...) + if (apiKey == $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X == apiKey) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute(..., f"...{$DATA}...", ...) + if (apiKey === $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X === apiKey) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute(..., $STR + $DATA, ...) + if (apiSecret == $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: $A = $CURSOR.execute(..., request.$W[...], ...) - - pattern: return $CURSOR.execute(..., request.$W[...], ...) - - pattern: $CURSOR.execute(..., $S.format(..., request.$W, ...), ...) - - pattern: $CURSOR.execute(..., $S % request.$W, ...) - - pattern: $CURSOR.execute(..., f"...{request.$W}...", ...) - - pattern: $CURSOR.execute(..., request.$W, ...) + if ($X == apiSecret) { + ... + } - pattern: | - $DATA = request.$W - ... - $CURSOR.execute(..., $DATA, ...) + if (apiSecret === $X) { + ... + } - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X === apiSecret) { + ... + } - pattern: | - $DATA = request.$W - ... - $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) + if (token == $X) { + ... + } - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X == token) { + ... + } - pattern: | - $DATA = request.$W - ... - $CURSOR.execute(..., $STR % $DATA, ...) + if (token === $X) { + ... + } - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X === token) { + ... + } - pattern: | - $DATA = request.$W - ... - $CURSOR.execute(..., f"...{$DATA}...", ...) + if (hash == $X) { + ... + } - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - $CURSOR.execute(..., $INTERM, ...) + if ($X == hash) { + ... + } - pattern: | - $DATA = request.$W - ... - $CURSOR.execute(..., $STR + $DATA, ...) + if (hash === $X) { + ... + } - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: $A = $CURSOR.execute(..., request.$W, ...) - - pattern: return $CURSOR.execute(..., request.$W, ...) + if ($X === hash) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $CURSOR.execute($STR % (..., $DATA, ...), ...) + if (auth_token == $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute($STR % (..., $DATA, ...), ...) + if ($X == auth_token) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute($STR % (..., $DATA, ...), ...) + if (auth_token === $X) { + ... + } - pattern: | - $DATA = request.$W - ... - $CURSOR.execute($STR % (..., $DATA, ...), ...) + if ($X === auth_token) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $CURSOR.execute($INTERM, ...) + if (password != $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $CURSOR.execute($INTERM, ...) + if ($X != password) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $CURSOR.execute($INTERM, ...) + if (password !== $X) { + ... + } - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $CURSOR.execute($INTERM, ...) - severity: WARNING - - id: python.django.security.injection.sql.sql-injection-using-raw.sql-injection-using-raw - languages: - - python - message: Data that is possible user-controlled from a python request is passed to `raw()`. This could lead to SQL injection and attackers gaining access to protected information. Instead, use django's QuerySets, which are built with query parameterization and therefore not vulnerable to sql injection. For example, you could use `Entry.objects.filter(date=2006)`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.0/topics/security/#sql-injection-protection - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $MODEL.objects.raw(..., $S % request.$W.get(...), ...) - - pattern: $MODEL.objects.raw(..., f"...{request.$W.get(...)}...", ...) - - pattern: $MODEL.objects.raw(..., request.$W.get(...), ...) + if ($X !== password) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw(..., $DATA, ...) + if (pass != $X) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X != pass) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) + if (pass !== $X) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X !== pass) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw(..., $STR % $DATA, ...) + if (secret != $X) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X != secret) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw(..., f"...{$DATA}...", ...) + if (secret !== $X) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X !== secret) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw(..., $STR + $DATA, ...) + if (api != $X) { + ... + } - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: $A = $MODEL.objects.raw(..., request.$W.get(...), ...) - - pattern: return $MODEL.objects.raw(..., request.$W.get(...), ...) - - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $MODEL.objects.raw(..., $S % request.$W(...), ...) - - pattern: $MODEL.objects.raw(..., f"...{request.$W(...)}...", ...) - - pattern: $MODEL.objects.raw(..., request.$W(...), ...) + if ($X != api) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw(..., $DATA, ...) + if (api !== $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X !== api) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) + if (apiKey != $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X != apiKey) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw(..., $STR % $DATA, ...) + if (apiKey !== $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X !== apiKey) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw(..., f"...{$DATA}...", ...) + if (apiSecret != $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X != apiSecret) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw(..., $STR + $DATA, ...) + if (apiSecret !== $X) { + ... + } - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: $A = $MODEL.objects.raw(..., request.$W(...), ...) - - pattern: return $MODEL.objects.raw(..., request.$W(...), ...) - - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $MODEL.objects.raw(..., $S % request.$W[...], ...) - - pattern: $MODEL.objects.raw(..., f"...{request.$W[...]}...", ...) - - pattern: $MODEL.objects.raw(..., request.$W[...], ...) + if ($X !== apiSecret) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw(..., $DATA, ...) + if (token != $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X != token) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) + if (token !== $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X !== token) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw(..., $STR % $DATA, ...) + if (hash != $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X != hash) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw(..., f"...{$DATA}...", ...) + if (hash !== $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X !== hash) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw(..., $STR + $DATA, ...) + if (auth_token != $X) { + ... + } - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: $A = $MODEL.objects.raw(..., request.$W[...], ...) - - pattern: return $MODEL.objects.raw(..., request.$W[...], ...) - - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W, ...), ...) - - pattern: $MODEL.objects.raw(..., $S % request.$W, ...) - - pattern: $MODEL.objects.raw(..., f"...{request.$W}...", ...) - - pattern: $MODEL.objects.raw(..., request.$W, ...) + if ($X != auth_token) { + ... + } - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw(..., $DATA, ...) + if (auth_token !== $X) { + ... + } - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) + if ($X !== auth_token) { + ... + } - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) + return $X === auth_token; - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.raw(..., $INTERM, ...) + return auth_token === $X; - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw(..., $STR % $DATA, ...) + return $X === token; - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) + return token === $X; - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw(..., f"...{$DATA}...", ...) + return $X === hash; - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.raw(..., $INTERM, ...) + return hash === $X; - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw(..., $STR + $DATA, ...) + return $X === password; - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: $A = $MODEL.objects.raw(..., request.$W, ...) - - pattern: return $MODEL.objects.raw(..., request.$W, ...) + return password === $X; - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw($STR % (..., $DATA, ...), ...) + return $X === pass; - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw($STR % (..., $DATA, ...), ...) + return pass === $X; - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw($STR % (..., $DATA, ...), ...) + return $X === apiKey; - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw($STR % (..., $DATA, ...), ...) + return apiKey === $X; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.raw($INTERM, ...) + return $X === apiSecret; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.raw($INTERM, ...) + return apiSecret === $X; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.raw($INTERM, ...) + return $X === api_key; - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.raw($INTERM, ...) - severity: WARNING - - id: python.django.security.injection.ssrf.ssrf-injection-requests.ssrf-injection-requests - languages: - - python - message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF). To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. See https://owasp.org/www-community/attacks/Server_Side_Request_Forgery to learn more about SSRF vulnerabilities. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: requests.$METHOD(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: requests.$METHOD(..., $S % request.$W.get(...), ...) - - pattern: requests.$METHOD(..., f"...{request.$W.get(...)}...", ...) - - pattern: requests.$METHOD(..., request.$W.get(...), ...) + return api_key === $X; - pattern: | - $DATA = request.$W.get(...) - ... - requests.$METHOD(..., $DATA, ...) + return $X === api_secret; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - requests.$METHOD(..., $INTERM, ...) + return api_secret === $X; - pattern: | - $DATA = request.$W.get(...) - ... - requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) + return $X === secret; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - requests.$METHOD(..., $INTERM, ...) + return secret === $X; - pattern: | - $DATA = request.$W.get(...) - ... - requests.$METHOD(..., $STR % $DATA, ...) + return $X === api; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - requests.$METHOD(..., $INTERM, ...) + return api === $X; - pattern: | - $DATA = request.$W.get(...) - ... - requests.$METHOD(..., f"...{$DATA}...", ...) + return $X == auth_token; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - requests.$METHOD(..., $INTERM, ...) + return auth_token == $X; - pattern: | - $DATA = request.$W.get(...) - ... - requests.$METHOD(..., $STR + $DATA, ...) + return $X == token; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: $A = requests.$METHOD(..., request.$W.get(...), ...) - - pattern: return requests.$METHOD(..., request.$W.get(...), ...) - - pattern: requests.$METHOD(..., $S.format(..., request.$W(...), ...), ...) - - pattern: requests.$METHOD(..., $S % request.$W(...), ...) - - pattern: requests.$METHOD(..., f"...{request.$W(...)}...", ...) - - pattern: requests.$METHOD(..., request.$W(...), ...) + return token == $X; - pattern: | - $DATA = request.$W(...) - ... - requests.$METHOD(..., $DATA, ...) + return $X == hash; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - requests.$METHOD(..., $INTERM, ...) + return hash == $X; - pattern: | - $DATA = request.$W(...) - ... - requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) + return $X == password; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - requests.$METHOD(..., $INTERM, ...) + return password == $X; - pattern: | - $DATA = request.$W(...) - ... - requests.$METHOD(..., $STR % $DATA, ...) + return $X == pass; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - requests.$METHOD(..., $INTERM, ...) + return pass == $X; - pattern: | - $DATA = request.$W(...) - ... - requests.$METHOD(..., f"...{$DATA}...", ...) + return $X == apiKey; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - requests.$METHOD(..., $INTERM, ...) + return apiKey == $X; - pattern: | - $DATA = request.$W(...) - ... - requests.$METHOD(..., $STR + $DATA, ...) + return $X == apiSecret; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: $A = requests.$METHOD(..., request.$W(...), ...) - - pattern: return requests.$METHOD(..., request.$W(...), ...) - - pattern: requests.$METHOD(..., $S.format(..., request.$W[...], ...), ...) - - pattern: requests.$METHOD(..., $S % request.$W[...], ...) - - pattern: requests.$METHOD(..., f"...{request.$W[...]}...", ...) - - pattern: requests.$METHOD(..., request.$W[...], ...) + return apiSecret == $X; - pattern: | - $DATA = request.$W[...] - ... - requests.$METHOD(..., $DATA, ...) + return $X == api_key; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - requests.$METHOD(..., $INTERM, ...) + return api_key == $X; - pattern: | - $DATA = request.$W[...] - ... - requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) + return $X == api_secret; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - requests.$METHOD(..., $INTERM, ...) + return api_secret == $X; - pattern: | - $DATA = request.$W[...] - ... - requests.$METHOD(..., $STR % $DATA, ...) + return $X == secret; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - requests.$METHOD(..., $INTERM, ...) + return secret == $X; - pattern: | - $DATA = request.$W[...] - ... - requests.$METHOD(..., f"...{$DATA}...", ...) + return $X == api; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - requests.$METHOD(..., $INTERM, ...) + return api == $X; - pattern: | - $DATA = request.$W[...] - ... - requests.$METHOD(..., $STR + $DATA, ...) + return $X !== auth_token; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: $A = requests.$METHOD(..., request.$W[...], ...) - - pattern: return requests.$METHOD(..., request.$W[...], ...) - - pattern: requests.$METHOD(..., $S.format(..., request.$W, ...), ...) - - pattern: requests.$METHOD(..., $S % request.$W, ...) - - pattern: requests.$METHOD(..., f"...{request.$W}...", ...) - - pattern: requests.$METHOD(..., request.$W, ...) + return auth_token !== $X; - pattern: | - $DATA = request.$W - ... - requests.$METHOD(..., $DATA, ...) + return $X !== token; - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - requests.$METHOD(..., $INTERM, ...) + return token !== $X; - pattern: | - $DATA = request.$W - ... - requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) + return $X !== hash; - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - requests.$METHOD(..., $INTERM, ...) + return hash !== $X; - pattern: | - $DATA = request.$W - ... - requests.$METHOD(..., $STR % $DATA, ...) + return $X !== password; - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - requests.$METHOD(..., $INTERM, ...) + return password !== $X; - pattern: | - $DATA = request.$W - ... - requests.$METHOD(..., f"...{$DATA}...", ...) + return $X !== pass; - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - requests.$METHOD(..., $INTERM, ...) + return pass !== $X; - pattern: | - $DATA = request.$W - ... - requests.$METHOD(..., $STR + $DATA, ...) + return $X !== apiKey; - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: $A = requests.$METHOD(..., request.$W, ...) - - pattern: return requests.$METHOD(..., request.$W, ...) - severity: ERROR - - id: python.django.security.injection.ssrf.ssrf-injection-urllib.ssrf-injection-urllib - languages: - - python - message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF), which could result in attackers gaining access to private organization data. To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: urllib.request.urlopen(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: urllib.request.urlopen(..., $S % request.$W.get(...), ...) - - pattern: urllib.request.urlopen(..., f"...{request.$W.get(...)}...", ...) - - pattern: urllib.request.urlopen(..., request.$W.get(...), ...) + return apiKey !== $X; - pattern: | - $DATA = request.$W.get(...) - ... - urllib.request.urlopen(..., $DATA, ...) + return $X !== apiSecret; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) + return apiSecret !== $X; - pattern: | - $DATA = request.$W.get(...) - ... - urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) + return $X !== api_key; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - urllib.request.urlopen(..., $INTERM, ...) + return api_key !== $X; - pattern: | - $DATA = request.$W.get(...) - ... - urllib.request.urlopen(..., $STR % $DATA, ...) + return $X !== api_secret; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) + return api_secret !== $X; - pattern: | - $DATA = request.$W.get(...) - ... - urllib.request.urlopen(..., f"...{$DATA}...", ...) + return $X !== secret; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - urllib.request.urlopen(..., $INTERM, ...) + return secret !== $X; - pattern: | - $DATA = request.$W.get(...) - ... - urllib.request.urlopen(..., $STR + $DATA, ...) + return $X !== api; - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: $A = urllib.request.urlopen(..., request.$W.get(...), ...) - - pattern: return urllib.request.urlopen(..., request.$W.get(...), ...) - - pattern: urllib.request.urlopen(..., $S.format(..., request.$W(...), ...), ...) - - pattern: urllib.request.urlopen(..., $S % request.$W(...), ...) - - pattern: urllib.request.urlopen(..., f"...{request.$W(...)}...", ...) - - pattern: urllib.request.urlopen(..., request.$W(...), ...) + return api !== $X; - pattern: | - $DATA = request.$W(...) - ... - urllib.request.urlopen(..., $DATA, ...) + return $X != auth_token; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) + return auth_token != $X; - pattern: | - $DATA = request.$W(...) - ... - urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) + return $X != token; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - urllib.request.urlopen(..., $INTERM, ...) + return token != $X; - pattern: | - $DATA = request.$W(...) - ... - urllib.request.urlopen(..., $STR % $DATA, ...) + return $X != hash; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) + return hash != $X; - pattern: | - $DATA = request.$W(...) - ... - urllib.request.urlopen(..., f"...{$DATA}...", ...) + return $X != password; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - urllib.request.urlopen(..., $INTERM, ...) + return password != $X; - pattern: | - $DATA = request.$W(...) - ... - urllib.request.urlopen(..., $STR + $DATA, ...) + return $X != pass; - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: $A = urllib.request.urlopen(..., request.$W(...), ...) - - pattern: return urllib.request.urlopen(..., request.$W(...), ...) - - pattern: urllib.request.urlopen(..., $S.format(..., request.$W[...], ...), ...) - - pattern: urllib.request.urlopen(..., $S % request.$W[...], ...) - - pattern: urllib.request.urlopen(..., f"...{request.$W[...]}...", ...) - - pattern: urllib.request.urlopen(..., request.$W[...], ...) + return pass != $X; - pattern: | - $DATA = request.$W[...] - ... - urllib.request.urlopen(..., $DATA, ...) + return $X != apiKey; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) + return apiKey != $X; - pattern: | - $DATA = request.$W[...] - ... - urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) + return $X != apiSecret; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - urllib.request.urlopen(..., $INTERM, ...) + return apiSecret != $X; - pattern: | - $DATA = request.$W[...] - ... - urllib.request.urlopen(..., $STR % $DATA, ...) + return $X != api_key; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) + return api_key != $X; - pattern: | - $DATA = request.$W[...] - ... - urllib.request.urlopen(..., f"...{$DATA}...", ...) + return $X != api_secret; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - urllib.request.urlopen(..., $INTERM, ...) + return api_secret != $X; - pattern: | - $DATA = request.$W[...] - ... - urllib.request.urlopen(..., $STR + $DATA, ...) + return $X != secret; - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: $A = urllib.request.urlopen(..., request.$W[...], ...) - - pattern: return urllib.request.urlopen(..., request.$W[...], ...) - - pattern: urllib.request.urlopen(..., $S.format(..., request.$W, ...), ...) - - pattern: urllib.request.urlopen(..., $S % request.$W, ...) - - pattern: urllib.request.urlopen(..., f"...{request.$W}...", ...) - - pattern: urllib.request.urlopen(..., request.$W, ...) + return secret != $X; - pattern: | - $DATA = request.$W - ... - urllib.request.urlopen(..., $DATA, ...) + return $X != api; - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) + return api != $X; + severity: WARNING + - id: javascript_xss_rule-mustache-escape + languages: + - javascript + - typescript + message: | + Markup escaping disabled. This can be used with some template engines to escape + disabling of HTML entities, which can lead to XSS attacks. + metadata: + category: security + cwe: CWE-79 + owasp: + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of input during web page generation (XSS) + patterns: + - pattern-inside: | + $OBJ = require('mustache') + ... + - pattern-either: - pattern: | - $DATA = request.$W - ... - urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) + $OBJ.escape = function($TEXT) { + ... + return $TEXT; + } + - patterns: + - metavariable-regex: + metavariable: $X + regex: '"\{\{\{(.+?)\}\}\}"' + - pattern: $OBJ.render($X, ... ) + - patterns: + - metavariable-regex: + metavariable: $Y + regex: '"\{\{\&(.+?)\}\}"' + - pattern: $OBJ.render($Y, ... ) + severity: WARNING + - id: python_assert_rule-assert-used + languages: + - python + message: | + The application was found using `assert` in non-test code. Usually reserved for debug and test + code, the `assert` + function is commonly used to test conditions before continuing execution. However, enclosed + code will be removed + when compiling Python code to optimized byte code. Depending on the assertion and subsequent + logic, this could + lead to undefined behavior of the application or application crashes. + + To remediate this issue, remove the `assert` calls. If necessary, replace them with either `if` + conditions or + `try/except` blocks. + + Example using `try/except` instead of `assert`: + ``` + # Below try/except is equal to the assert statement of: + # assert user.is_authenticated(), "user must be authenticated" + try: + if not user.is_authenticated(): + raise AuthError("user must be authenticated") + except AuthError as e: + # Handle error + # ... + # Return, do not continue processing + return + ``` + metadata: + category: security + cwe: CWE-754 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Info + shortDescription: Improper check for unusual or exceptional conditions + patterns: + - pattern: assert(...) + - pattern-not-inside: | + import pytest + ... + - pattern-not-inside: | + import unittest + ... + severity: INFO + - id: python_bind-all-interfaces_rule-general-bindall-interfaces + languages: + - python + message: | + Binding to all network interfaces can potentially open up a service to + traffic on unintended interfaces, that may not be properly documented or + secured. By passing "0.0.0.0", "::" or an empty string as the address to the `socket.bind` + function, + the application will bind to all interfaces. + + Consider passing in the interface ip address through an environment variable, + configuration file, or by determining the primary interface(s) IP address. + + Example getting the IP address from an environment variable `IP_ADDRESS`: + ``` + # Get the IP_ADDRESS env variable, or bind to + # 127.0.0.1 if it is not set + address = os.getenv("IP_ADDRESS", "127.0.0.1") + # Create an internet socket + sock = socket.socket(socket.AF_INET) + # Set the port to listen on + port = 9777 + # Bind to the address and port combination + sock.bind((address, port)) + # Listen for connections + sock.listen() + # Handle the connection + ``` + metadata: + category: security + cwe: CWE-1327 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Low + shortDescription: Binding to an unrestricted IP address + patterns: + - pattern-either: - pattern: | - $DATA = request.$W + $S = socket.socket(...) ... - $INTERM = $STR.format(..., $DATA, ...) + $S.bind(("0.0.0.0", ...)) + - pattern: | + $S = socket.socket(...) ... - urllib.request.urlopen(..., $INTERM, ...) + $S.bind(("::", ...)) - pattern: | - $DATA = request.$W + $S = socket.socket(...) ... - urllib.request.urlopen(..., $STR % $DATA, ...) + $S.bind(("", ...)) + severity: INFO + - id: python_crypto_rule-cipher-modes + languages: + - python + message: | + Cryptographic algorithms provide many different modes of operation, only some of which provide + message integrity. Without message integrity it could be possible for an adversary to attempt + to tamper with the ciphertext which could lead to compromising the encryption key. Newer + algorithms + apply message integrity to validate ciphertext has not been tampered with. + + Instead of using an algorithm that requires configuring a cipher mode, an algorithm + that has built-in message integrity should be used. Consider using `ChaCha20Poly1305` or + `AES-256-GCM` instead. + + For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is + recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Example using `ChaCha20Poly1305`: + ``` + import os + # Import ChaCha20Poly1305 from cryptography + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = ChaCha20Poly1305.generate_key() + # Create a new ChaCha20Poly1305 instance with our secure key + chacha = ChaCha20Poly1305(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = chacha.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + chacha.decrypt(nonce, cipher_text, aad) + ``` + + Example using `AESGCM`: + ``` + import os + # Import AESGCM from cryptography + from cryptography.hazmat.primitives.ciphers.aead import AESGCM + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = AESGCM.generate_key(bit_length=128) + # Create a new AESGCM instance with our secure key + aesgcm = AESGCM(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = aesgcm.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + aesgcm.decrypt(nonce, cipher_text, aad) + ``` + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + pattern: cryptography.hazmat.primitives.ciphers.modes.ECB(...) + severity: WARNING + - id: python_crypto_rule-crypto-cipher-blowfish + languages: + - python + message: | + The Blowfish encryption algorithm was meant as a drop-in replacement for DES and was created in + 1993. Smaller key sizes may make the ciphertext vulnerable to [birthday + attacks](https://en.wikipedia.org/wiki/Birthday_attack). While no known attacks against + Blowfish + exist, it should never be used to encrypt files over 4GB in size. If possible consider + using ChaCha20Poly1305 or AES-GCM instead of Blowfish. + + For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is + recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example using `ChaCha20Poly1305`: + ``` + import os + # Import ChaCha20Poly1305 from cryptography + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = ChaCha20Poly1305.generate_key() + # Create a new ChaCha20Poly1305 instance with our secure key + chacha = ChaCha20Poly1305(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = chacha.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + chacha.decrypt(nonce, cipher_text, aad) + ``` + + Example using `AESGCM`: + ``` + import os + # Import AESGCM from cryptography + from cryptography.hazmat.primitives.ciphers.aead import AESGCM + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = AESGCM.generate_key(bit_length=128) + # Create a new AESGCM instance with our secure key + aesgcm = AESGCM(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = aesgcm.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + aesgcm.decrypt(nonce, cipher_text, aad) + ``` + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: + - pattern: Cryptodome.Cipher.Blowfish.new(...) + - pattern: Crypto.Cipher.Blowfish.new(...) + severity: WARNING + - id: python_crypto_rule-crypto-cipher-des + languages: + - python + message: | + DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. + Newer algorithms apply message integrity to validate ciphertext has not been tampered + with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the + alternatives such as `AES-256-GCM`. + + For older applications that don't have support for `ChaCha20Poly1305`, + `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example using `ChaCha20Poly1305`: + ``` + import os + # Import ChaCha20Poly1305 from cryptography + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = ChaCha20Poly1305.generate_key() + # Create a new ChaCha20Poly1305 instance with our secure key + chacha = ChaCha20Poly1305(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = chacha.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + chacha.decrypt(nonce, cipher_text, aad) + ``` + + Example using `AESGCM`: + ``` + import os + # Import AESGCM from cryptography + from cryptography.hazmat.primitives.ciphers.aead import AESGCM + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = AESGCM.generate_key(bit_length=128) + # Create a new AESGCM instance with our secure key + aesgcm = AESGCM(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = aesgcm.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + aesgcm.decrypt(nonce, cipher_text, aad) + ``` + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: + - pattern: Cryptodome.Cipher.DES.new(...) + - pattern: Crypto.Cipher.DES.new(...) + severity: WARNING + - id: python_crypto_rule-crypto-cipher-rc2 + languages: + - python + message: | + DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. + Newer algorithms apply message integrity to validate ciphertext has not been tampered + with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the + alternatives such as `AES-256-GCM`. + + For older applications that don't have support for `ChaCha20Poly1305`, + `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example using `ChaCha20Poly1305`: + ``` + import os + # Import ChaCha20Poly1305 from cryptography + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = ChaCha20Poly1305.generate_key() + # Create a new ChaCha20Poly1305 instance with our secure key + chacha = ChaCha20Poly1305(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = chacha.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + chacha.decrypt(nonce, cipher_text, aad) + ``` + + Example using `AESGCM`: + ``` + import os + # Import AESGCM from cryptography + from cryptography.hazmat.primitives.ciphers.aead import AESGCM + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = AESGCM.generate_key(bit_length=128) + # Create a new AESGCM instance with our secure key + aesgcm = AESGCM(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = aesgcm.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + aesgcm.decrypt(nonce, cipher_text, aad) + ``` + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: + - pattern: Cryptodome.Cipher.ARC2.new(...) + - pattern: Crypto.Cipher.ARC2.new + severity: WARNING + - id: python_crypto_rule-crypto-cipher-rc4 + languages: + - python + message: | + DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. + Newer algorithms apply message integrity to validate ciphertext has not been tampered + with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the + alternatives such as `AES-256-GCM`. + + For older applications that don't have support for `ChaCha20Poly1305`, + `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example using `ChaCha20Poly1305`: + ``` + import os + # Import ChaCha20Poly1305 from cryptography + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = ChaCha20Poly1305.generate_key() + # Create a new ChaCha20Poly1305 instance with our secure key + chacha = ChaCha20Poly1305(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = chacha.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + chacha.decrypt(nonce, cipher_text, aad) + ``` + + Example using `AESGCM`: + ``` + import os + # Import AESGCM from cryptography + from cryptography.hazmat.primitives.ciphers.aead import AESGCM + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = AESGCM.generate_key(bit_length=128) + # Create a new AESGCM instance with our secure key + aesgcm = AESGCM(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = aesgcm.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + aesgcm.decrypt(nonce, cipher_text, aad) + ``` + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: + - pattern: Cryptodome.Cipher.ARC4.new(...) + - pattern: Crypto.Cipher.ARC4.new(...) + severity: WARNING + - id: python_crypto_rule-crypto-cipher-xor + languages: + - python + message: | + The application was found using the `xor` algorithm, which can be trivially decoded. + Newer algorithms apply message integrity to validate ciphertext has not been tampered + with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the + alternatives such as `AES-256-GCM`. + + For older applications that don't have support for `ChaCha20Poly1305`, + `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example using `ChaCha20Poly1305`: + ``` + import os + # Import ChaCha20Poly1305 from cryptography + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = ChaCha20Poly1305.generate_key() + # Create a new ChaCha20Poly1305 instance with our secure key + chacha = ChaCha20Poly1305(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = chacha.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + chacha.decrypt(nonce, cipher_text, aad) + ``` + + Example using `AESGCM`: + ``` + import os + # Import AESGCM from cryptography + from cryptography.hazmat.primitives.ciphers.aead import AESGCM + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = AESGCM.generate_key(bit_length=128) + # Create a new AESGCM instance with our secure key + aesgcm = AESGCM(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = aesgcm.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + aesgcm.decrypt(nonce, cipher_text, aad) + ``` + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: + - pattern: Cryptodome.Cipher.XOR.new(...) + - pattern: Crypto.Cipher.XOR.new(...) + severity: WARNING + - id: python_crypto_rule-crypto-encrypt-dsa-rsa + languages: + - python + message: | + The application is generating an RSA key that is less than the recommended 2048 bits. + The National Institute of Standards and Technology (NIST) deprecated signing Digital + Certificates that contained RSA Public Keys of 1024 bits in December 2010. While + 1024-bit RSA keys have not been factored yet, advances in compute may make it possible + in the near future. + + Consider upgrading to the newer asymmetric algorithm such as `X25519` which handles + the complexities of generating key pairs and choosing correct key sizes for you: + ``` + from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey + + # Generate a private key for use in the exchange. + private_key = X25519PrivateKey.generate() + # Work with private key/exchange with a peer's + # public key to created a shared and derived key + # ... + ``` + + Otherwise use a key size greater than 2048 when generating RSA keys: + ``` + from cryptography.hazmat.primitives.asymmetric import rsa + # Generate a private key of 4096 bits + private_key = rsa.generate_private_key( + # do not change the exponent value from 65537 + public_exponent=65537, + key_size=4096, + ) + # Work with the private key to sign/encrypt data + # ... + ``` + + For more information on using the cryptography module see: + - https://cryptography.io/en/latest + metadata: + category: security + cwe: CWE-326 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Inadequate encryption strength + patterns: + - pattern-either: - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) + cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key(...,key_size=$SIZE,...) - pattern: | - $DATA = request.$W - ... - urllib.request.urlopen(..., f"...{$DATA}...", ...) + cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key($EXP, $SIZE,...) - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - urllib.request.urlopen(..., $INTERM, ...) + cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key($SIZE, ...) - pattern: | - $DATA = request.$W - ... - urllib.request.urlopen(..., $STR + $DATA, ...) + cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key(...,key_size=$SIZE,...) - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: $A = urllib.request.urlopen(..., request.$W, ...) - - pattern: return urllib.request.urlopen(..., request.$W, ...) + cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key($EXP, $SIZE, ...) + - pattern: cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key($SIZE,...) + - pattern: Crypto.PublicKey.RSA.generate($SIZE, ...) + - pattern: Crypto.PublicKey.DSA.generate($SIZE, ...) + - pattern: Cryptodome.PublicKey.DSA.generate($SIZE, ...) + - pattern: Cryptodome.PublicKey.RSA.generate($SIZE, ...) + - pattern: Crypto.PublicKey.DSA.generate(bits=$SIZE, ...) + - pattern: Cryptodome.PublicKey.DSA.generate(bits=$SIZE, ...) + - pattern: pycrypto_rsa.generate(bits=$SIZE, ...) + - pattern: pycrypto_dsa.generate(bits=$SIZE, ...) + - pattern: pycryptodomex_rsa.generate(bits=$SIZE, ...) + - pattern: pycryptodomex_rsa.generate($SIZE, ...) + - pattern: pycryptodomex_dsa.generate(bits=$SIZE, ...) + - pattern: pycryptodomex_dsa.generate($SIZE, ...) + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE severity: ERROR - - id: python.django.security.nan-injection.nan-injection + - id: python_crypto_rule-crypto-encrypt-ec languages: - python - message: Found user input going directly into typecast for bool(), float(), or complex(). This allows an attacker to inject Python's not-a-number (NaN) into the typecast. This results in undefind behavior, particularly when doing comparisons. Either cast to a different type, or add a guard checking for all capitalizations of the string 'nan'. + message: | + The application was found using an insufficient curve size for the Elliptical + Cryptography (EC) asymmetric algorithm. NIST recommends using a key size of + 224 or greater. + + To remediate this issue, replace the current key size with `ec.SECP384R1`, + + Example using `ec.SECP384R1`: + ``` + from cryptography.hazmat.primitives.asymmetric import ec + # Generate an EC private key using SECP384R1 + private_key = ec.generate_private_key( + ec.SECP384R1() + ) + # Work with/sign data using the key + # ... + ``` + + For more information on the cryptography module's EC section see: + - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/ metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-704: Incorrect Type Conversion or Cast' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://discuss.python.org/t/nan-breaks-min-max-and-sorting-functions-a-solution/2868 - - https://blog.bitdiscovery.com/2021/12/python-nan-injection/ - subcategory: - - vuln - technology: - - django - mode: taint - pattern-sanitizers: - - not_conflicting: true - pattern: $ANYTHING(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: float(...) - - pattern: bool(...) - - pattern: complex(...) - - pattern-not-inside: | - if $COND: - ... - ... - pattern-sources: - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] + cwe: CWE-326 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Inadequate encryption strength + patterns: + - pattern-inside: cryptography.hazmat.primitives.asymmetric.ec.generate_private_key(...) + - pattern: cryptography.hazmat.primitives.asymmetric.ec.$SIZE + - metavariable-pattern: + metavariable: $SIZE + pattern-either: + - pattern: SECP192R1 + - pattern: SECT163K1 + - pattern: SECT163R2 + - focus-metavariable: $SIZE severity: ERROR - - id: python.django.security.passwords.password-empty-string.password-empty-string + - id: python_crypto_rule-crypto-hash-md5 languages: - python - message: '''$VAR'' is the empty string and is being used to set the password on ''$MODEL''. If you meant to set an unusable password, set the password to None or call ''set_unusable_password()''.' + message: | + The application was found using an insecure or risky digest or signature algorithm. MD5 + and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. + It is strongly recommended that a standard digest algorithm be chosen instead as implementing + a custom algorithm is prone to errors. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example of creating a SHA-384 hash using the `cryptography` package: + ``` + from cryptography.hazmat.primitives import hashes + # Create a SHA384 digest + digest = hashes.Hash(hashes.SHA384()) + # Update the digest with some initial data + digest.update(b"some data to hash") + # Add more data to the digest + digest.update(b"some more data") + # Finalize the digest as bytes + result = digest.finalize() + ``` + + For more information on secure password storage see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-521: Weak Password Requirements' - impact: MEDIUM - likelihood: LOW + cwe: CWE-327 owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://docs.djangoproject.com/en/3.0/ref/contrib/auth/#django.contrib.auth.models.User.set_password - subcategory: - - vuln - technology: - - django + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm patterns: - pattern-either: - - pattern: | - $MODEL.set_password($EMPTY) - ... - $MODEL.save() - - pattern: | - $VAR = $EMPTY - ... - $MODEL.set_password($VAR) - ... - $MODEL.save() - - metavariable-regex: - metavariable: $EMPTY - regex: (\'\'|\"\") - severity: ERROR - - fix: | - None - id: python.django.security.passwords.use-none-for-password-default.use-none-for-password-default + - pattern: Crypto.Hash.MD5.new(...) + - pattern: Cryptodome.Hash.MD5.new (...) + severity: WARNING + - id: python_crypto_rule-crypto-hash-sha1 languages: - python - message: '''$VAR'' is using the empty string as its default and is being used to set the password on ''$MODEL''. If you meant to set an unusable password, set the default value to ''None'' or call ''set_unusable_password()''.' + message: | + The application was found using an insecure or risky digest or signature algorithm. MD5 + and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. + It is strongly recommended that a standard digest algorithm be chosen instead as implementing + a custom algorithm is prone to errors. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example of creating a SHA-384 hash using the `cryptography` package: + ``` + from cryptography.hazmat.primitives import hashes + # Create a SHA384 digest + digest = hashes.Hash(hashes.SHA384()) + # Update the digest with some initial data + digest.update(b"some data to hash") + # Add more data to the digest + digest.update(b"some more data") + # Finalize the digest as bytes + result = digest.finalize() + ``` + + For more information on secure password storage see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-521: Weak Password Requirements' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-327 owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://docs.djangoproject.com/en/3.0/ref/contrib/auth/#django.contrib.auth.models.User.set_password - subcategory: - - vuln - technology: - - django + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm patterns: - pattern-either: - - pattern: | - $VAR = request.$W.get($X, $EMPTY) - ... - $MODEL.set_password($VAR) - ... - $MODEL.save(...) - - pattern: | - def $F(..., $VAR=$EMPTY, ...): - ... - $MODEL.set_password($VAR) - - metavariable-pattern: - metavariable: $EMPTY - pattern: '""' - - focus-metavariable: $EMPTY - severity: ERROR - - id: python.fastapi.security.wildcard-cors.wildcard-cors + - pattern: Crypto.Hash.SHA.new(...) + - pattern: Cryptodome.Hash.SHA.new (...) + severity: WARNING + - id: python_crypto_rule-crypto-hazmat-cipher-arc4 languages: - python - message: CORS policy allows any origin (using wildcard '*'). This is insecure and should be avoided. + message: | + DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. + Newer algorithms apply message integrity to validate ciphertext has not been tampered + with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the + alternatives such as `AES-256-GCM`. + + For older applications that don't have support for `ChaCha20Poly1305`, + `AES-256-GCM` is recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Example using `ChaCha20Poly1305`: + ``` + import os + # Import ChaCha20Poly1305 from cryptography + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = ChaCha20Poly1305.generate_key() + # Create a new ChaCha20Poly1305 instance with our secure key + chacha = ChaCha20Poly1305(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = chacha.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + chacha.decrypt(nonce, cipher_text, aad) + ``` + + Example using `AESGCM`: + ``` + import os + # Import AESGCM from cryptography + from cryptography.hazmat.primitives.ciphers.aead import AESGCM + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = AESGCM.generate_key(bit_length=128) + # Create a new AESGCM instance with our secure key + aesgcm = AESGCM(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = aesgcm.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + aesgcm.decrypt(nonce, cipher_text, aad) + ``` + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-942: Permissive Cross-domain Policy with Untrusted Domains' - impact: LOW - likelihood: HIGH + cwe: CWE-327 owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - - https://cwe.mitre.org/data/definitions/942.html - subcategory: - - vuln - technology: - - python - - fastapi - vulnerability_class: - - Configuration - mode: taint - pattern-sinks: - - patterns: - - pattern: | - $APP.add_middleware( - CORSMiddleware, - allow_origins=$ORIGIN, - ...); - - focus-metavariable: $ORIGIN - pattern-sources: - - pattern: '[..., "*", ...]' + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + pattern: cryptography.hazmat.primitives.ciphers.algorithms.ARC4(...) severity: WARNING - - id: python.flask.security.audit.app-run-param-config.avoid_app_run_with_bad_host + - id: python_crypto_rule-crypto-hazmat-cipher-blowfish languages: - python - message: Running flask app with host 0.0.0.0 could expose the server publicly. + message: | + The Blowfish encryption algorithm was meant as a drop-in replacement for DES and was created in + 1993. Smaller key sizes may make the ciphertext vulnerable to [birthday + attacks](https://en.wikipedia.org/wiki/Birthday_attack). While no known attacks against + Blowfish + exist, it should never be used to encrypt files over 4GB in size. If possible consider + using ChaCha20Poly1305 or AES-GCM instead of Blowfish. + + For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is + recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Example using `ChaCha20Poly1305`: + ``` + import os + # Import ChaCha20Poly1305 from cryptography + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = ChaCha20Poly1305.generate_key() + # Create a new ChaCha20Poly1305 instance with our secure key + chacha = ChaCha20Poly1305(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = chacha.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + chacha.decrypt(nonce, cipher_text, aad) + ``` + + Example using `AESGCM`: + ``` + import os + # Import AESGCM from cryptography + from cryptography.hazmat.primitives.ciphers.aead import AESGCM + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = AESGCM.generate_key(bit_length=128) + # Create a new AESGCM instance with our secure key + aesgcm = AESGCM(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = aesgcm.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + aesgcm.decrypt(nonce, cipher_text, aad) + ``` + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ metadata: category: security - confidence: HIGH - cwe: - - 'CWE-668: Exposure of Resource to Wrong Sphere' - impact: MEDIUM - likelihood: HIGH + cwe: CWE-327 owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - flask - pattern-either: - - pattern: app.run(..., host="0.0.0.0", ...) - - pattern: app.run(..., "0.0.0.0", ...) + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + pattern: cryptography.hazmat.primitives.ciphers.algorithms.Blowfish(...) severity: WARNING - - id: python.flask.security.audit.app-run-security-config.avoid_using_app_run_directly + - id: python_crypto_rule-crypto-hazmat-cipher-idea languages: - python - message: top-level app.run(...) is ignored by flask. Consider putting app.run(...) behind a guard, like inside a function + message: | + The IDEA encryption algorithm was meant as a drop-in replacement for DES and was created in + 1991. A number of [vulnerabilities and + exploits](https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm#Security) have + been identified to work against IDEA and + it is no longer recommended. If possible consider + using ChaCha20Poly1305 or AES-GCM instead of Blowfish. + + For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is + recommended, however it has many drawbacks: + - Slower than `ChaCha20Poly1305`. + - Catastrophic failure if nonce values are reused. + + Example using `ChaCha20Poly1305`: + ``` + import os + # Import ChaCha20Poly1305 from cryptography + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = ChaCha20Poly1305.generate_key() + # Create a new ChaCha20Poly1305 instance with our secure key + chacha = ChaCha20Poly1305(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = chacha.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + chacha.decrypt(nonce, cipher_text, aad) + ``` + + Example using `AESGCM`: + ``` + import os + # Import AESGCM from cryptography + from cryptography.hazmat.primitives.ciphers.aead import AESGCM + # Our plaintext to encrypt + plain_text = b"Secret text to encrypt" + # We do not require authenticated but unencrypted data, so set to None + aad = None + # Generate a secure key + key = AESGCM.generate_key(bit_length=128) + # Create a new AESGCM instance with our secure key + aesgcm = AESGCM(key) + # Note: nonce values _must_ be regenerated every time they are used. + nonce = os.urandom(12) + # Encrypt our plaintext + cipher_text = aesgcm.encrypt(nonce, plain_text, aad) + # Decrypt the plain text using the nonce and cipher_text + aesgcm.decrypt(nonce, cipher_text, aad) + ``` + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-668: Exposure of Resource to Wrong Sphere' - impact: MEDIUM - likelihood: LOW + cwe: CWE-327 owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - flask + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a Broken or Risky Cryptographic Algorithm + pattern: cryptography.hazmat.primitives.ciphers.algorithms.IDEA(...) + severity: WARNING + - id: python_crypto_rule-crypto.hazmat-hash-md5 + languages: + - python + message: | + The application was found using an insecure or risky digest or signature algorithm. MD2, MD5 + and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. + It is strongly recommended that a standard digest algorithm be chosen instead as implementing + a custom algorithm is prone to errors. + + Example of creating a SHA-384 hash using the `cryptography` package: + ``` + from cryptography.hazmat.primitives import hashes + # Create a SHA384 digest + digest = hashes.Hash(hashes.SHA384()) + # Update the digest with some initial data + digest.update(b"some data to hash") + # Add more data to the digest + digest.update(b"some more data") + # Finalize the digest as bytes + result = digest.finalize() + ``` + + For more information on secure password storage see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + pattern: cryptography.hazmat.primitives.hashes.MD5(...) + severity: WARNING + - id: python_crypto_rule-crypto.hazmat-hash-sha1 + languages: + - python + message: | + The application was found using an insecure or risky digest or signature algorithm. MD2, MD5 + and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. + It is strongly recommended that a standard digest algorithm be chosen instead as implementing + a custom algorithm is prone to error. + + Example of creating a SHA-384 hash using the `cryptography` package: + ``` + from cryptography.hazmat.primitives import hashes + # Create a SHA384 digest + digest = hashes.Hash(hashes.SHA384()) + # Update the digest with some initial data + digest.update(b"some data to hash") + # Add more data to the digest + digest.update(b"some more data") + # Finalize the digest as bytes + result = digest.finalize() + ``` + + For more information on secure password storage see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + pattern: cryptography.hazmat.primitives.hashes.SHA1(...) + severity: WARNING + - id: python_crypto_rule-hash-md2 + languages: + - python + message: | + The application was found using an insecure or risky digest or signature algorithm. MD2, MD5 + and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example of creating a SHA-384 hash using the `cryptography` package: + ``` + from cryptography.hazmat.primitives import hashes + # Create a SHA384 digest + digest = hashes.Hash(hashes.SHA384()) + # Update the digest with some initial data + digest.update(b"some data to hash") + # Add more data to the digest + digest.update(b"some more data") + # Finalize the digest as bytes + result = digest.finalize() + ``` + + For more information on secure password storage see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: + - pattern: Crypto.Hash.MD2.new(...) + - pattern: Cryptodome.Hash.MD2.new (...) + severity: WARNING + - id: python_crypto_rule-hash-md4 + languages: + - python + message: | + The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, + MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example of creating a SHA-384 hash using the `cryptography` package: + ``` + from cryptography.hazmat.primitives import hashes + # Create a SHA384 digest + digest = hashes.Hash(hashes.SHA384()) + # Update the digest with some initial data + digest.update(b"some data to hash") + # Add more data to the digest + digest.update(b"some more data") + # Finalize the digest as bytes + result = digest.finalize() + ``` + + For more information on secure password storage see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: + - pattern: Crypto.Hash.MD4.new(...) + - pattern: Cryptodome.Hash.MD4.new (...) + severity: WARNING + - id: python_crypto_rule-hash-md5 + languages: + - python + message: | + The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, + MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example of creating a SHA-384 hash using the `cryptography` package: + ``` + from cryptography.hazmat.primitives import hashes + # Create a SHA384 digest + digest = hashes.Hash(hashes.SHA384()) + # Update the digest with some initial data + digest.update(b"some data to hash") + # Add more data to the digest + digest.update(b"some more data") + # Finalize the digest as bytes + result = digest.finalize() + ``` + + For more information on secure password storage see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + pattern: hashlib.md5(...) + severity: WARNING + - id: python_crypto_rule-hash-sha1 + languages: + - python + message: | + The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, + MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. + + Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for + new applications, instead consider using the [cryptography](https://cryptography.io/) package. + + Example of creating a SHA-384 hash using the `cryptography` package: + ``` + from cryptography.hazmat.primitives import hashes + # Create a SHA384 digest + digest = hashes.Hash(hashes.SHA384()) + # Update the digest with some initial data + digest.update(b"some data to hash") + # Add more data to the digest + digest.update(b"some more data") + # Finalize the digest as bytes + result = digest.finalize() + ``` + + For more information on secure password storage see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + + For more information on the cryptography module see: + - https://cryptography.io/en/latest/ + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + pattern: hashlib.sha1(...) + severity: WARNING + - id: python_crypto_rule-hashlib-new-insecure-functions + languages: + - python + message: | + The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, + MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. + + This means + that two different values, when hashed, can lead to the same hash value. If the application is + trying + to use these hash methods for storing passwords, then it is recommended to switch to a + password hashing + algorithm such as Argon2id or PBKDF2. + It is strongly recommended that a standard digest algorithm be chosen instead as implementing + a custom algorithm is prone to errors. + + Example using `hashlib.sha384()` to create a SHA384 hash: + ``` + import hashlib + # Create a SHA384 digest + digest = hashlib.sha384() + # Update the digest with some initial data + digest.update(b"some data to hash") + # Add more data to the digest + digest.update(b"some more data") + # Finalize the digest as bytes + digest.digest() + ``` + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: + - pattern: hashlib.new("=~/[M|m][D|d][4|5]/", ...) + - pattern: hashlib.new(..., name="=~/[M|m][D|d][4|5]/", ...) + - pattern: hashlib.new('sha1') + - pattern: hashlib.new(..., name='SHA1') + - pattern: hashlib.new('sha', string='test') + - pattern: hashlib.new(name='SHA', string='test') + severity: WARNING + - id: python_crypto_rule-import-pycrypto + languages: + - python + message: | + The application was detected importing `pycrypto`. This package has been deprecated as it + contains + security vulnerabilities. + + To remediate this issue, consider using the [cryptography](https://cryptography.io/) + package instead. + metadata: + category: security + cwe: CWE-1104 + owasp: + - A9:2017-Using Components with Known Vulnerabilities + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Use of unmaintained third party components + pattern-either: + - pattern: import pycryto + - pattern: import Crypto.Cipher + - pattern: import Crypto.Hash + - pattern: import Crypto.IO + - pattern: import Crypto.Protocol + - pattern: import Crypto.PublicKey + - pattern: import Crypto.Random + - pattern: import Crypto.Signature + - pattern: import Crypto.Util + severity: ERROR + - id: python_deserialization_rule-cpickle + languages: + - python + message: | + The application was found using `cPickle` which is vulnerable to deserialization attacks. + Deserialization attacks exploit the process of reading serialized data and turning it back + into an object. By constructing malicious objects and serializing them, an adversary may + attempt to: + + - Inject code that is executed upon object construction, which occurs during the + deserialization process. + - Exploit mass assignment by including fields that are not normally a part of the serialized + data but are read in during deserialization. + + Consider safer alternatives such as serializing data in the JSON format. Ensure any format + chosen allows + the application to specify exactly which object types are allowed to be deserialized. + + To protect against mass assignment, only allow deserialization of the specific fields that are + required. If this is not easily done, consider creating an intermediary type that + can be serialized with only the necessary fields exposed. + + Example JSON deserializer using an intermediary type that is validated against a schema to + ensure + it is safe from mass assignment: + ``` + import jsonschema + + # Create a schema to validate our user-supplied input against + # an intermediary object + intermediary_schema = { + "type" : "object", + "properties" : { + "name": {"type" : "string"} + }, + "required": ["name"], + # Protect against random properties being added to the object + "additionalProperties": False, + } + # If a user attempted to add "'is_admin': True" it would cause a validation error + intermediary_object = {'name': 'test user'} + + try: + # Validate the user supplied intermediary object against our schema + jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) + user_object = {'user': + { + # Assign the deserialized data from intermediary object + 'name': intermediary_object['name'], + # Add in protected data in object definition (or set it from a class constructor) + 'is_admin': False, + } + } + # Work with the user_object + except jsonschema.exceptions.ValidationError as ex: + # Gracefully handle validation errors + # ... + ``` + + For more details on deserialization attacks in general, see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-502 + owasp: + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: High + shortDescription: Deserialization of untrusted data + pattern: cPickle.$FUNC(...) + severity: WARNING + - id: python_deserialization_rule-dill + languages: + - python + message: | + The application was found using `dill` which is vulnerable to deserialization attacks. + Deserialization attacks exploit the process of reading serialized data and turning it back + into an object. By constructing malicious objects and serializing them, an adversary may + attempt to: + + - Inject code that is executed upon object construction, which occurs during the + deserialization process. + - Exploit mass assignment by including fields that are not normally a part of the serialized + data but are read in during deserialization. + + Consider safer alternatives such as serializing data in the JSON format. Ensure any format + chosen allows + the application to specify exactly which object types are allowed to be deserialized. + + To protect against mass assignment, only allow deserialization of the specific fields that are + required. If this is not easily done, consider creating an intermediary type that + can be serialized with only the necessary fields exposed. + + Example JSON deserializer using an intermediary type that is validated against a schema to + ensure + it is safe from mass assignment: + ``` + import jsonschema + + # Create a schema to validate our user-supplied input against + # an intermediary object + intermediary_schema = { + "type" : "object", + "properties" : { + "name": {"type" : "string"} + }, + "required": ["name"], + # Protect against random properties being added to the object + "additionalProperties": False, + } + # If a user attempted to add "'is_admin': True" it would cause a validation error + intermediary_object = {'name': 'test user'} + + try: + # Validate the user supplied intermediary object against our schema + jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) + user_object = {'user': + { + # Assign the deserialized data from intermediary object + 'name': intermediary_object['name'], + # Add in protected data in object definition (or set it from a class constructor) + 'is_admin': False, + } + } + # Work with the user_object + except jsonschema.exceptions.ValidationError as ex: + # Gracefully handle validation errors + # ... + ``` + + For more details on deserialization attacks in general, see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-502 + owasp: + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: High + shortDescription: Deserialization of untrusted data patterns: - - pattern-not-inside: | - if __name__ == '__main__': - ... - - pattern-not-inside: | - def $X(...): - ... - - pattern: app.run(...) + - pattern: dill.$FUNC(...) + - pattern-not: dill.$FUNC("...") severity: WARNING - - id: python.flask.security.audit.debug-enabled.debug-enabled + - id: python_deserialization_rule-marshal languages: - python - message: Detected Flask app with debug=True. Do not deploy to production with this flag enabled as it will leak sensitive information. Instead, consider using Flask configuration variables or setting 'debug' using system environment variables. + message: | + The application was found using `dill` which is vulnerable to deserialization attacks. + Deserialization attacks exploit the process of reading serialized data and turning it back + into an object. By constructing malicious objects and serializing them, an adversary may + attempt to: + + - Inject code that is executed upon object construction, which occurs during the + deserialization process. + - Exploit mass assignment by including fields that are not normally a part of the serialized + data but are read in during deserialization. + + Consider safer alternatives such as serializing data in the JSON format. Ensure any format + chosen allows + the application to specify exactly which object types are allowed to be deserialized. + + To protect against mass assignment, only allow deserialization of the specific fields that are + required. If this is not easily done, consider creating an intermediary type that + can be serialized with only the necessary fields exposed. + + Example JSON deserializer using an intermediary type that is validated against a schema to + ensure + it is safe from mass assignment: + ``` + import jsonschema + + # Create a schema to validate our user-supplied input against + # an intermediary object + intermediary_schema = { + "type" : "object", + "properties" : { + "name": {"type" : "string"} + }, + "required": ["name"], + # Protect against random properties being added to the object + "additionalProperties": False, + } + # If a user attempted to add "'is_admin': True" it would cause a validation error + intermediary_object = {'name': 'test user'} + + try: + # Validate the user supplied intermediary object against our schema + jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) + user_object = {'user': + { + # Assign the deserialized data from intermediary object + 'name': intermediary_object['name'], + # Add in protected data in object definition (or set it from a class constructor) + 'is_admin': False, + } + } + # Work with the user_object + except jsonschema.exceptions.ValidationError as ex: + # Gracefully handle validation errors + # ... + ``` + + For more details on deserialization attacks in general, see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html metadata: category: security - confidence: HIGH - cwe: - - 'CWE-489: Active Debug Code' - impact: MEDIUM - likelihood: HIGH - owasp: A06:2017 - Security Misconfiguration - references: - - https://labs.detectify.com/2015/10/02/how-patreon-got-hacked-publicly-exposed-werkzeug-debugger/ - subcategory: - - vuln - technology: - - flask - patterns: - - pattern-inside: | - import flask - ... - - pattern: $APP.run(..., debug=True, ...) + cwe: CWE-502 + owasp: + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: High + shortDescription: Deserialization of untrusted data + pattern-either: + - pattern: marshal.dump(...) + - pattern: marshal.dumps(...) + - pattern: marshal.load(...) + - pattern: marshal.loads(...) severity: WARNING - - id: python.flask.security.audit.directly-returned-format-string.directly-returned-format-string + - id: python_deserialization_rule-pickle languages: - python - message: Detected Flask route directly returning a formatted string. This is subject to cross-site scripting if user input can reach the string. Consider using the template engine instead and rendering pages with 'render_template()'. + message: | + The application was found using `pickle` which is vulnerable to deserialization attacks. + Deserialization attacks exploit the process of reading serialized data and turning it back + into an object. By constructing malicious objects and serializing them, an adversary may + attempt to: + + - Inject code that is executed upon object construction, which occurs during the + deserialization process. + - Exploit mass assignment by including fields that are not normally a part of the serialized + data but are read in during deserialization. + + Consider safer alternatives such as serializing data in the JSON format. Ensure any format + chosen allows the application to specify exactly which object types are allowed to be deserialized. + + To protect against mass assignment, only allow deserialization of the specific fields that are + required. If this is not easily done, consider creating an intermediary type that + can be serialized with only the necessary fields exposed. + + Example JSON deserializer using an intermediary type that is validated against a schema to ensure + it is safe from mass assignment: + ``` + import jsonschema + + # Create a schema to validate our user-supplied input against + # an intermediary object + intermediary_schema = { + "type" : "object", + "properties" : { + "name": {"type" : "string"} + }, + "required": ["name"], + # Protect against random properties being added to the object + "additionalProperties": False, + } + # If a user attempted to add "'is_admin': True" it would cause a validation error + intermediary_object = {'name': 'test user'} + + try: + # Validate the user supplied intermediary object against our schema + jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) + user_object = {'user': + { + # Assign the deserialized data from intermediary object + 'name': intermediary_object['name'], + # Add in protected data in object definition (or set it from a class constructor) + 'is_admin': False, + } + } + # Work with the user_object + except jsonschema.exceptions.ValidationError as ex: + # Gracefully handle validation errors + # ... + ``` + + For more details on deserialization attacks in general, see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-502 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - flask - mode: taint - pattern-sinks: - - patterns: - - pattern-not-inside: return "..." - - pattern-either: - - pattern: return "...".format(...) - - pattern: return "..." % ... - - pattern: return "..." + ... - - pattern: return ... + "..." - - pattern: return f"...{...}..." - - patterns: - - pattern: return $X - - pattern-either: - - pattern-inside: | - $X = "...".format(...) - ... - - pattern-inside: | - $X = "..." % ... - ... - - pattern-inside: | - $X = "..." + ... - ... - - pattern-inside: | - $X = ... + "..." - ... - - pattern-inside: | - $X = f"...{...}..." - ... - - pattern-not-inside: | - $X = "..." - ... - pattern-sources: + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: High + shortDescription: Deserialization of untrusted data + patterns: - pattern-either: - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $PARAM, ...): - ... - - pattern: $PARAM - - pattern: | - request.$FUNC.get(...) - - pattern: | - request.$FUNC(...) - - pattern: request.$FUNC[...] + - pattern: pickle.$METHOD(...) + - pattern-not: pickle.$METHOD("...") + - patterns: + - pattern: _pickle.$METHOD(...) + - pattern-not: _pickle.$METHOD("...") + - metavariable-regex: + metavariable: $METHOD + regex: (load|loads|Unpickler) severity: WARNING - - id: python.flask.security.hashids-with-flask-secret.hashids-with-flask-secret + - id: python_deserialization_rule-shelve 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. + message: | + The application was found using `shelve` which is vulnerable to deserialization attacks as + it calls `pickle` internally. + Deserialization attacks exploit the process of reading serialized data and turning it back + into an object. By constructing malicious objects and serializing them, an adversary may + attempt to: + + - Inject code that is executed upon object construction, which occurs during the + deserialization process. + - Exploit mass assignment by including fields that are not normally a part of the serialized + data but are read in during deserialization. + + Consider safer alternatives such as serializing data in the JSON format. Ensure any format + chosen allows + the application to specify exactly which object types are allowed to be deserialized. + + To protect against mass assignment, only allow deserialization of the specific fields that are + required. If this is not easily done, consider creating an intermediary type that + can be serialized with only the necessary fields exposed. + + Example JSON deserializer using an intermediary type that is validated against a schema to + ensure + it is safe from mass assignment: + ``` + import jsonschema + + # Create a schema to validate our user-supplied input against + # an intermediary object + intermediary_schema = { + "type" : "object", + "properties" : { + "name": {"type" : "string"} + }, + "required": ["name"], + # Protect against random properties being added to the object + "additionalProperties": False, + } + # If a user attempted to add "'is_admin': True" it would cause a validation error + intermediary_object = {'name': 'test user'} + + try: + # Validate the user supplied intermediary object against our schema + jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) + user_object = {'user': + { + # Assign the deserialized data from intermediary object + 'name': intermediary_object['name'], + # Add in protected data in object definition (or set it from a class constructor) + 'is_admin': False, + } + } + # Work with the user_object + except jsonschema.exceptions.ValidationError as ex: + # Gracefully handle validation errors + # ... + ``` + + For more details on deserialization attacks in general, see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html metadata: category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: HIGH - likelihood: LOW + cwe: CWE-502 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 - subcategory: - - vuln - technology: - - flask + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: High + shortDescription: Deserialization of untrusted data 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 - - id: python.flask.security.injection.csv-writer-injection.csv-writer-injection + - pattern: shelve.$FUNC(...) + severity: WARNING + - id: python_deserialization_rule-yaml-load languages: - python - message: Detected user input into a generated CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs. + message: | + The application was found using an unsafe version of `yaml` load which is vulnerable to + deserialization attacks. Deserialization attacks exploit the process of reading serialized + data and turning it back + into an object. By constructing malicious objects and serializing them, an adversary may + attempt to: + + - Inject code that is executed upon object construction, which occurs during the + deserialization process. + - Exploit mass assignment by including fields that are not normally a part of the serialized + data but are read in during deserialization. + + To remediate this issue, use `safe_load()` or call `yaml.load()` with the `Loader` argument + set to + `yaml.SafeLoader`. + + Example loading YAML using `safe_load`: + ``` + import yaml + + # Use safe_load to load data into an intermediary object + intermediary_object = yaml.safe_load("""user: + name: 'test user'""" + ) + # Create our real object, copying over only the necessary fields + user_object = {'user': { + # Assign the deserialized data from intermediary object + 'name': intermediary_object['user']['name'], + # Add in protected data in object definition (or set it from a class constructor) + 'is_admin': False, + } + } + # Work with user_object + # ... + ``` + + For more details on deserialization attacks in general, see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-1236: Improper Neutralization of Formula Elements in a CSV File' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-502 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/raphaelm/defusedcsv - - https://owasp.org/www-community/attacks/CSV_Injection - - https://web.archive.org/web/20220516052229/https://www.contextis.com/us/blog/comma-separated-vulnerabilities - subcategory: - - vuln - technology: - - python - - flask - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - $WRITER = csv.writer(...) - - ... - - $WRITER.$WRITE(...) - - pattern: $WRITER.$WRITE(...) - - metavariable-regex: - metavariable: $WRITE - regex: ^(writerow|writerows|writeheader)$ - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: High + shortDescription: Deserialization of untrusted data + patterns: + - pattern-inside: | + import yaml + ... + - pattern-not-inside: | + from ruamel.yaml import YAML + ... + - pattern-either: + - pattern: yaml.unsafe_load(...) + - pattern: yaml.$LD(..., Loader=yaml.$LOADER, ...) + - pattern: yaml.$LD($DATA) + - metavariable-regex: + metavariable: $LOADER + regex: (Loader|UnsafeLoader|CLoader|FullLoader) + - metavariable-regex: + metavariable: $LD + regex: (load|load_all) severity: ERROR - - id: python.flask.security.injection.nan-injection.nan-injection + - id: python_django_rule-django-extra-used languages: - python - message: Found user input going directly into typecast for bool(), float(), or complex(). This allows an attacker to inject Python's not-a-number (NaN) into the typecast. This results in undefind behavior, particularly when doing comparisons. Either cast to a different type, or add a guard checking for all capitalizations of the string 'nan'. + message: | + SQL Injection is a critical vulnerability that can lead to data or system compromise. By + dynamically generating SQL query strings, user input may be able to influence the logic of + the SQL statement. This could lead to an adversary accessing information they should + not have access to, or in some circumstances, being able to execute OS functionality or code. + + Replace all dynamically generated SQL queries with parameterized queries. In situations where + dynamic queries must be created, never use direct user input, but instead use a map or + dictionary of valid values and resolve them using a user supplied key. + + For example, some database drivers do not allow parameterized queries for `>` or `<` comparison + operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the + user + supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` + values to be used in the construction of the dynamic query. The same goes for other queries + where + column or table names are required but cannot be parameterized. + + The `QuerySet.extra` API method will be deprecated as it a source of SQL Injection + vulnerabilities and other problems. This method is especially risky as callers + will need to do their own escaping of any parameters that come from user-supplied + information. + + To remediate this issue, do not use `extra` but use other `QuerySet` methods to achieve + the same goals. If for some reason this is not feasible, consider using the `RawSQL` method + and making sure that all arguments, including user-supplied ones, are only used in + `params` + + + While not recommended due to [potential SQL + Injection](https://docs.djangoproject.com/en/4.2/ref/models/expressions/#raw-sql-expressions), + below is an example using `RawSQL`, + passing in user-supplied data as a `param` which will escape the input: + ``` + # If dealing with integer based user input, restrict the values to integers only using the + # path configuration: path('/someview/', views.some_view, + name='someview'), + + # views.py + def some_view(request, user_supplied_id): + # Never use string interpolation in the `sql` parameter. + # Never quote the `%s` string format such as `... where id='%s'` as this could lead to SQL + Injection. + # Pass the user supplied data only in the `params` parameter. + for obj in DBObject.objects.all().annotate( + val=RawSQL(sql="select id from some_secondary_table where id=%s", + params=[user_supplied_id])): + # Work with the results from the query + # ... + ``` + + For more information on QuerySet see: + - https://docs.djangoproject.com/en/4.2/ref/models/querysets/#queryset-api + + For more information on SQL Injection see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-704: Incorrect Type Conversion or Cast' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://discuss.python.org/t/nan-breaks-min-max-and-sorting-functions-a-solution/2868 - - https://blog.bitdiscovery.com/2021/12/python-nan-injection/ - subcategory: - - vuln - technology: - - flask - mode: taint - pattern-sanitizers: - - not_conflicting: true - pattern: $ANYTHING(...) - pattern-sinks: - - pattern-either: - - pattern: float(...) - - pattern: bool(...) - - pattern: complex(...) - pattern-sources: - - pattern-either: - - pattern: flask.request.$SOMETHING.get(...) - - pattern: flask.request.$SOMETHING[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR - severity: ERROR - - id: python.flask.security.injection.os-system-injection.os-system-injection + cwe: CWE-89 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an SQL Command ('SQL Injection') + patterns: + - pattern: $X.objects. ... .extra(..., $K = $V, ...) + - pattern-not-inside: | + $V = ['...'] + ... + - metavariable-pattern: + metavariable: $V + patterns: + - pattern: $V + - pattern-not: '[..., ''...'', ...]' + - pattern-not: '{..., ''...'': ''...'', ...}' + - pattern-not: '"..."' + - pattern-not: '[..., "..." % "...", ...]' + - pattern-not: '{..., $L: "..." % "...", ...}' + - pattern-not: '{..., $L: "...".format("..."), ...}' + - pattern-not: '[..., "...".format("..."), ...]' + severity: WARNING + - id: python_escaping_rule-jinja2-autoescape-false languages: - python - message: User data detected in os.system. This could be vulnerable to a command injection and should be avoided. If this must be done, use the 'subprocess' module instead and pass the arguments as a list. + message: | + The application was found using Jinja2 `Environment` without autoescaping enabled. If using in + the context of HTML this could lead to Cross-Site Scripting (XSS) attacks when rendering with + user-supplied input. + + Unfortunately, Jinja2 does not support context-aware escaping, meaning it is insufficient to + protect against + XSS for the various web contexts. It is important to encode the data depending on the specific + context + it + is used in. There are at least six context types: + + - Inside HTML tags `
context 1
` + - Inside attributes: `
` + - Inside event attributes `` + - Inside script blocks: `` + - Unsafe element HTML assignment: `element.innerHTML = "context 5"` + - Inside URLs: `link` + + Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if + user input + is ever output inside of script tags. + + User input that is displayed within the application must be encoded, sanitized or validated + to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be + taken + to not mix server-side templating with client-side templating, as the server-side templating + will + not encode things like {{ 7*7 }} which may execute client-side templating features. + + It is _NOT_ advised to encode user input prior to inserting into a data store. The data will + need to be + encoded depending on context of where it is output. It is much safer to force the displaying + system to + handle the encoding and not attempt to guess how it should be encoded. + + To handle different contexts, one approach would be to write custom Jinja2 filters. Below is + an example + that escapes or encodes links and potentially malicious script, note this does not include + other contexts + such as CSS or attributes: + ``` + from jinja2 import Environment, select_autoescape, FileSystemLoader + from jinja2 import pass_eval_context + from markupsafe import Markup, escape + + @pass_eval_context + def escape_link(eval_ctx, value): + bad_link = "#JinjatmplZ" + # Block any values that start with // as that could be used to inject + # links to third party pages see: + https://en.wikipedia.org/wiki/Wikipedia:Protocol-relative_URL + if value.startswith('//'): + return bad_link + + # Only allow relative links + # if you want to allow links that start with http or ws replace with below: + # if not value.startswith('/'): and not value.startswith('http') and not + value.startswith('ws') + if not value.startswith('/'): + return bad_link + + # Alternatively, you could only call escape if autoescape is true + # if eval_ctx.autoescape: + # return escape(value) + # else + # return value + + return escape(value) + + # Create a replacement table + js_replacement = str.maketrans({ + '"': "\\u0022", + '`': "\\u0060", + '&': "\\u0026", + '\'': "\\u0027", + '+': "\\u002b", + '/': "\\/", + '<': "\\u003c", + '>': "\\u003e", + '\\': "\\\\", + '(': "\\u0028", + ')': "\\u0029", + }) + + @pass_eval_context + def escape_js(eval_ctx, value): + """ + Escape the input for use in ", + script_context="alert(1);alert`1`",) + ) + + # Sample template: + """ + + + + My Webpage + + +

My Webpage

+ {{ html_context }} + link + + + + """ + ``` + + For more information on autoescape see: + - https://jinja.palletsprojects.com/en/3.1.x/api/#autoescaping + + For more information on XSS see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-116 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/Command_Injection - subcategory: - - audit - technology: - - flask - pattern-either: - - patterns: - - pattern: os.system(...) - - pattern-either: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - os.system(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - $INTERM = <... $ROUTEVAR ...> - ... - os.system(..., <... $INTERM ...>, ...) - - pattern: os.system(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: os.system(..., <... flask.request.$W[...] ...>, ...) - - pattern: os.system(..., <... flask.request.$W(...) ...>, ...) - - pattern: os.system(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - os.system(<... $INTERM ...>) - - pattern: os.system(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - os.system(<... $INTERM ...>) - - pattern: os.system(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - os.system(<... $INTERM ...>) - - pattern: os.system(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - os.system(<... $INTERM ...>) - - pattern: os.system(...) - severity: ERROR - - id: python.flask.security.injection.path-traversal-open.path-traversal-open + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper encoding or escaping of output + patterns: + - pattern-inside: | + import jinja2 + ... + - pattern-not: jinja2.Environment(..., autoescape=True, ...) + - pattern-not: jinja2.Environment(..., autoescape=jinja2.select_autoescape(...),...) + - pattern-not: jinja2.Environment(..., autoescape=select_autoescape(...), ...) + - pattern: jinja2.Environment(...) + severity: WARNING + - id: python_escaping_rule-use-of-mako-templates languages: - python - message: Found request data in a call to 'open'. Ensure the request data is validated or sanitized, otherwise it could result in path traversal attacks. + message: "The application was found using mako templates without `default_filters`\nbeing passed to the `Template` or `TemplateLookup` constructors. If using \nin the context of HTML, this could lead to Cross-Site Scripting (XSS) attacks \nwhen rendering with user-supplied input.\n\nUnfortunately, Jinja2 does not support context-aware escaping, meaning it\nis insufficient to protect against XSS for the various web contexts. It is \nimportant to encode the data depending on the specific context it is used in. \nThere are at least six context types:\n\n- Inside HTML tags `
context 1
`\n- Inside attributes: `
`\n- Inside event attributes ``\n- Inside script blocks: ``\n- Unsafe element HTML assignment: `element.innerHTML = \"context 5\"`\n- Inside URLs: \n`link`\n\nScript blocks alone have multiple ways they need to be encoded. Extra care\nmust be taken if user input is ever output inside of script tags.\n\nUser input that is displayed within the application must be encoded,\nsanitized or validated to ensure it cannot be treated as HTML or executed \nas Javascript code. Care must also be taken to not mix server-side templating \nwith client-side templating, as the server-side templating will not encode things \nlike {{ 7*7 }} which may execute client-side templating features.\n\nIt is _NOT_ advised to encode user input prior to inserting into a data\nstore. The data will need to be encoded depending on context of where it is output. \nIt is much safer to force the displaying system to handle the encoding and \nnot attempt to guess how it should be encoded.\n\nTo handle different contexts, one approach would be to write custom mako\nfilters. Below is an example that escapes or encodes links and \npotentially malicious script, note this does not include other contexts \nsuch as CSS or attributes:\n```\n# filters.py module:\n\ndef escape_link(value):\n bad_link = \"#JinjatmplZ\"\n # Block any values that start with // as that could be used to inject\n # links to third party pages see:\nhttps://en.wikipedia.org/wiki/Wikipedia:Protocol-relative_URL\n if value.startswith('//'):\n return bad_link\n\n # Only allow relative links\n # if you want to allow links that start with http or ws replace with below:\n # if not value.startswith('/'): and not value.startswith('http') and not\nvalue.startswith('ws')\n if not value.startswith('/'):\n return bad_link\n\n return value\n\n# Create a replacement table\njs_replacement = str.maketrans({\n '\\0': \"\\\\u0000\",\n '\\t': \"\\\\t\",\n '\\n': \"\\\\n\",\n '\\v': \"\\\\u000b\",\n '\\f': \"\\\\f`\",\n '\\r': \"\\\\r\",\n '\"': \"\\\\u0022\",\n '`': \"\\\\u0060\",\n '&': \"\\\\u0026\",\n '\\'': \"\\\\u0027\",\n '+': \"\\\\u002b\",\n '/': \"\\\\/\",\n '<': \"\\\\u003c\",\n '>': \"\\\\u003e\",\n '\\\\': \"\\\\\\\\\",\n '(': \"\\\\u0028\",\n ')': \"\\\\u0029\",\n})\n\ndef escape_js(value):\n # Escape the input for use in \n\n\n\"\"\"\n\n# Load our template with default filters and our imported filters for\n# usage in template files\nt = Template(template_text,\n # By default enable the html filter with 'h'\n default_filters=['h'],\n # Import our custom filters\n imports=[\"from filters import escape_link, escape_js\"])\n\n# Render our template\nprint(t.render(html_context=\"\",\n link_context=\"/# onclick=alert(1)\",\n script_context=\"alert(1)\",)\n)\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-79 owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - subcategory: - - audit - technology: - - flask - pattern-either: - - patterns: - - pattern: open(...) - - pattern-either: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - open(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - with open(..., <... $ROUTEVAR ...>, ...) as $FD: - ... - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - $INTERM = <... $ROUTEVAR ...> - ... - open(..., <... $INTERM ...>, ...) - - pattern: open(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: open(..., <... flask.request.$W[...] ...>, ...) - - pattern: open(..., <... flask.request.$W(...) ...>, ...) - - pattern: open(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - open(<... $INTERM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - open(<... $INTERM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - open(<... $INTERM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - open(<... $INTERM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - with open(<... $INTERM ...>, ...) as $F: - ... - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - with open(<... $INTERM ...>, ...) as $F: - ... - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - with open(<... $INTERM ...>, ...) as $F: - ... - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - with open(<... $INTERM ...>, ...) as $F: - ... - - pattern: open(...) - severity: ERROR - - id: python.flask.security.injection.raw-html-concat.raw-html-format + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + patterns: + - pattern-either: + - pattern: mako.template.Template(...) + - pattern: mako.lookup.TemplateLookup(...) + - pattern-not: mako.lookup.TemplateLookup(..., default_filters=["..."]) + - pattern-not: mako.template.Template(..., default_filters=["..."]) + severity: WARNING + - id: python_exec_rule-exec-used languages: - python - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates (`flask.render_template`) which will safely render HTML instead. + message: "The application was found calling the `exec` function with a non-literal variable. If the\nvariable comes from user-supplied input, an adversary could compromise the entire system by\nexecuting arbitrary python code.\n\nTo remediate this issue, remove all calls to `exec` and consider alternative methods for\nexecuting the necessary business logic. There is almost no safe method of calling `eval` \nwith user-supplied input.\n\nIf the application only needs to convert strings into objects, consider using `json.loads`.\nIn some cases `ast.literal_eval` is recommended, but this should be avoided as it can still\nsuffer from other issues such as the ability for malicious code to crash the python\ninterpreter or application.\n\nExample using `json.loads`` to load in arbitrary data to create data structures:\n```\n# User supplied data as a blob of JSON\nuser_supplied_data = \"\"\"{\"user\": \"test\", \"metadata\": [1,2,3]}\"\"\"\n# Load the JSON\nuser_object = json.loads(user_supplied_data)\n# Manually add protected properties _after_ loading, never before\nuser_object[\"is_admin\"] = False\n# Work with the object\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: CWE-78 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://flask.palletsprojects.com/en/2.0.x/security/#cross-site-scripting-xss - subcategory: - - vuln - technology: - - flask - mode: taint - pattern-sanitizers: - - pattern: jinja2.escape(...) - - pattern: flask.escape(...) - - pattern: flask.render_template("~=/.*\.html", ...) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: '"$HTMLSTR" % ...' - - pattern: '"$HTMLSTR".format(...)' - - pattern: '"$HTMLSTR" + ...' - - pattern: f"$HTMLSTR{...}..." - - patterns: - - pattern-inside: | - $HTML = "$HTMLSTR" - ... - - pattern-either: - - pattern: $HTML % ... - - pattern: $HTML.format(...) - - pattern: $HTML + ... - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - pattern-sources: - - patterns: - - pattern-either: - - pattern: flask.request.$ANYTHING - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + patterns: + - pattern: exec(...) + - pattern-not: exec("...") severity: WARNING - - id: python.flask.security.injection.ssrf-requests.ssrf-requests + - id: python_exec_rule-os-path languages: - python - message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF). To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. + message: | + Starting a process with a shell; seems safe, but may be changed in the future, consider + rewriting without shell metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-78 owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery - subcategory: - - vuln - technology: - - flask + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') pattern-either: - - patterns: - - pattern: requests.$FUNC(...) - - pattern-either: - - pattern-inside: | - @$APP.$ROUTE_METHOD($ROUTE, ...) - def $ROUTE_FUNC(..., $ROUTEVAR, ...): - ... - requests.$FUNC(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.$ROUTE_METHOD($ROUTE, ...) - def $ROUTE_FUNC(..., $ROUTEVAR, ...): - ... - $INTERM = <... $ROUTEVAR ...> - ... - requests.$FUNC(..., <... $INTERM ...>, ...) - - metavariable-regex: - metavariable: $ROUTE_METHOD - regex: ^(route|get|post|put|delete|patch)$ - - pattern: requests.$FUNC(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: requests.$FUNC(..., <... flask.request.$W[...] ...>, ...) - - pattern: requests.$FUNC(..., <... flask.request.$W(...) ...>, ...) - - pattern: requests.$FUNC(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - requests.$FUNC(<... $INTERM ...>, ...) - - pattern: requests.$FUNC(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - requests.$FUNC(<... $INTERM ...>, ...) - - pattern: requests.$FUNC(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - requests.$FUNC(<... $INTERM ...>, ...) - - pattern: requests.$FUNC(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - requests.$FUNC(<... $INTERM ...>, ...) - - pattern: requests.$FUNC(...) - severity: ERROR - - id: python.flask.security.injection.subprocess-injection.subprocess-injection + - pattern: os.system("...", ...) + - pattern: $OS.popen("...", ...) + - pattern: $OS.popen2("...", ...) + - pattern: $OS.popen3("...", ...) + - pattern: $OS.popen4("...", ...) + - pattern: commands.getoutput("...", ...) + - pattern: commands.getstatusoutput("...", ...) + severity: INFO + - id: python_exec_rule-os-popen2 languages: - python - message: Detected user input entering a `subprocess` call unsafely. This could result in a command injection vulnerability. An attacker could use this vulnerability to execute arbitrary commands on the host, which allows them to download malware, scan sensitive data, or run any command they wish on the server. Do not let users choose the command to run. In general, prefer to use Python API versions of system commands. If you must use subprocess, use a dictionary to allowlist a set of commands. + message: | + Starting a process with a shell; seems safe, but may be changed in the future, consider + rewriting without shell metadata: category: security - confidence: HIGH - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-78 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - flask - mode: taint - options: - symbolic_propagation: true - pattern-sanitizers: - - patterns: - - pattern: $DICT[$KEY] - - focus-metavariable: $KEY - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: subprocess.$FUNC(...) - - pattern-not: subprocess.$FUNC("...", ...) - - pattern-not: subprocess.$FUNC(["...", ...], ...) - - pattern-not-inside: | - $CMD = ["...", ...] - ... - subprocess.$FUNC($CMD, ...) - - patterns: - - pattern: subprocess.$FUNC(["$SHELL", "-c", ...], ...) - - metavariable-regex: - metavariable: $SHELL - regex: ^(sh|bash|ksh|csh|tcsh|zsh)$ - - patterns: - - pattern: subprocess.$FUNC(["$INTERPRETER", ...], ...) - - metavariable-regex: - metavariable: $INTERPRETER - regex: ^(python|python\d)$ - pattern-sources: + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') + patterns: - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - severity: ERROR - - id: python.flask.security.injection.tainted-sql-string.tainted-sql-string + - pattern: os.system(...) + - pattern: os.popen(...) + - pattern: os.popen2(...) + - pattern: os.popen3(...) + - pattern: os.popen4(...) + - pattern: popen2.popen2(...) + - pattern: popen2.popen3(...) + - pattern: popen2.popen4(...) + - pattern: popen2.Popen3(...) + - pattern: popen2.Popen4(...) + - pattern: commands.getoutput(...) + - pattern: commands.getstatusoutput("") + severity: INFO + - id: python_exec_rule-start-process-with-no-shell languages: - python - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as SQLAlchemy which will protect your queries. + message: | + Found dynamic content when spawning a process. This is dangerous if externaldata can reach this + function call because it allows a malicious actor toexecute commands. Ensure no external data + reaches here. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-704: Incorrect Type Conversion or Cast' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-78 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql - - https://www.tutorialspoint.com/sqlalchemy/sqlalchemy_quick_guide.htm - - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-more-specific-text-with-table-expression-literal-column-and-expression-column - subcategory: - - vuln - technology: - - sqlalchemy - - flask - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR" % ... - - pattern: | - "$SQLSTR".format(...) - - pattern: | - f"$SQLSTR{...}..." - - metavariable-regex: - metavariable: $SQLSTR - regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.* - pattern-sources: - - patterns: - - pattern-either: - - pattern: flask.request.$ANYTHING - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR - severity: ERROR - - id: python.flask.security.injection.tainted-url-host.tainted-url-host + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') + patterns: + - pattern-either: + - patterns: + - pattern-not: os.$W("...", ...) + - pattern-either: + - pattern: os.execl(...) + - pattern: os.execle(...) + - pattern: os.execlp(...) + - pattern: os.execlpe(...) + - pattern: os.execv(...) + - pattern: os.execve(...) + - pattern: os.execvp(...) + - pattern: os.execvpe(...) + - pattern: os.startfile(...) + - patterns: + - pattern-either: + - pattern: os.spawnl(...) + - pattern: os.spawnle(...) + - pattern: os.spawnlp(...) + - pattern: os.spawnlpe(...) + - pattern: os.spawnv(...) + - pattern: os.spawnve(...) + - pattern: os.spawnvp(...) + - pattern: os.spawnvpe(...) + severity: WARNING + - id: python_exec_rule-subprocess-call languages: - python - message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. + message: | + Python possesses many mechanisms to invoke an external executable. However, + doing so may present a security issue if appropriate care is not taken to + sanitize any user provided or variable input. This plugin test is part of a + family of tests built to check for process spawning and warn appropriately. + Specifically, this test looks for the spawning of a subprocess without the + use of a command shell. This type of subprocess invocation is not + vulnerable to shell injection attacks, but care should still be taken to + ensure validity of input. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: CWE-78 owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - flask - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: '"$URLSTR" % ...' - - metavariable-pattern: - language: generic - metavariable: $URLSTR - patterns: - - pattern-either: - - pattern: $SCHEME://%s - - pattern: $SCHEME://%r - - patterns: - - pattern: '"$URLSTR".format(...)' - - metavariable-pattern: - language: generic - metavariable: $URLSTR - pattern: $SCHEME:// { ... } - - patterns: - - pattern: '"$URLSTR" + ...' - - metavariable-regex: - metavariable: $URLSTR - regex: .*://$ - - patterns: - - pattern: f"$URLSTR{...}..." - - metavariable-regex: - metavariable: $URLSTR - regex: .*://$ - - patterns: - - pattern-inside: | - $URL = "$URLSTR" - ... - - pattern: $URL += ... - - metavariable-regex: - metavariable: $URLSTR - regex: .*://$ - pattern-sources: - - patterns: - - pattern-either: - - pattern: flask.request.$ANYTHING - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') + patterns: + - pattern-not: subprocess.$FUNC($ARG, shell=<... True ...>) + - pattern-not: subprocess.$FUNC($ARG, shell=<... 'True' ...>) + - pattern-not: subprocess.$FUNC($ARG, shell=<... "True" ...>) + - pattern-either: + - pattern: | + subprocess.$FUNC($ARG, shell=False) + - pattern: | + subprocess.$FUNC($ARG, shell=0) + - pattern: | + subprocess.$FUNC($ARG, shell={...}) + - pattern: | + subprocess.$FUNC($ARG, shell=[...]) + - pattern: | + subprocess.$FUNC($ARG) severity: WARNING - - id: python.flask.security.injection.user-eval.eval-injection + - id: python_exec_rule-subprocess-popen-shell-true languages: - python - message: Detected user data flowing into eval. This is code injection and should be avoided. + message: | + Found `subprocess` function `$FUNC` with `shell=True`. This is dangerous because this call will + spawn the command using a shell process. Doing so propagates current shell settings and + variables, + which makes it much easier for a malicious actor to execute commands. Use `shell=False` + instead. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-78 owasp: - - A03:2021 - Injection - references: - - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html - subcategory: - - vuln - technology: - - flask - pattern-either: - - patterns: - - pattern: eval(...) - - pattern-either: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - eval(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - $INTERM = <... $ROUTEVAR ...> - ... - eval(..., <... $INTERM ...>, ...) - - pattern: eval(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: eval(..., <... flask.request.$W[...] ...>, ...) - - pattern: eval(..., <... flask.request.$W(...) ...>, ...) - - pattern: eval(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - eval(..., <... $INTERM ...>, ...) - - pattern: eval(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - eval(..., <... $INTERM ...>, ...) - - pattern: eval(...) + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') + patterns: - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> + - pattern-not-inside: | ... - eval(..., <... $INTERM ...>, ...) - - pattern: eval(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> + $ARG = '...'.format('...') ... - eval(..., <... $INTERM ...>, ...) - - pattern: eval(...) + - pattern: subprocess.$FUNC($ARG, ...) + - pattern-not: subprocess.$FUNC('...', ...) + - pattern-not: subprocess.$FUNC('...' % '...', ...) + - pattern-not: subprocess.$FUNC('...'.format('...'), ...) + - pattern-either: + - pattern: subprocess.$FUNC(..., shell=True, ...) + - pattern: subprocess.$FUNC(..., shell=[$V, ...], ...) + - pattern: 'subprocess.$FUNC(..., shell={$K: $V, ...}, ...)' + - patterns: + - pattern: subprocess.$FUNC(..., shell=$INTVAL, ...) + - pattern-not: subprocess.$FUNC(..., shell=0, ...) + - metavariable-regex: + metavariable: $INTVAL + regex: ^[0-9]+$ + - patterns: + - pattern: subprocess.$FUNC(..., shell='$STRVAL', ...) + - pattern-not: subprocess.$FUNC(..., shell='', ...) severity: ERROR - - id: python.flask.security.injection.user-exec.exec-injection + - id: python_exec_rule-subprocess-shell-TRUE languages: - python - message: Detected user data flowing into exec. This is code injection and should be avoided. + message: | + subprocess call - check for execution of untrusted input metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM + cwe: CWE-78 owasp: - - A03:2021 - Injection - references: - - https://nedbatchelder.com/blog/201206/exec_really_is_dangerous.html - subcategory: - - vuln - technology: - - flask - pattern-either: - - patterns: - - pattern: exec(...) - - pattern-either: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - exec(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - $INTERM = <... $ROUTEVAR ...> - ... - exec(..., <... $INTERM ...>, ...) - - pattern: exec(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: exec(..., <... flask.request.$W[...] ...>, ...) - - pattern: exec(..., <... flask.request.$W(...) ...>, ...) - - pattern: exec(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - exec(..., <... $INTERM ...>, ...) - - pattern: exec(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - exec(..., <... $INTERM ...>, ...) - - pattern: exec(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - exec(..., <... $INTERM ...>, ...) - - pattern: exec(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - exec(..., <... $INTERM ...>, ...) - - pattern: exec(...) - severity: ERROR - - fix: | - True - id: python.jinja2.security.audit.autoescape-disabled-false.incorrect-autoescape-disabled + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') + patterns: + - pattern-not: subprocess.$FUNC(..., shell=True, ...) + - pattern: $FOO(..., shell=True, ...) + severity: WARNING + - id: python_file-permissions_rule-general-bad-permission languages: - python - message: Detected a Jinja2 environment with 'autoescaping' disabled. This is dangerous if you are rendering to a browser because this allows for cross-site scripting (XSS) attacks. If you are in a web context, enable 'autoescaping' by setting 'autoescape=True.' You may also consider using 'jinja2.select_autoescape()' to only enable automatic escaping for certain file extensions. + message: | + The application was found setting file permissions to overly permissive values. Consider + using the following values if the application user is the only process to access + the file: + + - 0400 - read only access to the file + - 0200 - write only access to the file + - 0600 - read/write access to the file + + Example creating a file with read/write permissions for the application user: + ``` + # Use octal values to set 0o600 (read/write access to the file) for the current + # user + os.chmod('somefile.txt', 0o600) + ``` + + For all other values please see: + https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation + metadata: + category: security + cwe: CWE-732 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Incorrect permission assignment for critical resource + patterns: + - pattern: os.chmod(...,$MASK) + - metavariable-regex: + metavariable: $MASK + regex: (0x..f|0o..[2,3,7]|stat.S_IXGRP|stat.S_IWOTH) + severity: WARNING + - id: python_files_rule-tarfile-unsafe-members + languages: + - python + message: | + The application may be vulnerable to a path traversal if it extracts untrusted archive files. + This vulnerability is colloquially known as 'Zip Slip'. Archive files may contain folders + which, + when extracted, may write outside of the intended directory. This is exploited by including + path traversal characters such as `../../other/directory` to overwrite or place files in system + or application directories. + + Extra care must be taken when extracting archive files as there are numerous concerns: + + - If possible, generate unique filenames instead of using the archives file names, as it may be + possible for users to overwrite files if the filenames are the same. + - Validate file paths are written with a prefixed, known trusted directory. + - Only process regular files and not symbolic links, as some applications may attempt to + read/follow + the symbolic link, leading to arbitrary file read / write vulnerabilities. + + Example of securely processing an archive file: + ``` + import tarfile + import uuid + # import os + + tar = tarfile.open('some.tar') + + # Max number of allowed files in our archive + max_files = 10 + # Max size for all files in archive + max_size = 1024 * 1024 * 10 # 10MB + # Max size per file in archive + max_file_size = 1024 * 1024 # 1MB + + # Validate number of files in archive + if len(tar.getmembers()) > max_files: + raise Exception("Too many files in archive") + + total_size = 0 + # Loop over all files to see if we exceed max size + # if so, do not process any of them. + for f in tar.getmembers(): + total_size += f.size + if total_size >= max_size: + raise Exception("Archive files exceeded max file size") + + # Iterate over files now that we know the total size is within limits + for f in tar.getmembers(): + # Internally this calls TarInfo.isreg() which ensures + # the file is a regular file and not a sym link or directory + if not f.isfile(): + continue + + # Optional, set a limit on each file size + if f.size > max_file_size: + raise Exception(f"File {f.name} too large: {f.size}") + + # If original names are required, ensure that only the + # filename is used: + # filename = os.path.basename(f.name) + + # More secure, generate a UUID4 value instead + filename = uuid.uuid4().hex + + # Reset the archive filename to the basename + # Newer versions of python (3.11.4+) should use: + # new_tar = old_tar.replace(name=...new name...) + f.name = filename + + # Extract the file into a restricted directory, with our + # own user's attributes, not the file from the archive + tar.extract(f, '/opt/app/restricted/', set_attrs=False) + ``` + + For more information on tarfile see: + - https://docs.python.org/3/library/tarfile.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-116: Improper Encoding or Escaping of Output' - impact: MEDIUM - likelihood: LOW + cwe: CWE-22 owasp: - - A03:2021 - Injection - references: - - https://jinja.palletsprojects.com/en/2.11.x/api/#basics - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html - subcategory: - - vuln - technology: - - jinja2 + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') patterns: - - pattern: jinja2.Environment(... , autoescape=$VAL, ...) - - pattern-not: jinja2.Environment(... , autoescape=True, ...) - - pattern-not: jinja2.Environment(... , autoescape=jinja2.select_autoescape(...), ...) - - focus-metavariable: $VAL + - pattern-inside: | + import tarfile + ... + - pattern-either: + - patterns: + - pattern-inside: | + $TAR = tarfile.open(...) + ... + - pattern-either: + - pattern: $TAR.extractall(...) + - pattern: tarfile.extractall(..., members=$TAR) + - pattern: $TAR.extractall(..., members=[]) + - patterns: + - pattern: tarfile.extractall(...) + - pattern: tarfile.extractall(..., members=[]) severity: WARNING - - fix-regex: - regex: (.*)\) - replacement: \1, autoescape=True) - id: python.jinja2.security.audit.missing-autoescape-disabled.missing-autoescape-disabled + - id: python_flask_rule-app-debug languages: - python - message: Detected a Jinja2 environment without autoescaping. Jinja2 does not autoescape by default. This is dangerous if you are rendering to a browser because this allows for cross-site scripting (XSS) attacks. If you are in a web context, enable autoescaping by setting 'autoescape=True.' You may also consider using 'jinja2.select_autoescape()' to only enable automatic escaping for certain file extensions. + message: | + The Flask application is running with `debug=True` configured. By enabling this option, certain + exceptions or errors could cause sensitive information to be leaked in HTTP responses. + + Additionally, it is not recommended to run a Flask application using `Flask.run(...)` in + production. Instead, a WSGI server such as + [gunicorn](https://flask.palletsprojects.com/en/2.3.x/deploying/gunicorn/) + or [waitress](https://flask.palletsprojects.com/en/2.3.x/deploying/waitress/) be used instead. + + For more information on deployment options for Flask applications see: + - https://flask.palletsprojects.com/en/2.3.x/deploying/ metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-116: Improper Encoding or Escaping of Output' - impact: MEDIUM - likelihood: LOW + cwe: CWE-489 owasp: - - A03:2021 - Injection - references: - - https://jinja.palletsprojects.com/en/2.11.x/api/#basics - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html - subcategory: - - vuln - technology: - - jinja2 + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Medium + shortDescription: Active debug code patterns: - - pattern-not: jinja2.Environment(..., autoescape=$VAL, ...) - - pattern: jinja2.Environment(...) + - pattern-inside: | + import flask + ... + - pattern: $APP.run(..., debug=True, ...) severity: WARNING - - id: python.jwt.security.jwt-hardcode.jwt-python-hardcoded-secret + - id: python_ftp_rule-ftplib languages: - python - message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' + message: | + The application was found using an FTP library. As FTP does not provide encryption, it is + strongly recommended that any file transfers be done over a more secure transport such as + SSH. + + The [paramiko](https://www.paramiko.org/) library can be used with an SCP module to allow + secure file transfers. + + Example using `paramiko` SSH client and the `scp` module: + ``` + import paramiko + import scp + + # Create an SSH client + with paramiko.SSHClient() as ssh: + # Load the system host keys so we can confirm the + # host we are connecting to is legitimate + ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts') + + # Connect to the remote host using our SSH private key + ssh.connect(hostname='example.org', + port=22, + username='appuser', + key_filename='/home/appuser/.ssh/private_key') + + # Create an SCP client with the ssh transport and copy files + with scp.SCPClient(ssh.get_transport()) as secure_copy: + secure_copy.get('remote/test.file', 'local/test.file') + secure_copy.put('local/some.file', 'remote/some.file') + ``` + + For more information on the paramiko module see: + - https://www.paramiko.org/ + + For more information on the scp module see: + - https://github.com/jbardin/scp.py metadata: category: security - confidence: HIGH - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-319 owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - vuln - technology: - - jwt - patterns: - - pattern: | - jwt.encode($X, $SECRET, ...) - - focus-metavariable: $SECRET - - pattern: | - "..." - severity: ERROR - - id: python.jwt.security.jwt-none-alg.jwt-python-none-alg + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Cleartext transmission of sensitive information + pattern: ftplib.$ANYTHING(...) + severity: WARNING + - id: python_log_rule-logging-config-insecure-listen languages: - python - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + message: | + The application was found calling the `logging.config.listen`` function, which provides the + ability to listen for + external configuration files over a socket server. This listen socket parses part of the + configuration and calls + `eval` on the supplied configuration file. A local user, or an adversary who is able to + exploit + a Server Side Request Forgery (SSRF) attack to communicate over localhost, would be able to + execute arbitrary + code by passing in a logging config that contains python code. + + To remediate the issue, remove the call to `logging.config.listen` method. + + For more information on the listen functionality see: + - https://docs.python.org/3/library/logging.config.html#logging.config.listen metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-94 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - vuln - technology: - - jwt - pattern-either: - - pattern: | - jwt.encode(...,algorithm="none",...) - - pattern: jwt.decode(...,algorithms=[...,"none",...],...) - severity: ERROR - - fix: | - True - id: python.jwt.security.unverified-jwt-decode.unverified-jwt-decode + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper control of generation of code ('Code Injection') + patterns: + - pattern: logging.config.listen(...) + severity: WARNING + - id: python_random_rule-random languages: - python - message: Detected JWT token decoded with 'verify=False'. This bypasses any integrity checks for the token which means the token could be tampered with by malicious actors. Ensure that the JWT token is verified. + message: | + Depending on the context, generating weak random numbers may expose cryptographic functions, + which rely on these numbers, to be exploitable. When generating numbers for sensitive values + such as tokens, nonces, and cryptographic keys, it is recommended that the `secrets` module + be used instead. + + Example using the secrets module: + ``` + import secrets + + # Generate a secure random 64 byte array + random_bytes = secrets.token_bytes(64) + print(random_bytes) + + # Generate a secure random 64 byte array as a hex string + random_bytes_hex = secrets.token_hex(64) + + # Generate a secure random 64 byte array base64 encoded for use in URLs + random_string = secrets.token_urlsafe(64) + ``` + + For more information on the `secrets` module see: + - https://docs.python.org/3/library/secrets.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-287: Improper Authentication' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-338 owasp: - - A02:2017 - Broken Authentication - - A07:2021 - Identification and Authentication Failures - references: - - https://github.com/we45/Vulnerable-Flask-App/blob/752ee16087c0bfb79073f68802d907569a1f0df7/app/app.py#L96 - subcategory: - - audit - technology: - - jwt - patterns: - - pattern-either: - - patterns: - - pattern: | - jwt.decode(..., options={..., "verify_signature": $BOOL, ...}, ...) - - metavariable-pattern: - metavariable: $BOOL - pattern: | - False - - focus-metavariable: $BOOL - - patterns: - - pattern: | - $OPTS = {..., "verify_signature": $BOOL, ...} - ... - jwt.decode(..., options=$OPTS, ...) - - metavariable-pattern: - metavariable: $BOOL - pattern: | - False - - focus-metavariable: $BOOL - severity: ERROR - - id: python.lang.security.audit.dangerous-asyncio-exec-tainted-env-args.dangerous-asyncio-exec-tainted-env-args + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Low + shortDescription: Use of cryptographically weak pseudo-random number generator (PRNG) + pattern-either: + - pattern: random.random(...) + - pattern: random.randrange(...) + - pattern: random.randint(...) + - pattern: random.choice(...) + - pattern: random.uniform(...) + - pattern: random.triangular(...) + severity: WARNING + - id: python_requests_rule-request-without-timeout languages: - python - message: Detected subprocess function '$LOOP.subprocess_exec' with user controlled data. You may consider using 'shlex.escape()'. + message: | + The application was found using the `requests` module without configuring a timeout value for + connections. This could lead to uncontrolled resource consumption where the application could + run out of + socket descriptors, effectively causing a Denial of Service (DoS). + + To remediate this issue, pass in a `timeout=` argument to each `requests` call. + + Example using a timeout for an HTTP GET request: + ``` + # Issue a GET request to https://example.com with a timeout of 10 seconds + response = requests.get('https://example.com', timeout=10) + # Work with the response object + # ... + ``` + + For more information on using the requests module see: + - https://requests.readthedocs.io/en/latest/api/ metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-770 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Medium + shortDescription: Allocation of resources without limits or throttling + patterns: - pattern-either: - patterns: - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "...", ...) - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["...",...], ...) - - pattern: $LOOP.subprocess_exec(...) + - pattern: requests.$METHOD(..., timeout=$VAL, ...) + - metavariable-comparison: + comparison: $VAL <= 0 + metavariable: $VAL - patterns: - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) - - pattern: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) + - pattern: requests.$METHOD(..., timeout=$VAL, ...) + - metavariable-regex: + metavariable: $VAL + regex: (^None) - patterns: - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) - - pattern: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.audit.dangerous-asyncio-shell-tainted-env-args.dangerous-asyncio-shell-tainted-env-args + - pattern-not: requests.$METHOD(..., timeout=$VAL, ...) + - pattern-either: + - pattern: requests.$METHOD(..., ...) + - pattern: requests.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (get|put|delete|post|options|head|patch) + severity: WARNING + - id: python_snmp_rule-insecure-snmp-version languages: - python - message: Detected asyncio subprocess function with user controlled data. You may consider using 'shlex.escape()'. + message: | + Pysnmp was detected using versions SNMPv1 or SNMPv2. SNPMv1 and SNMPv2 are insecure + and should no longer be used as they do not offer encryption. + + If possible, query SNMP devices using SNMPv3 instead. + + Example querying a device using SNMPv3 with SHA-AES: + ``` + from pysnmp.hlapi import * + # Create the snpm iterator + iterator = getCmd( + SnmpEngine(), + # Configure using SHA AES + UsmUserData('usr-sha-aes', 'authkey1', 'privkey1', + authProtocol=USM_AUTH_HMAC96_SHA, + privProtocol=USM_PRIV_CFB128_AES), + UdpTransportTarget(('demo.snmplabs.com', 161)), + ContextData(), + ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)) + ) + ``` + + For more information on using SNMPv3 with `Pysnmp` see: + - https://pysnmp.readthedocs.io/en/latest/examples/hlapi/v3arch/asyncore/sync/manager/cmdgen/snmp-versions.html#snmpv3-auth-sha-privacy-aes128 metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-319 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.python.org/3/library/asyncio-subprocess.html - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: $LOOP.subprocess_shell($PROTOCOL, $CMD) - - pattern-inside: asyncio.subprocess.create_subprocess_shell($CMD, ...) - - pattern-inside: asyncio.create_subprocess_shell($CMD, ...) - - focus-metavariable: $CMD - - pattern-not-inside: | - $CMD = "..." - ... - - pattern-not: $LOOP.subprocess_shell($PROTOCOL, "...") - - pattern-not: asyncio.subprocess.create_subprocess_shell("...", ...) - - pattern-not: asyncio.create_subprocess_shell("...", ...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.audit.dangerous-code-run-tainted-env-args.dangerous-interactive-code-run-tainted-env-args + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Cleartext transmission of sensitive information + pattern-either: + - pattern: pysnmp.hlapi.CommunityData(..., mpModel=0, ...) + - pattern: pysnmp.hlapi.CommunityData(..., mpModel=1, ...) + severity: WARNING + - id: python_snmp_rule-snmp-weak-cryptography languages: - python - message: Found user controlled data inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. + message: "Pysnmp was detected using SNMPv3 without authentication or encryption\nprotections enabled.\n\n- Use of `usmNoAuthProtocol` or `usmNoPrivProtocol` indicates that\neither authentication or privacy, respectively, is not being used. \n- The absence of `authKey` (or `authKey=None`) implies no authentication, \nwhich is equivalent to using `usmNoAuthProtocol`. \n- The absence of `privKey` (or `privKey=None`) implies no privacy (encryption), \nwhich is equivalent to using `usmNoPrivProtocol`.\n\nTo enhance the security of your SNMP communications, it is recommended to use both\nauthentication and privacy features in SNMPv3:\n\n- Use SHA for Authentication: SHA (Secure Hash Algorithm) is a more secure option \nfor SNMP message authentication. To use SHA, set the `authProtocol` to \n`usmHMACSHAAuthProtocol` and provide a strong `authKey`.\n- Use AES for Privacy: AES (Advanced Encryption Standard) is recommended for \nencrypting SNMP messages. Set the `privProtocol` to `usmAesCfb128Protocol`\nor a similar AES-based protocol and specify a strong `privKey`.\n\nExample of secure `UsmUserData` configuration:\n``` \n from pysnmp.hlapi import UsmUserData, usmHMACSHAAuthProtocol, usmAesCfb128Protocol\n \n user_data = UsmUserData('username','authKey', 'privKey', \n authProtocol=usmHMACSHAAuthProtocol,\n privProtocol=usmAesCfb128Protocol)\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM + cwe: CWE-319 owasp: - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Cleartext transmission of sensitive information + pattern-either: + - pattern-regex: UsmUserData(.*usmNoAuthProtocol.*) + - pattern-regex: UsmUserData(.*usmNoPrivProtocol.*) + - pattern: | + UsmUserData(..., authKey=None, ...) + - pattern: | + UsmUserData(..., privKey=None, ...) + - pattern: | + UsmUserData(..., authProtocol=(1,3,6,1,6,3,10,1,1,1), ...) + - pattern: | + UsmUserData(..., privProtocol=(1,3,6,1,6,3,10,1,2,1), ...) - patterns: - - pattern-either: - - pattern-inside: | - $X = code.InteractiveConsole(...) - ... - - pattern-inside: | - $X = code.InteractiveInterpreter(...) - ... - - pattern-either: - - pattern-inside: | - $X.push($PAYLOAD,...) - - pattern-inside: | - $X.runsource($PAYLOAD,...) - - pattern-inside: | - $X.runcode(code.compile_command($PAYLOAD),...) - - pattern-inside: | - $PL = code.compile_command($PAYLOAD,...) - ... - $X.runcode($PL,...) - - pattern: $PAYLOAD - - pattern-not: | - $X.push("...",...) - pattern-not: | - $X.runsource("...",...) + UsmUserData($NAME,$AUTHKEY,"...", ...) - pattern-not: | - $X.runcode(code.compile_command("..."),...) + UsmUserData(..., privKey=$PRIVKEY, ...) - pattern-not: | - $PL = code.compile_command("...",...) - ... - $X.runcode($PL,...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS + UsmUserData(..., privProtocol=$PRIVPROT, ...) + - pattern: | + UsmUserData(...) severity: WARNING - - id: python.lang.security.audit.dangerous-os-exec-tainted-env-args.dangerous-os-exec-tainted-env-args + - id: python_sql_rule-hardcoded-sql-expression languages: - python - message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. + message: | + SQL Injection is a critical vulnerability that can lead to data or system compromise. By + dynamically generating SQL query strings, user input may be able to influence the logic of + the SQL statement. This could lead to an adversary accessing information they should + not have access to, or in some circumstances, being able to execute OS functionality or code. + + Replace all dynamically generated SQL queries with parameterized queries. In situations where + dynamic queries must be created, never use direct user input, but instead use a map or + dictionary of valid values and resolve them using a user supplied key. + + For example, some database drivers do not allow parameterized queries for `>` or `<` comparison + operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the + user + supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` + values to be used in the construction of the dynamic query. The same goes for other queries + where + column or table names are required but cannot be parameterized. + + Example using `PreparedStatement` queries: + ``` + import sqlite3 + + # Create a new database (in memory) + con = sqlite3.connect(":memory:") + # Get a cursor from the connection + cur = con.cursor() + # Create a tuple of the value to be used in the parameterized query + params = ('user-input',) + # execute the statement, passing in the params for the value + cur.execute("select name from sqlite_master where name = ?", params) + # work with the result + result = cur.fetchall() + ``` + + For more information on SQL Injection see OWASP: + https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + category: security + cwe: CWE-89 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an SQL Command ('SQL Injection') mode: taint - options: - symbolic_propagation: true pattern-sinks: - patterns: - - pattern-either: - - patterns: - - pattern-not: os.$METHOD("...", ...) - - pattern: os.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (execl|execle|execlp|execlpe|execv|execve|execvp|execvpe) - - patterns: - - pattern-not: os.$METHOD("...", [$PATH,"...","...",...],...) - - pattern-inside: os.$METHOD($BASH,[$PATH,"-c",$CMD,...],...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (execv|execve|execvp|execvpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-not: os.$METHOD("...", $PATH, "...", "...",...) - - pattern-inside: os.$METHOD($BASH, $PATH, "-c", $CMD,...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (execl|execle|execlp|execlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - pattern: $DB.execute(...) + - pattern-not: + pattern-either: + - pattern: $DB.execute("...") + - pattern: $DB.execute("$QUERY" % "...") + - pattern: $DB.execute("$QUERY" + "...") pattern-sources: - patterns: - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS + - pattern: | + "$QUERY" % ... + - pattern: | + "$QUERY".format(...) + - pattern: | + f"$QUERY{...}..." + - pattern: | + "$QUERY" + ... + - pattern: | + $TMP = "$QUERY" + ... + $SQL = $TMP + "..." % ... + - pattern: "$SQL = \"$QUERY\"\n...\n$SQL += ... \n" + - metavariable-regex: + metavariable: $QUERY + regex: (?i)^(SELECT|INSERT|UPDATE|DELETE)\s + severity: WARNING + - id: python_ssh_rule-ssh-nohost-key-verification + languages: + - python + message: | + The application was found to ignore host keys. Host keys are important as + they provide assurance that the client can prove that the host is trusted. + By ignoring these host keys, it is impossible for the client to validate the + connection is to a trusted host. + + To remediate this issue, remove the call to `set_missing_host_key_policy(...)` which + sets the host key policy. Instead, load key files using either `load_system_host_keys` + or `load_host_keys` to only allow known good hosts. By not setting a host key policy + for unknown hosts, `paramiko`'s default policy is to use `RejectPolicy`. + + Example configuration connecting to a known, trusted host, and not allowing connections + to unknown hosts: + ``` + import paramiko + + # Create an SSH client + with paramiko.SSHClient() as ssh: + # Load the system host keys so we can confirm the + # host we are connecting to is legitimate + ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts') + + # Connect to the remote host using our SSH private key + ssh.connect(hostname='example.org', + port=22, + username='appuser', + key_filename='/home/appuser/.ssh/private_key') + ``` + + For more information on `set_missing_host_key_policy` see: + - https://docs.paramiko.org/en/stable/api/client.html#paramiko.client.SSHClient.set_missing_host_key_policy + metadata: + category: security + cwe: CWE-322 + owasp: + - A5:2017-Broken Access Control + - A07:2021-Identification and Authentication Failures + security-severity: Medium + shortDescription: Key exchange without entity authentication + patterns: + - pattern-inside: | + $CLIENT = paramiko.client.SSHClient(...) + ... + $CLIENT.set_missing_host_key_policy(...) + - pattern-either: + - pattern: paramiko.client.AutoAddPolicy + - pattern: paramiko.client.WarningPolicy severity: ERROR - - id: python.lang.security.audit.dangerous-spawn-process-tainted-env-args.dangerous-spawn-process-tainted-env-args + - id: python_ssl_rule-req-no-certvalid languages: - python - message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. + message: | + The application was found using the `requests` module without configuring a timeout value for + connections. The `verify=False` argument has been set, which effectively disables the + validation + of server certificates. + + This allows for an adversary who is in between the application and the target host to intercept + potentially sensitive information or transmit malicious data. + + To remediate this issue either remove the `verify=False` argument, or set `verify=True`to each + `requests` call. + + Example verifying server certificates for an HTTP GET request: + ``` + # Issue a GET request to https://example.com with a timeout of 10 seconds and verify the + # server certificate explicitly. + response = requests.get('https://example.com', timeout=10, verify=True) + # Work with the response object + # ... + ``` + + For more information on using the requests module see: + - https://requests.readthedocs.io/en/latest/api/ metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-295 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-not: os.$METHOD($MODE, "...", ...) - - pattern-inside: os.$METHOD($MODE, $CMD, ...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) - - patterns: - - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...) - - pattern-inside: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...) - - pattern-inside: os.$METHOD($MODE, $BASH, "-c", $CMD,...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: Medium + shortDescription: Improper certificate validation + patterns: + - pattern-either: + - pattern: requests.put(..., verify=False, ...) + - pattern: requests.patch(..., verify=False, ...) + - pattern: requests.delete(..., verify=False, ...) + - pattern: requests.head(..., verify=False, ...) + - pattern: requests.options(..., verify=False, ...) + - pattern: requests.request(..., verify=False, ...) + - pattern: requests.get(..., verify=False, ...) + - pattern: requests.post(..., verify=False, ...) severity: ERROR - - id: python.lang.security.audit.dangerous-subinterpreters-run-string-tainted-env-args.dangerous-subinterpreters-run-string-tainted-env-args + - id: python_ssl_rule-ssl-no-version languages: - python - message: Found user controlled content in `run_string`. This is dangerous because it allows a malicious actor to run arbitrary Python code. + message: | + The application was found calling `ssl.wrap_socket` without a TLS protocol version specified. + Additionally, `ssl.wrap_socket` has been deprecated since Python 3.7. It is strongly + recommended + that newer applications use TLS 1.2 or 1.3 and `SSLContext.wrap_socket`. + + To remediate this issue, create a new TLS context and pass in `ssl.PROTOCOL_TLS_CLIENT` + for clients or `ssl.PROTOCOL_TLS_SERVER` for servers to the `ssl.SSLContext(...)` `protocol=` + argument. When converting the socket to a TLS socket, use the new `SSLContext.wrap_socket` + method instead. + + + Example creating a TLS 1.3 client socket connection by using a newer version of Python + (3.11.4) and + the SSL module: + ``` + import ssl + import socket + + # Create our initial socket + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + # Connect the socket + sock.connect(('www.example.org', 443)) + + # Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT + # This will auto-select the highest grade TLS protocol version (1.3) + context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) + # Load our a certificates for server certificate authentication + context.load_verify_locations('cert.pem') + # Create our TLS socket, and validate the server hostname matches + with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock: + # Send some bytes over the socket (HTTP request in this case)\ + data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8') + sent_bytes = tls_sock.send(data) + # Validate number of sent bytes + # ... + # Read the response + resp = tls_sock.recv() + # Work with the response + # ... + ``` + + For more information on the ssl module see: + - https://docs.python.org/3/library/ssl.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM + cwe: CWE-326 owasp: - - A03:2021 - Injection - references: - - https://bugs.python.org/issue43472 - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-inside: | - _xxsubinterpreters.run_string($ID, $PAYLOAD, ...) - - pattern-not: | - _xxsubinterpreters.run_string($ID, "...", ...) - - pattern: $PAYLOAD - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Inadequate encryption strength + patterns: + - pattern: ssl.wrap_socket() severity: WARNING - - id: python.lang.security.audit.dangerous-subprocess-use-tainted-env-args.dangerous-subprocess-use-tainted-env-args + - id: python_ssl_rule-ssl-with-bad-version languages: - python - message: Detected subprocess function '$FUNC' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.escape()'. + message: | + The application was found calling an SSL module with SSL or TLS protocols that have known + deficiencies. + It is strongly recommended that newer applications use TLS 1.2 or 1.3 and + `SSLContext.wrap_socket`. + + If using the `pyOpenSSL` module, please note that it has been deprecated and the Python + Cryptographic Authority + strongly suggests moving to use the [pyca/cryptography](https://github.com/pyca/cryptography) + module instead. + + To remediate this issue for the `ssl` module, create a new TLS context and pass in + `ssl.PROTOCOL_TLS_CLIENT` for clients or `ssl.PROTOCOL_TLS_SERVER` for servers to the + `ssl.SSLContext(...)` `protocol=` + argument. When converting the socket to a TLS socket, use the new `SSLContext.wrap_socket` + method instead. + + Example creating a TLS 1.3 client socket connection by using a newer version of Python + (3.11.4) and + the SSL module: + ``` + import ssl + import socket + + # Create our initial socket + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + # Connect the socket + sock.connect(('www.example.org', 443)) + + # Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT + # This will auto-select the highest grade TLS protocol version (1.3) + context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) + # Load our a certificates for server certificate authentication + context.load_verify_locations('cert.pem') + # Create our TLS socket, and validate the server hostname matches + with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock: + # Send some bytes over the socket (HTTP request in this case)\ + data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8') + sent_bytes = tls_sock.send(data) + # Validate number of sent bytes + # ... + # Read the response + resp = tls_sock.recv() + # Work with the response + # ... + ``` + + For more information on the ssl module see: + - https://docs.python.org/3/library/ssl.html + + For more information on pyca/cryptography and openssl see: + - https://cryptography.io/en/latest/openssl/ metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-326 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess - - https://docs.python.org/3/library/subprocess.html - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-not: subprocess.$FUNC("...", ...) - - pattern-not: subprocess.$FUNC(["...",...], ...) - - pattern-not: subprocess.$FUNC(("...",...), ...) - - pattern-not: subprocess.CalledProcessError(...) - - pattern-not: subprocess.SubprocessError(...) - - pattern: subprocess.$FUNC($CMD, ...) - - patterns: - - pattern-not: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...) - - pattern: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD) - - patterns: - - pattern-not: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...],...) - - pattern-not: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...),...) - - pattern-either: - - pattern: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD], ...) - - pattern: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD), ...) - - patterns: - - pattern-not: subprocess.$FUNC("=~/(python)/","...",...) - - pattern: subprocess.$FUNC("=~/(python)/", $CMD) - - patterns: - - pattern-not: subprocess.$FUNC(["=~/(python)/","...",...],...) - - pattern-not: subprocess.$FUNC(("=~/(python)/","...",...),...) - - pattern-either: - - pattern: subprocess.$FUNC(["=~/(python)/", $CMD],...) - - pattern: subprocess.$FUNC(("=~/(python)/", $CMD),...) - - focus-metavariable: $CMD - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Inadequate Encryption Strength + patterns: + - pattern-either: + - pattern: ssl.PROTOCOL_SSLv2 + - pattern: ssl.PROTOCOL_SSLv3 + - pattern: ssl.PROTOCOL_TLSv1 + - pattern: ssl.PROTOCOL_TLSv1_1 + - pattern: pyOpenSSL.SSL.SSLv2_METHOD + - pattern: pyOpenSSL.SSL.SSLv23_METHOD + - pattern: pyOpenSSL.SSL.SSLv3_METHOD + - pattern: pyOpenSSL.SSL.TLSv1_METHOD + - pattern: pyOpenSSL.SSL.TLSv1_1_METHOD severity: ERROR - - id: python.lang.security.audit.dangerous-system-call-tainted-env-args.dangerous-system-call-tainted-env-args + - id: python_ssl_rule-unverified-context + languages: + - python + message: | + The application was found creating a SSL context using the `_create_unverified_context`. + This effectively disables the validation of server certificates. + + This allows for an adversary who is in between the application and the target host to intercept + potentially sensitive information or transmit malicious data. + + To remediate this issue remove the call to `_create_unverified_context` and either create a + default + context using `ssl.create_default_context` or create a context with TLS 1.3. + + Example creating a TLS 1.3 client socket connection by using a newer version of Python + (3.11.4) and + the SSL module: + ``` + import ssl + import socket + + # Create our initial socket + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + # Connect the socket + sock.connect(('www.example.org', 443)) + + # Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT + # This will auto-select the highest grade TLS protocol version (1.3) + context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) + # Load our a certificates for server certificate authentication + context.load_verify_locations('cert.pem') + # Create our TLS socket, and validate the server hostname matches + with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock: + # Send some bytes over the socket (HTTP request in this case)\ + data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8') + sent_bytes = tls_sock.send(data) + # Validate number of sent bytes + # ... + # Read the response + resp = tls_sock.recv() + # Work with the response + # ... + ``` + + Unverified SSL context detected. This will permit insecure connections without `verifyingSSL` + certificates. Use `ssl.create_default_context()` instead. + metadata: + category: security + cwe: CWE-295 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: Medium + shortDescription: Improper certificate validation + pattern: ssl._create_unverified_context(...) + severity: ERROR + - id: python_telnet_rule-import-telnib + languages: + - python + message: | + The application was found using a telnet library. As telnet does not provide encryption, it is + strongly recommended that communications use a more secure transport such as + SSH. + + The [paramiko](https://www.paramiko.org/) library can be used to initiate SSH connections. + + Example using `paramiko` SSH client: + ``` + import paramiko + import scp + + # Create an SSH client + with paramiko.SSHClient() as ssh: + # Load the system host keys so we can confirm the + # host we are connecting to is legitimate + ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts') + + # Connect to the remote host using our SSH private key + ssh.connect(hostname='example.org', + port=22, + username='appuser', + key_filename='/home/appuser/.ssh/private_key') + # Work with the connection + ``` + + For more information on the paramiko module see: + - https://www.paramiko.org/ + metadata: + category: security + cwe: CWE-319 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Medium + shortDescription: Cleartext transmission of sensitive information + patterns: + - pattern: import telnetlib + severity: ERROR + - id: python_tmpdir_rule-hardcodedtmp + languages: + - python + message: | + The application was found creating files in shared system temporary directories + (`/tmp` or `/var/tmp`) without using the `tempfile.TemporaryFile` function. Depending + on how the application uses this temporary file, an attacker may be able to create + symlinks that point to other files prior to the application creating or writing + to the target file, leading to unintended files being created or overwritten. + + Example using `tempfile.TemporaryFile` to write a file: + ``` + import tempfile + + # Open a new temporary file using a context manager + with tempfile.TemporaryFile() as fp: + # Write some data to the temporary file + fp.write(b'Some data') + # Seek back to beginning of file + fp.seek(0) + # Read it + data = fp.read() + # File is automatically closed/removed once we exit the with context + ``` + + For more information on alternative tempfile functions see: + - https://docs.python.org/3/library/tempfile.html + metadata: + category: security + cwe: CWE-377 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Insecure temporary file + pattern: $CALL("=~/^\/tmp.*/", ...) + severity: WARNING + - id: python_tmpdir_rule-mktemp-q + languages: + - python + message: | + The application was found creating temporary files with the insecure `mktemp` method. + Depending on how the application uses this temporary file, an attacker may be able to create + symlinks that point to other files prior to the application creating or writing + to the target file, leading to unintended files being created or overwritten. + + To remediate this issue consider using `tempfile.TemporaryFile` instead. + + Example using `tempfile.TemporaryFile` to write a file: + ``` + import tempfile + + # Open a new temporary file using a context manager + with tempfile.TemporaryFile() as fp: + # Write some data to the temporary file + fp.write(b'Some data') + # Seek back to beginning of file + fp.seek(0) + # Read it + data = fp.read() + # File is automatically closed/removed once we exit the with context + ``` + + For more information on alternative tempfile functions see: + - https://docs.python.org/3/library/tempfile.html + metadata: + category: security + cwe: CWE-377 + owasp: + - A3:2017-Sensitive Data Exposure + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Insecure temporary file + pattern: tempfile.mktemp(...) + severity: ERROR + - id: python_urlopen_rule-urllib-urlopen + languages: + - python + message: | + The application was found passing in a non-literal value to the `urllib` methods which issue + requests. `urllib` supports the `file://` scheme, which may allow an adversary who can control + the URL value to read arbitrary files on the file system. + + To remediate this issue either hardcode the URLs being used in urllib or use the `requests` + module instead. + + Example using the `requests` module to issue an HTTPS request: + ``` + import requests + # Issue a GET request to https://example.com with a timeout of 10 seconds + response = requests.get('https://example.com', timeout=10) + # Work with the response object + # ... + ``` + metadata: + category: security + cwe: CWE-939 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper authorization in handler for custom URL scheme + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: urllib.$METHOD(...) + - pattern: urllib.request.$METHOD(...) + - pattern-not: urllib.$METHOD("...") + - pattern-not: urllib.request.$METHOD("...") + - pattern-not: urllib.$METHOD("...", ...) + - pattern-not: urllib.request.$METHOD("...", ...) + - metavariable-regex: + metavariable: $METHOD + regex: (urlopen|urlretrieve) + - patterns: + - pattern-either: + - pattern-inside: | + $OPENER = urllib.URLopener(...) + ... + - pattern-inside: | + $OPENER = urllib.request.URLopener(...) + ... + - pattern-inside: | + $OPENER = urllib.FancyURLopener(...) + ... + - pattern-inside: | + $OPENER = urllib.request.FancyURLopener(...) + ... + - pattern-either: + - pattern: $OPENER.open(...) + - pattern: $OPENER.retrieve(...) + - pattern-not: $OPENER.open("...") + - pattern-not: $OPENER.retrieve("...") + severity: WARNING + - id: python_xml_rule-celement languages: - python - message: Found user-controlled data used in a system call. This could allow a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. + message: | + The application was found using the `xml.etree` package for processing XML. + Pythons default xml processors suffer from various XML parsing vulnerabilities + and care must be taken when handling XML data. Additionally, depending on the + version of Python, more critical vulnerabilities such as eXternal XML Entity + injection maybe exploitable. + + The `etree` package suffers from the following security risks as of Python 3.7.1: + * Billion laughs / exponential entity expansion - May allow an adversary to cause + a Denial of Service (DoS) against the application parsing arbitrary XML. + * Quadratic blowup entity expansion - Similar to above, but requires a larger input + to cause the Denial of Service. + + To remediate the above issues, consider using the + [defusedxml](https://pypi.org/project/defusedxml/) + library when processing untrusted XML. + + Example parsing an XML document using defusedxml: + ``` + from defusedxml.ElementTree import parse + + # Parse the inventory.xml file + et = parse('inventory.xml') + # Get the root element + root = et.getroot() + # Work with the root element + # ... + ``` + + For more information on the various XML parsers and their vulnerabilities please see: + - https://docs.python.org/3/library/xml.html#xml-vulnerabilities + + For more information on XML security see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python metadata: - asvs: - control_id: 5.2.4 Dyanmic Code Execution Features - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-611 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-not: os.$W("...", ...) - - pattern-either: - - pattern: os.system(...) - - pattern: | - $X = __import__("os") - ... - $X.system(...) - - pattern: | - $X = __import__("os") - ... - getattr($X, "system")(...) - - pattern: | - $X = getattr(os, "system") - ... - $X(...) - - pattern: | - $X = __import__("os") - ... - $Y = getattr($X, "system") - ... - $Y(...) - - pattern: os.popen(...) - - pattern: os.popen2(...) - - pattern: os.popen3(...) - - pattern: os.popen4(...) - pattern-sources: + - A4:2017-XML External Entities (XXE) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper restriction of XML external entity reference + pattern-either: - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.audit.dangerous-testcapi-run-in-subinterp-tainted-env-args.dangerous-testcapi-run-in-subinterp-tainted-env-args + - pattern: xml.etree.cElementTree.fromstring(...) + - pattern-not: xml.etree.cElementTree.fromstring("...") + - pattern: xml.etree.cElementTree.parse(...) + - pattern: xml.etree.cElementTree.iterparse(...) + - pattern: xml.etree.cElementTree.XMLParser(...) + severity: WARNING + - id: python_xml_rule-element languages: - python - message: Found user controlled content in `run_in_subinterp`. This is dangerous because it allows a malicious actor to run arbitrary Python code. + message: | + The application was found using the `xml.etree` package for processing XML. + Pythons default xml processors suffer from various XML parsing vulnerabilities + and care must be taken when handling XML data. Additionally, depending on the + version of Python, more critical vulnerabilities such as eXternal XML Entity + injection maybe exploitable. + + The `etree` package suffers from the following security risks as of Python 3.7.1: + * Billion laughs / exponential entity expansion - May allow an adversary to cause + a Denial of Service (DoS) against the application parsing arbitrary XML. + * Quadratic blowup entity expansion - Similar to above, but requires a larger input + to cause the Denial of Service. + + To remediate the above issues, consider using the + [defusedxml](https://pypi.org/project/defusedxml/) + library when processing untrusted XML. + + Example parsing an XML document using defusedxml: + ``` + from defusedxml.ElementTree import parse + + # Parse the inventory.xml file + et = parse('inventory.xml') + # Get the root element + root = et.getroot() + # Work with the root element + # ... + ``` + + For more information on the various XML parsers and their vulnerabilities please see: + - https://docs.python.org/3/library/xml.html#xml-vulnerabilities + + For more information on XML security see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM + cwe: CWE-611 owasp: - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - _testcapi.run_in_subinterp($PAYLOAD, ...) - - pattern-inside: | - test.support.run_in_subinterp($PAYLOAD, ...) - - pattern: $PAYLOAD - - pattern-not: | - _testcapi.run_in_subinterp("...", ...) - - pattern-not: | - test.support.run_in_subinterp("...", ...) - pattern-sources: + - A4:2017-XML External Entities (XXE) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper restriction of XML external entity reference + pattern-either: - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS + - pattern: xml.etree.ElementTree.fromstring(...) + - pattern-not: xml.etree.ElementTree.fromstring("...") + - pattern: xml.etree.ElementTree.parse(...) + - pattern: xml.etree.ElementTree.iterparse(...) + - pattern: xml.etree.ElementTree.XMLParser(...) severity: WARNING - - id: python.lang.security.audit.insecure-file-permissions.insecure-file-permissions + - id: python_xml_rule-etree languages: - python - message: These permissions `$BITS` are widely permissive and grant access to more people than may be necessary. A good default is `0o644` which gives read and write access to yourself and read access to everyone else. + message: | + The application was found using the `lxml.etree` package for processing XML. + Python's default XML processors suffer from various XML parsing vulnerabilities + and care must be taken when handling XML data. Additionally, depending on the + version of Python, more critical vulnerabilities such as eXternal XML Entity + injection maybe exploitable. + + The `etree` package suffers from the following security risks as of Python 3.7.1: + * Billion laughs / exponential entity expansion - May allow an adversary to cause + a Denial of Service (DoS) against the application parsing arbitrary XML. + * Quadratic blowup entity expansion - Similar to above, but requires a larger input + to cause the Denial of Service. + + To remediate the above issues, consider using the + [defusedxml](https://pypi.org/project/defusedxml/) + library when processing untrusted XML. + + Example parsing an XML document using defusedxml: + ``` + from defusedxml.ElementTree import parse + + # Parse the inventory.xml file + et = parse('inventory.xml') + # Get the root element + root = et.getroot() + # Work with the root element + # ... + ``` + + For more information on the various XML parsers and their vulnerabilities please see: + - https://docs.python.org/3/library/xml.html#xml-vulnerabilities + + For more information on XML security see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-276: Incorrect Default Permissions' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + cwe: CWE-611 owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - python - patterns: - - pattern-inside: os.$METHOD(...) - - metavariable-pattern: - metavariable: $METHOD - patterns: - - pattern-either: - - pattern: chmod - - pattern: lchmod - - pattern: fchmod - - pattern-either: - - patterns: - - pattern: os.$METHOD($FILE, $BITS, ...) - - metavariable-comparison: - comparison: $BITS >= 0o650 and $BITS < 0o100000 - metavariable: $BITS - - patterns: - - pattern: os.$METHOD($FILE, $BITS) - - metavariable-comparison: - comparison: $BITS >= 0o100650 - metavariable: $BITS - - patterns: - - pattern: os.$METHOD($FILE, $BITS, ...) - - metavariable-pattern: - metavariable: $BITS - patterns: - - pattern-either: - - pattern: <... stat.S_IWGRP ...> - - pattern: <... stat.S_IXGRP ...> - - pattern: <... stat.S_IWOTH ...> - - pattern: <... stat.S_IXOTH ...> - - pattern: <... stat.S_IRWXO ...> - - pattern: <... stat.S_IRWXG ...> - - patterns: - - pattern: os.$METHOD($FILE, $EXPR | $MOD, ...) - - metavariable-comparison: - comparison: $MOD == 0o111 - metavariable: $MOD + - A4:2017-XML External Entities (XXE) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper restriction of XML external entity reference + pattern-either: + - pattern: lxml.etree.parse(...) + - patterns: + - pattern: lxml.etree.fromstring(...) + - pattern-not: lxml.etree.fromstring("...") + - pattern: lxml.etree.RestrictedElement(...) + - pattern: lxml.etree.GlobalParserTLS(...) + - pattern: lxml.etree.getDefaultParser(...) + - pattern: lxml.etree.check_docinfo(...) severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.requests.request-session-http-in-with-context.request-session-http-in-with-context + - id: python_xml_rule-expatbuilder languages: - python - message: Detected a request using 'http://'. This request will be unencrypted. Use 'https://' instead. + message: | + The application was found using the `xml.dom.expatbuilder` which calls the `xml.dom.minidom` + package for processing XML. Python's default XML processors suffer from various XML parsing + vulnerabilities + and care must be taken when handling XML data. Additionally, depending on the + version of Python, more critical vulnerabilities such as eXternal XML Entity + injection maybe exploitable. + + The `xml.dom.minidom` package suffers from the following security risks as of Python 3.7.1: + * Billion laughs / exponential entity expansion - May allow an adversary to cause + a Denial of Service (DoS) against the application parsing arbitrary XML. + * Quadratic blowup entity expansion - Similar to above, but requires a larger input + to cause the Denial of Service. + + To remediate the above issues, consider using the + [defusedxml](https://pypi.org/project/defusedxml/) + library when processing untrusted XML. + + Example parsing an XML document using defusedxml: + ``` + from defusedxml.ElementTree import parse + + # Parse the inventory.xml file + et = parse('inventory.xml') + # Get the root element + root = et.getroot() + # Work with the root element + # ... + ``` + + For more information on the various XML parsers and their vulnerabilities please see: + - https://docs.python.org/3/library/xml.html#xml-vulnerabilities + + For more information on XML security see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python metadata: - asvs: - control_id: 9.2.1 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW + cwe: CWE-611 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - requests - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-inside: | - with requests.Session(...) as $SESSION: - ... - - pattern-either: - - pattern: $SESSION.$W($SINK, ...) - - pattern: $SESSION.request($METHOD, $SINK, ...) - - focus-metavariable: $SINK - pattern-sources: + - A4:2017-XML External Entities (XXE) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper restriction of XML external entity reference + pattern-either: - patterns: - - pattern: | - "$URL" - - metavariable-pattern: - language: regex - metavariable: $URL - patterns: - - pattern-regex: http:// - - pattern-not-regex: .*://localhost - - pattern-not-regex: .*://127\.0\.0\.1 - severity: INFO - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.requests.request-session-with-http.request-session-with-http + - pattern: xml.dom.expatbuilder.parse(...) + - pattern-not: xml.dom.expatbuilder.parse("...") + - pattern: xml.dom.expatbuilder.parseString(...) + severity: WARNING + - id: python_xml_rule-expatreader languages: - python - message: Detected a request using 'http://'. This request will be unencrypted. Use 'https://' instead. + message: | + The application was found using the `xml.sax.expatreader` package for processing XML. Python's + default XML processors suffer from various XML parsing vulnerabilities + and care must be taken when handling XML data. Additionally, depending on the + version of Python, more critical vulnerabilities such as eXternal XML Entity + injection maybe exploitable. + + The `xml.sax` package suffers from the following security risks as of Python 3.7.1: + * Billion laughs / exponential entity expansion - May allow an adversary to cause + a Denial of Service (DoS) against the application parsing arbitrary XML. + * Quadratic blowup entity expansion - Similar to above, but requires a larger input + to cause the Denial of Service. + + To remediate the above issues, consider using the + [defusedxml](https://pypi.org/project/defusedxml/) + library when processing untrusted XML. + + Example parsing an XML document using defusedxml: + ``` + from defusedxml.ElementTree import parse + + # Parse the inventory.xml file + et = parse('inventory.xml') + # Get the root element + root = et.getroot() + # Work with the root element + # ... + ``` + + For more information on the various XML parsers and their vulnerabilities please see: + - https://docs.python.org/3/library/xml.html#xml-vulnerabilities + + For more information on XML security see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python metadata: - asvs: - control_id: 9.1.1 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW + cwe: CWE-611 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - requests - mode: taint - options: - symbolic_propagation: true - pattern-sinks: + - A4:2017-XML External Entities (XXE) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper restriction of XML external entity reference + pattern-either: + - pattern: xml.dom.expatreader.parse(...) - patterns: - - pattern-either: - - pattern: requests.Session(...).$W($SINK, ...) - - pattern: requests.Session(...).request($METHOD, $SINK, ...) - - focus-metavariable: $SINK - pattern-sources: + - pattern: xml.dom.expatreader.parseString(...) + - pattern-not: xml.dom.expatreader.parseString("...") + - pattern: xml.dom.expatreader.parseString(...) + - pattern: xml.dom.expatreader.create_parser(...) + severity: WARNING + - id: python_xml_rule-minidom + languages: + - python + message: | + The application was found using the `xml.dom.minidom` package for processing XML. Python's + default XML processors suffer from various XML parsing vulnerabilities + and care must be taken when handling XML data. Additionally, depending on the + version of Python, more critical vulnerabilities such as eXternal XML Entity + injection maybe exploitable. + + The `xml.dom.minidom` package suffers from the following security risks as of Python 3.7.1: + * Billion laughs / exponential entity expansion - May allow an adversary to cause + a Denial of Service (DoS) against the application parsing arbitrary XML. + * Quadratic blowup entity expansion - Similar to above, but requires a larger input + to cause the Denial of Service. + + To remediate the above issues, consider using the + [defusedxml](https://pypi.org/project/defusedxml/) + library when processing untrusted XML. + + Example parsing an XML document using defusedxml: + ``` + from defusedxml.ElementTree import parse + + # Parse the inventory.xml file + et = parse('inventory.xml') + # Get the root element + root = et.getroot() + # Work with the root element + # ... + ``` + + For more information on the various XML parsers and their vulnerabilities please see: + - https://docs.python.org/3/library/xml.html#xml-vulnerabilities + + For more information on XML security see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python + metadata: + category: security + cwe: CWE-611 + owasp: + - A4:2017-XML External Entities (XXE) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper restriction of XML external entity reference + pattern-either: - patterns: - - pattern: | - "$URL" - - metavariable-pattern: - language: regex - metavariable: $URL - patterns: - - pattern-regex: http:// - - pattern-not-regex: .*://localhost - - pattern-not-regex: .*://127\.0\.0\.1 - severity: INFO - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.requests.request-with-http.request-with-http + - pattern: xml.dom.minidom.parseString(...) + - pattern-not: xml.dom.minidom.parseString("...") + - pattern: xml.dom.minidom.parse(...) + severity: WARNING + - id: python_xml_rule-pulldom languages: - python - message: Detected a request using 'http://'. This request will be unencrypted, and attackers could listen into traffic on the network and be able to obtain sensitive information. Use 'https://' instead. + message: | + The application was found using the `xml.dom.pulldom` package for processing XML. Python's + default XML processors suffer from various XML parsing vulnerabilities + and care must be taken when handling XML data. Additionally, depending on the + version of Python, more critical vulnerabilities such as eXternal XML Entity + injection maybe exploitable. + + The `xml.dom.pulldom` package suffers from the following security risks as of Python 3.7.1: + * Billion laughs / exponential entity expansion - May allow an adversary to cause + a Denial of Service (DoS) against the application parsing arbitrary XML. + * Quadratic blowup entity expansion - Similar to above, but requires a larger input + to cause the Denial of Service. + + To remediate the above issues, consider using the + [defusedxml](https://pypi.org/project/defusedxml/) + library when processing untrusted XML. + + Example parsing an XML document using defusedxml: + ``` + from defusedxml.ElementTree import parse + + # Parse the inventory.xml file + et = parse('inventory.xml') + # Get the root element + root = et.getroot() + # Work with the root element + # ... + ``` + + For more information on the various XML parsers and their vulnerabilities please see: + - https://docs.python.org/3/library/xml.html#xml-vulnerabilities + + For more information on XML security see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python metadata: - asvs: - control_id: 9.1.1 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW + cwe: CWE-611 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - requests - mode: taint - options: - symbolic_propagation: true - pattern-sinks: + - A4:2017-XML External Entities (XXE) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper restriction of XML external entity reference + pattern-either: - patterns: - - pattern-either: - - pattern: requests.$W($SINK, ...) - - pattern: requests.request($METHOD, $SINK, ...) - - pattern: requests.Request($METHOD, $SINK, ...) - - focus-metavariable: $SINK - pattern-sources: + - pattern: xml.dom.pulldom.parseString(...) + - pattern-not: xml.dom.pulldom.parseString("...") + - pattern: xml.dom.pulldom.parse(...) + severity: WARNING + - id: python_xml_rule-sax + languages: + - python + message: | + The application was found using the `xml.sax` package for processing XML. + Python's default XML processors suffer from various XML parsing vulnerabilities + and care must be taken when handling XML data. Additionally, depending on the + version of Python, more critical vulnerabilities such as eXternal XML Entity + injection maybe exploitable. + + The `xml.sax` package suffers from the following security risks as of Python 3.7.1: + * Billion laughs / exponential entity expansion - May allow an adversary to cause + a Denial of Service (DoS) against the application parsing arbitrary XML. + * Quadratic blowup entity expansion - Similar to above, but requires a larger input + to cause the Denial of Service. + + To remediate the above issues, consider using the + [defusedxml](https://pypi.org/project/defusedxml/) + library when processing untrusted XML. + + Example parsing an XML document using defusedxml: + ``` + from defusedxml.ElementTree import parse + + # Parse the inventory.xml file + et = parse('inventory.xml') + # Get the root element + root = et.getroot() + # Work with the root element + # ... + ``` + + For more information on the various XML parsers and their vulnerabilities please see: + - https://docs.python.org/3/library/xml.html#xml-vulnerabilities + + For more information on XML security see OWASP's guide: + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python + metadata: + category: security + cwe: CWE-611 + owasp: + - A4:2017-XML External Entities (XXE) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper restriction of XML external entity reference + pattern-either: + - pattern: xml.sax.parse(...) - patterns: - - pattern: | - "$URL" - - metavariable-pattern: - language: regex - metavariable: $URL - patterns: - - pattern-regex: http:// - - pattern-not-regex: .*://localhost - - pattern-not-regex: .*://127\.0\.0\.1 - severity: INFO - - id: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure + - pattern: xml.sax.parseString(...) + - pattern-not: xml.sax.parseString("...") + - pattern: xml.sax.make_parser(...) + severity: WARNING + - id: generic_injection_rule-BiDiTrojanSource languages: - - python - message: Detected a python logger call with a potential hardcoded secret $FORMAT_STRING being logged. This may lead to secret credentials being exposed. Make sure that the logger is not logging sensitive information. + - generic + message: "Unicode bidirectional (BiDi) control characters were detected in source code.\nThese characters can be used to reorder text and hide malicious code \n(CVE-2021-42574).\n\nBiDi override characters can make code appear different from its actual logic:\n- Text that appears as a comment might actually be executable code\n- Code that appears harmless might contain hidden malicious logic\n- Variable names and string literals may not reflect their true content\n\nMitigation Steps:\n- Remove any BiDi override characters\n- Only use standard ASCII characters in source code\n- If BiDi characters are required, thoroughly review the code\n\nSecure Code Example:\n```java\npublic class DataProcessor {\n // Use standard ASCII characters only\n public void processData(String data) {\n String cleanInput = data.trim(); // Clean the input\n System.out.println(\"Processing: \" + cleanInput); // Clear, readable code\n }\n}\n```\n\nReferences:\n- https://nvd.nist.gov/vuln/detail/CVE-2021-42574\n- https://trojansource.codes/\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-532: Insertion of Sensitive Information into Log File' - impact: MEDIUM - likelihood: LOW + cwe: CWE-94 owasp: - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures - subcategory: - - vuln - technology: - - python - patterns: - - pattern: | - $LOGGER_OBJ.$LOGGER_CALL($FORMAT_STRING,...) - - metavariable-regex: - metavariable: $LOGGER_OBJ - regex: (?i)(_logger|logger|self.logger|log) - - metavariable-regex: - metavariable: $LOGGER_CALL - regex: (debug|info|warn|warning|error|exception|critical) - - metavariable-regex: - metavariable: $FORMAT_STRING - regex: (?i).*(api.key|secret|credential|token|password).*\%s.* + - A03:2021-Injection + - A1:2017-Injection + security-severity: Low + shortDescription: Improper control of generation of code ('Code Injection') + paths: + include: + - '*.py' + - '*.js' + - '*.java' + - '*.c' + - '*.cpp' + - '*.cs' + - '*.go' + - '*.rs' + - '*.php' + - '*.rb' + - '*.scala' + - '*.ts' + - '*.kt' + - '*.m' + - '*.swift' + pattern-regex: '[\x{202A}-\x{202E}\x{2066}-\x{2069}\x{200E}\x{200F}\x{061C}]' severity: WARNING - - id: python.lang.security.audit.md5-used-as-password.md5-used-as-password + - id: java_deserialization_rule-InsecureDeserialization languages: - - python - message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as scrypt. You can use `hashlib.scrypt`. + - java + message: | + Deserialization attacks exploit the process of reading serialized data and turning it back into an + object. By constructing malicious objects and serializing them, an adversary may attempt to: + + - Inject code that is executed upon object construction, which occurs during the deserialization process. + - Exploit mass assignment by including fields that are not normally a part of the serialized data but are + read in during deserialization. + + Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows + the application to specify exactly which object types are allowed to be deserialized. Additionally, when + deserializing, never deserialize to base object types like `Object` and only cast to the exact object + type that is expected. + + To protect against mass assignment, only allow deserialization of the specific fields that are required. + If this is not easily done, consider creating an intermediary type that can be serialized with only the + necessary fields exposed. + + For more details on deserialization attacks in general, see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW - likelihood: HIGH + cwe: CWE-502 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://tools.ietf.org/html/rfc6151 - - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords - - https://github.com/returntocorp/semgrep-rules/issues/1609 - - https://docs.python.org/3/library/hashlib.html#hashlib.scrypt - subcategory: - - vuln + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: Medium + shortDescription: Deserialization of Untrusted Data technology: - - pycryptodome - - hashlib - - md5 + - java mode: taint + pattern-propagators: + - from: $X + pattern: $V = new ObjectInputStream($X) + to: $V pattern-sinks: + - pattern: $V.readObject(...) + pattern-sources: - patterns: - - pattern: $FUNCTION(...) - - metavariable-regex: - metavariable: $FUNCTION - regex: (?i)(.*password.*) + - pattern-inside: "$FUNC (..., byte[] $X, ...) { \n ... \n}\n" + - focus-metavariable: $X + severity: WARNING + - id: javascript_crypto_rule-NodeLibcurlSSLVerificationDisable + languages: + - javascript + message: "The application was identified disabling the `SSL_VERIFYPEER` and/or the \n`SSL_VERIFYHOST` options of the node-libcurl library. These options control \nthe verification process of SSL/TLS certificates and hostnames. \n\n- SSL_VERIFYPEER: This option, when enabled, ensures that the SSL certificate \npresented by the server is valid and trusted by a Certificate Authority (CA) \nthat the client also trusts. This is crucial for verifying that the server with \nwhich the client is connecting is authenticated and its certificate is not forged.\n- SSL_VERIFYHOST: This option, when enabled, makes sure that the certificate's \ncommon name (CN) or one of its subject alternative names (SANs) matches the \nhost name in the URL being connected . This is essential for ensuring that \nthe client is communicating with the correct server and not another server \npresenting a valid certificate.\n\nDisabling these options compromises the security of SSL/TLS connections. It \nexposes the application to MITM attacks, where an attacker could intercept, \nread, or modify the data sent and received over what is assumed to be a secure \nconnection.\n\nMitigation Strategy:\nTo mitigate this vulnerability and ensure secure communication, enable SSL/TLS \ncertificate and hostname verification by setting `SSL_VERIFYPEER` to `1` or \n`true` and `SSL_VERIFYHOST` to `2`. These options are enabled by default as \nwell. This configuration ensures that the server's SSL certificate is validated \nagainst trusted CAs and that the hostname in the certificate matches the hostname \nthe client intends to communicate with.\n\nSecure Code Example:\n```\nconst { Curl } = require('node-libcurl')\nconst curl = new Curl()\ncurl.setOpt('SSL_VERIFYPEER', 1)\ncurl.setOpt('SSL_VERIFYHOST', 2)\ncurl.setOpt('URL', 'https://yourserver.com:443')\n```\n" + metadata: + category: security + cwe: CWE-599 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Missing validation of OpenSSL certificate + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + $X.setOpt($SSL, 0) + - pattern: | + $X.setOpt($SSL, false) + - metavariable-pattern: + metavariable: $SSL + pattern-either: + - pattern: | + "SSL_VERIFYHOST" + - pattern: | + "SSL_VERIFYPEER" + - pattern: | + $Y.option.SSL_VERIFYHOST + - pattern: | + $Y.option.SSL_VERIFYPEER pattern-sources: - patterns: - pattern-either: - - pattern: hashlib.md5 - - pattern: hashlib.new(..., name="MD5", ...) - - pattern: Cryptodome.Hash.MD5 - - pattern: Crypto.Hash.MD5 - - pattern: cryptography.hazmat.primitives.hashes.MD5 + - pattern-inside: | + $Y = require('node-libcurl') + ... + - pattern-inside: | + import { $Y } from 'node-libcurl' + ... + - pattern-inside: | + import { $K as $Y } from 'node-libcurl' + ... + - pattern: | + $X = new $Y() severity: WARNING - - id: python.lang.security.audit.network.bind.avoid-bind-to-all-interfaces + - id: python_exec_rule-start-process-partial-path languages: - python - message: Running `socket.bind` to 0.0.0.0, or empty string could unexpectedly expose the server publicly as it binds to all available interfaces. Consider instead getting correct address from an environment variable or configuration file. + message: | + Starting a process with a partial executable path metadata: category: security - confidence: HIGH - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-78 owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - python - pattern-either: - - pattern: | - $S = socket.socket(...) - ... - $S.bind(("0.0.0.0", ...)) - - pattern: | - $S = socket.socket(...) - ... - $S.bind(("::", ...)) - - pattern: | - $S = socket.socket(...) - ... - $S.bind(("", ...)) + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') + patterns: + - pattern-either: + - patterns: + - pattern: os.popen(...) + - pattern-not: os.popen("...", ...) + - patterns: + - pattern: os.system(...) + - pattern-not: os.system("...", ...) + - patterns: + - pattern: os.popen2(...) + - pattern-not: os.popen2("...", ...) + - patterns: + - pattern: os.popen3(...) + - pattern-not: os.popen3("...", ...) + - patterns: + - pattern: os.popen4(...) + - pattern-not: os.popen4("...", ...) + - patterns: + - pattern: popen2.popen2(...) + - pattern-not: popen2.popen2("...", ...) + - patterns: + - pattern: popen2.popen3(...) + - pattern-not: popen2.popen3("...", ...) + - patterns: + - pattern: popen2.popen4(...) + - pattern-not: popen2.popen4("...", ...) + - patterns: + - pattern: popen2.Popen3(...) + - pattern-not: popen2.Popen3("...", ...) + - patterns: + - pattern: popen2.Popen4(...) + - pattern-not: popen2.Popen4("...", ...) + - patterns: + - pattern: commands.getoutput(...) + - pattern-not: commands.getoutput("...", ...) + - patterns: + - pattern: commands.getstatusoutput(...) + - pattern-not: commands.getstatusoutput("...", ...) severity: INFO - - id: python.lang.security.audit.network.disabled-cert-validation.disabled-cert-validation + - id: python_exec_rule-start-process-path languages: - python - message: certificate verification explicitly disabled, insecure connections possible + message: | + Starting a process with a partial executable path metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: HIGH + cwe: CWE-78 owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - subcategory: - - vuln - technology: - - python + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') patterns: - pattern-either: - - pattern: urllib3.PoolManager(..., cert_reqs=$REQS, ...) - - pattern: urllib3.ProxyManager(..., cert_reqs=$REQS, ...) - - pattern: urllib3.HTTPSConnectionPool(..., cert_reqs=$REQS, ...) - - pattern: urllib3.connectionpool.HTTPSConnectionPool(..., cert_reqs=$REQS, ...) - - pattern: urllib3.connection_from_url(..., cert_reqs=$REQS, ...) - - pattern: urllib3.proxy_from_url(..., cert_reqs=$REQS, ...) - - pattern: $CONTEXT.wrap_socket(..., cert_reqs=$REQS, ...) - - pattern: ssl.wrap_socket(..., cert_reqs=$REQS, ...) + - pattern: subprocess.Popen($BIN, shell=False) + - pattern: subprocess.Popen([$BIN, ...], shell=False) + - pattern: os.system($BIN, shell=False) + - pattern: os.system([$BIN, ...], shell=False) + - pattern: popen2.Popen3($BIN, shell=False) + - pattern: popen2.Popen3([$BIN, ...], shell=False) + - pattern: popen2.Popen4($BIN, shell=False) + - pattern: popen2.Popen4([$BIN, ...], shell=False) + - pattern: commands.getoutput($BIN, shell=False) + - pattern: commands.getoutput([$BIN, ...], shell=False) + - pattern: commands.getstatusoutput($BIN, shell=False) + - pattern: commands.getstatusoutput([$BIN, ...], shell=False) - metavariable-regex: - metavariable: $REQS - regex: (NONE|CERT_NONE|CERT_OPTIONAL|ssl\.CERT_NONE|ssl\.CERT_OPTIONAL|\'NONE\'|\"NONE\"|\'OPTIONAL\'|\"OPTIONAL\") + metavariable: $BIN + regex: ^['"][^/\.][^:].*['"] severity: ERROR - - id: python.lang.security.audit.network.http-not-https-connection.http-not-https-connection + - id: python_exec_rule-subprocess-call-array languages: - python - message: Detected HTTPConnectionPool. This will transmit data in cleartext. It is recommended to use HTTPSConnectionPool instead for to encrypt communications. + message: | + subprocess call - check for execution of untrusted input metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-78 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://urllib3.readthedocs.io/en/1.2.1/pools.html#urllib3.connectionpool.HTTPSConnectionPool - subcategory: - - audit + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') + patterns: + - pattern: | + subprocess.$FUNC([..., $ARG, ...]) + - metavariable-pattern: + metavariable: $ARG + patterns: + - pattern-not: | + "..." + - pattern-not: | + '...' + severity: WARNING + - id: scala_unsafe_rule-InformationExposureVariant2 + languages: + - scala + message: | + The sensitive information may be valuable information on its own (such as a password), or it + may be useful for launching other, more deadly attacks. If an attack fails, an attacker may use + error information provided by the server to launch another more focused attack. For example, an + attempt to exploit a path traversal weakness (CWE-22) might yield the full pathname of the + installed application. + metadata: + category: security + cwe: CWE-209 + security-severity: Info + shortDescription: Information Exposure Through an Error Message technology: - - python - pattern-either: - - pattern: urllib3.HTTPConnectionPool(...) - - pattern: urllib3.connectionpool.HTTPConnectionPool(...) - severity: ERROR - - id: python.lang.security.audit.ssl-wrap-socket-is-deprecated.ssl-wrap-socket-is-deprecated + - scala + patterns: + - pattern-either: + - pattern: $E.printStackTrace + - patterns: + - pattern: $E.printStackTrace($OUT) + - metavariable-pattern: + metavariable: $OUT + pattern-either: + - pattern: '($PS: java.io.PrintStream)' + - pattern: '($PW: java.io.PrintWriter)' + - pattern: java.lang.System.out + - pattern: '($O: java.io.OutputStream)' + - pattern: '($SOS: javax.servlet.ServletOutputStream)' + severity: WARNING + - id: java_cookie_rule-CookieHTTPOnly languages: - - python - message: '''ssl.wrap_socket()'' is deprecated. This function creates an insecure socket without server name indication or hostname matching. Instead, create an SSL context using ''ssl.SSLContext()'' and use that to wrap a socket.' + - java + message: | + The `HttpOnly` attribute when set to `true` protects the cookie value from being accessed by + client side JavaScript such + as reading the `document.cookie` values. By enabling this protection, a website that is + vulnerable to + Cross-Site Scripting (XSS) will be able to block malicious scripts from accessing the cookie + value from JavaScript. + + Example of protecting a `Cookie`: + ``` + // Create an HttpOnly cookie. + Cookie someCookie = new Cookie("SomeCookieName", "SomeValue"); + // Set HttpOnly flag to true + someCookie.setHttpOnly(true); + ``` + + For more information see: + https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/http/cookie#setHttpOnly-boolean- + + Session cookies should be configured with the following security directives: + + - [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) + - [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) + - [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-1004 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/ssl.html#ssl.wrap_socket - - https://docs.python.org/3/library/ssl.html#ssl.SSLContext.wrap_socket - subcategory: - - vuln + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: Low + shortDescription: Sensitive cookie without 'HttpOnly' flag technology: - - python - pattern: ssl.wrap_socket(...) + - java + patterns: + - pattern-either: + - pattern: ($X.servlet.http.Cookie $COOKIE).setHttpOnly(false); + - patterns: + - pattern-not-inside: ($X.servlet.http.Cookie $COOKIE).setHttpOnly(...); ... + - pattern: $RESPONSE.addCookie($COOKIE); severity: WARNING - - fix-regex: - regex: (shell\s*=\s*)True - replacement: \1False - id: python.lang.security.audit.subprocess-shell-true.subprocess-shell-true + - id: java_crypto_rule-DisallowOldTLSVersion languages: - - python - message: Found 'subprocess' function '$FUNC' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead. + - java + message: "This application sets the `jdk.tls.client.protocols` system property to\ninclude insecure TLS or SSL versions (SSLv3, TLSv1, TLSv1.1), which are\ndeprecated due to serious security vulnerabilities like POODLE attacks and\nsusceptibility to man-in-the-middle attacks. Continuing to use these\nprotocols can expose data to interception or manipulation. \n\nTo mitigate the issue, upgrade to TLSv1.2 or higher, which provide stronger \nencryption and improved security. Refrain from using any SSL versions as they \nare entirely deprecated.\n\nSecure Code Example:\n```\npublic void safe() {\n java.lang.System.setProperty(\"jdk.tls.client.protocols\", \"TLSv1.3\");\n}\n```\n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: HIGH + cwe: CWE-326 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess - - https://docs.python.org/3/library/subprocess.html - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html + - https://stackoverflow.com/questions/26504653/is-it-possible-to-disable-sslv3-for-all-java-applications + security-severity: MEDIUM + shortDescription: Inadequate encryption strength subcategory: - vuln technology: - - python + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information patterns: - - pattern: subprocess.$FUNC(..., shell=True, ...) - - pattern-not: subprocess.$FUNC("...", shell=True, ...) - severity: ERROR - - id: python.lang.security.audit.weak-ssl-version.weak-ssl-version + - pattern: $VALUE. ... .setProperty("jdk.tls.client.protocols", "$PATTERNS"); + - metavariable-pattern: + language: generic + metavariable: $PATTERNS + patterns: + - pattern-either: + - pattern-regex: ^(.*TLSv1|.*SSLv.*)$ + - pattern-regex: ^(.*TLSv1,.*|.*TLSv1.1.*) + severity: WARNING + - id: java_crypto_rule-GCMNonceReuse languages: - - python - message: An insecure SSL version was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use 'ssl.PROTOCOL_TLSv1_2' or higher. + - java + message: "GCM is a mode of operation for symmetric-key cryptographic block ciphers. GCM allows the usage of\nan initialization vector or nonce used to provide the initial state. The IV is an arbitrary number \nthat can be used just once in a cryptographic communication. Re use of initialization vectors \nnullifies their usage, as the initial state of all GCMs with the same vector will effectively be\nthe same.\n\nInstead of hard coding an initialization vector, it is recommended to use nextBytes() method from\njava.security.SecureRandom. This generates a user specified number of random bytes.\n\nExample using `java.security.SecureRandom`:\n```\nCipher cipher = Cipher.getInstance(\"AES/GCM/NoPadding\");\nSecretKeySpec keySpec = new SecretKeySpec(secretKey.getEncoded(), \"AES\");\n\n// Generate a new, random IV for each encryption operation\nSecureRandom secureRandom = new SecureRandom();\n// GCM standard recommends a 12-byte (96-bit) IV\nbyte[] iv = new byte[12];\nsecureRandom.nextBytes(iv);\n\nGCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);\ncipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);\n```\n\nFor more information on Java Cryptography see:\nhttps://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html\n" metadata: - asvs: - control_id: 9.1.3 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v91-client-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-323 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://tools.ietf.org/html/rfc7568 - - https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html - - https://docs.python.org/3/library/ssl.html#ssl.PROTOCOL_TLSv1_2 - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/insecure_ssl_tls.py#L30 - subcategory: - - audit + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Reuse of cryptographic initialization vector technology: - - python - pattern-either: - - pattern: ssl.PROTOCOL_SSLv2 - - pattern: ssl.PROTOCOL_SSLv3 - - pattern: ssl.PROTOCOL_TLSv1 - - pattern: ssl.PROTOCOL_TLSv1_1 - - pattern: pyOpenSSL.SSL.SSLv2_METHOD - - pattern: pyOpenSSL.SSL.SSLv23_METHOD - - pattern: pyOpenSSL.SSL.SSLv3_METHOD - - pattern: pyOpenSSL.SSL.TLSv1_METHOD - - pattern: pyOpenSSL.SSL.TLSv1_1_METHOD + - java + mode: taint + pattern-sinks: + - pattern: new GCMParameterSpec(...,$NONCE, ...) + pattern-sources: + - pattern-either: + - pattern: new byte[]{...}; + - pattern: $STRING.getBytes(); severity: WARNING - - id: python.lang.security.dangerous-code-run.dangerous-interactive-code-run + - id: java_crypto_rule-HTTPUrlConnectionHTTPRequest languages: - - python - message: Found user controlled data inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. + - java + message: "Detected an HTTP request sent via HttpURLConnection or URLConnection.\nThis could lead to sensitive information being sent over an insecure \nchannel, as HTTP does not encrypt data. Transmitting data over HTTP \nexposes it to potential interception by attackers, risking data \nintegrity and confidentiality. Using HTTP for transmitting sensitive \ndata such as passwords, personal information, or financial details can \nlead to information disclosure.\n\nTo mitigate the issue, switch to HTTPS to ensure all data transmitted \nis securely encrypted. This helps protect against eavesdropping and \nman-in-the-middle attacks. Modify the URL in your code from HTTP to \nHTTPS and ensure the server supports HTTPS.\n\nSecure Code Example:\n```\nprivate static void safe() {\n try {\n URL url = new URL(\"https://example.com/api/data\"); // Changed to HTTPS\n HttpURLConnection con = (HttpURLConnection) url.openConnection();\n con.setRequestMethod(\"GET\");\n\n int status = con.getResponseCode();\n if (status == HttpURLConnection.HTTP_OK) { \n BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n String inputLine;\n StringBuilder response = new StringBuilder();\n while ((inputLine = in.readLine()) != null) {\n response.append(inputLine);\n }\n in.close();\n System.out.println(\"Response: \" + response.toString());\n } else {\n System.out.println(\"HTTP error code: \" + status);\n }\n con.disconnect();\n } catch (Exception e) {\n e.printStackTrace();\n }\n}\n```\n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: MEDIUM owasp: - - A03:2021 - Injection + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - vuln technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $X = code.InteractiveConsole(...) - ... - - pattern-inside: | - $X = code.InteractiveInterpreter(...) - ... - - pattern-either: - - pattern: | - $X.push($PAYLOAD,...) - - pattern: | - $X.runsource($PAYLOAD,...) - - pattern: | - $X.runcode(code.compile_command($PAYLOAD),...) - - pattern: | - $PL = code.compile_command($PAYLOAD,...) - ... - $X.runcode($PL,...) - - focus-metavariable: $PAYLOAD - - pattern-not: | - $X.push("...",...) - - pattern-not: | - $X.runsource("...",...) - - pattern-not: | - $X.runcode(code.compile_command("..."),...) - - pattern-not: | - $PL = code.compile_command("...",...) + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information + patterns: + - pattern: | + "=~/[Hh][Tt][Tt][Pp]://.*/" + - pattern-either: + - pattern-inside: | + URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); ... - $X.runcode($PL,...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession + $CON = (HttpURLConnection) $URL.openConnection(...); + ... + $CON.$FUNC(...); + - pattern-inside: | + URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); + ... + $CON = $URL.openConnection(...); + ... + $CON.$FUNC(...); severity: WARNING - - id: python.lang.security.dangerous-os-exec.dangerous-os-exec + - id: java_crypto_rule-HttpComponentsRequest languages: - - python - message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. + - java + message: "Detected an HTTP GET request sent via Apache HTTP Components. Sending data\nover HTTP can expose sensitive information to interception or modification\nby attackers, as HTTP does not encrypt the data transmitted. It is critical\nto use HTTPS, which encrypts the communication, to protect the confidentiality\nand integrity of data in transit.\n\nTo mitigate the issue, ensure all data transmitted between the client and \nserver is sent over HTTPS. Update all HTTP URLs to HTTPS and configure your \nserver to redirect HTTP requests to HTTPS. Additionally, implement HSTS \n(HTTP Strict Transport Security) to enforce secure connections.\nSecure Code Example:\n```\nprivate static void safe() {\n CloseableHttpClient httpclient = HttpClients.createDefault();\n CloseableHttpResponse response = httpclient.execute(new HttpPost(\"https://example.com\"));\n}\n```\n" metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true + cwe: CWE-319 impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: MEDIUM owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + - https://hc.apache.org/httpcomponents-client-ga/quickstart.html + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - vuln technology: - - python + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information mode: taint - options: - symbolic_propagation: true pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-not: os.$METHOD("...", ...) - - pattern: os.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (execl|execle|execlp|execlpe|execv|execve|execvp|execvpe) - - patterns: - - pattern-not: os.$METHOD("...", [$PATH,"...","...",...],...) - - pattern-inside: os.$METHOD($BASH,[$PATH,"-c",$CMD,...],...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (execv|execve|execvp|execvpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-not: os.$METHOD("...", $PATH, "...", "...",...) - - pattern-inside: os.$METHOD($BASH, $PATH, "-c", $CMD,...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (execl|execle|execlp|execlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - pattern: (org.apache.http.impl.client.CloseableHttpClient $A).execute($HTTPREQ); pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - severity: ERROR - - id: python.lang.security.dangerous-spawn-process.dangerous-spawn-process + - pattern: | + "=~/^http://.+/i" + severity: WARNING + - id: java_crypto_rule-HttpGetHTTPRequest languages: - - python - message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. + - java + message: "Detected an HTTP GET request sent via HttpGet. Sending data over HTTP can\nexpose sensitive information to interception or modification by attackers,\nas HTTP does not encrypt the data transmitted. It is critical to use\nHTTPS, which encrypts the communication, to protect the confidentiality\nand integrity of data in transit.\n\nTo mitigate the issue, ensure all data transmitted between the client and \nserver is sent over HTTPS. Update all HTTP URLs to HTTPS and configure your \nserver to redirect HTTP requests to HTTPS. Additionally, implement HSTS \n(HTTP Strict Transport Security) to enforce secure connections.\n\nSecure Code Example:\n```\nprivate static void safe() throws IOException {\n HttpGet httpGet = new HttpGet(\"https://example.com\");\n HttpClients.createDefault().execute(httpGet);\n}\n```\n" metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true + cwe: CWE-319 impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: MEDIUM owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - vuln technology: - - python + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information mode: taint - options: - symbolic_propagation: true pattern-sinks: - patterns: - - pattern-either: - - patterns: - - pattern-not: os.$METHOD($MODE, "...", ...) - - pattern-inside: os.$METHOD($MODE, $CMD, ...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) - - patterns: - - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...) - - pattern-inside: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...) - - pattern-inside: os.$METHOD($MODE, $BASH, "-c", $CMD,...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - pattern: | + $R = new org.apache.http.client.methods.HttpGet($PROT); + ... + $CLIENT. ... .execute($R, ...); + - focus-metavariable: $PROT pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - - patterns: - - pattern-either: - - pattern: os.environ['$ANYTHING'] - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb['$ANYTHING'] - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv[...] - - pattern: sys.orig_argv[...] - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.dangerous-subinterpreters-run-string.dangerous-subinterpreters-run-string + - pattern: | + "=~/^http:\/\/.+/i" + severity: WARNING + - id: java_crypto_rule_JwtDecodeWithoutVerify languages: - - python - message: Found user controlled content in `run_string`. This is dangerous because it allows a malicious actor to run arbitrary Python code. + - java + message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + cwe: CWE-347 impact: HIGH - likelihood: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW owasp: - - A03:2021 - Injection - references: - - https://bugs.python.org/issue43472 - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern: | - _xxsubinterpreters.run_string($ID, $PAYLOAD, ...) - - pattern-not: | - _xxsubinterpreters.run_string($ID, "...", ...) - - focus-metavariable: $PAYLOAD - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + references: https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + security-severity: MEDIUM + shortDescription: Improper verification of cryptographic signature + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: vuln + technology: jwt + vulnerability_class: Improper Authentication + patterns: + - pattern: | + com.auth0.jwt.JWT.decode(...); + - pattern-not-inside: |- + class $CLASS { + ... + $RETURNTYPE $FUNC (...) { + ... + $VERIFIER.verify(...); + ... + } + } severity: WARNING - - id: python.lang.security.dangerous-subprocess-use.dangerous-subprocess-use + - id: java_crypto_rule_JwtNoneAlgorithm languages: - - python - message: Detected subprocess function '$FUNC' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.escape()'. + - java + message: | + Detected use of the 'none' algorithm in a JWT token. The 'none' + algorithm assumes the integrity of the token has already been verified. + This would allow a malicious actor to forge a JWT token that will + automatically be verified. Do not explicitly use the 'none' algorithm. + Instead, use an algorithm such as 'HS256'. + + For more information on how to securely use JWT please see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html metadata: asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + control_id: 3.5.3 Insecue Stateless Session Tokens + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + confidence: LOW + cwe: CWE-327 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess - - https://docs.python.org/3/library/subprocess.html - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + security-severity: CRITICAL + shortDescription: Use of a broken or risky cryptographic algorithm + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ subcategory: - - vuln + - audit technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-not: subprocess.$FUNC("...", ...) - - pattern-not: subprocess.$FUNC(["...",...], ...) - - pattern-not: subprocess.$FUNC(("...",...), ...) - - pattern-not: subprocess.CalledProcessError(...) - - pattern-not: subprocess.SubprocessError(...) - - pattern: subprocess.$FUNC($CMD, ...) - - patterns: - - pattern-not: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...) - - pattern: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD) - - patterns: - - pattern-not: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...],...) - - pattern-not: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...),...) - - pattern-either: - - pattern: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD], ...) - - pattern: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD), ...) - - patterns: - - pattern-not: subprocess.$FUNC("=~/(python)/","...",...) - - pattern: subprocess.$FUNC("=~/(python)/", $CMD) - - patterns: - - pattern-not: subprocess.$FUNC(["=~/(python)/","...",...],...) - - pattern-not: subprocess.$FUNC(("=~/(python)/","...",...),...) - - pattern-either: - - pattern: subprocess.$FUNC(["=~/(python)/", $CMD],...) - - pattern: subprocess.$FUNC(("=~/(python)/", $CMD),...) - - focus-metavariable: $CMD - pattern-sources: + - jwt + vulnerability_class: + - Cryptographic Issues + pattern-either: - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession + - pattern: | + io.jsonwebtoken.Jwts.builder() + - pattern-not-inside: | + $RETURNTYPE $FUNC(...) { + ... + $JWTS.signWith(...); + ... + } + - pattern: | + $J.sign(com.auth0.jwt.algorithms.Algorithm.none()) + - pattern: | + new com.nimbusds.jose.PlainHeader(...); + - pattern: | + new com.nimbusds.jose.PlainHeader.Builder(). ... .build(); severity: ERROR - - id: python.lang.security.dangerous-system-call.dangerous-system-call + - id: java_crypto_rule-SocketRequestUnsafeProtocols languages: - - python - message: Found user-controlled data used in a system call. This could allow a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. + - java + message: | + This code establishes a network connection using an insecure protocol + (HTTP, FTP, or Telnet). These protocols transmit data in cleartext, which + can be intercepted and read by malicious actors. This exposure of + sensitive information violates security best practices and can lead to + data breaches. + + To mitigate the vulnerability, consider using secure protocols that encrypt + the transmission of data. For web traffic, replace HTTP with HTTPS, which + uses SSL/TLS to protect the data in transit. For file transfers, use SFTP + or FTPS instead of FTP. For remote terminal access, use SSH instead of Telnet. + + Secure Code Example: + ``` + public void safe() { + BufferedReader in = null; + PrintWriter out = null; + Socket pingSocket = null; + try{ + pingSocket = new Socket("ssh://example.com", 22); + out = new PrintWriter(pingSocket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(pingSocket.getInputStream())); + out.println("ping"); + System.out.println(in.readLine()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (in != null) in.close(); + if (pingSocket != null) pingSocket.close(); + } catch (IOException e) { + System.out.println("Failed to close resources: " + e.getMessage()); + } + } + } + ``` metadata: - asvs: - control_id: 5.2.4 Dyanmic Code Execution Features - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: HIGH + confidence: LOW + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html - subcategory: - - vuln + - https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-not: os.$W("...", ...) - - pattern-either: - - pattern: os.system(...) - - pattern: getattr(os, "system")(...) - - pattern: __import__("os").system(...) - - pattern: getattr(__import__("os"), "system")(...) - - pattern: | - $X = __import__("os") - ... - $X.system(...) - - pattern: | - $X = __import__("os") - ... - getattr($X, "system")(...) - - pattern: | - $X = getattr(os, "system") - ... - $X(...) - - pattern: | - $X = __import__("os") - ... - $Y = getattr($X, "system") - ... - $Y(...) - - pattern: os.popen(...) - - pattern: os.popen2(...) - - pattern: os.popen3(...) - - pattern: os.popen4(...) - pattern-sources: + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information + pattern-either: + - pattern: | + $SOCKET = new java.net.Socket("=~/^ftp://.+/i", ...); + - pattern: | + $SOCKET = new java.net.Socket("=~/^http://.+/i", ...); + - pattern: | + $SOCKET = new java.net.Socket("=~/^telnet://.+/i", ...); - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - severity: ERROR - - id: python.lang.security.dangerous-testcapi-run-in-subinterp.dangerous-testcapi-run-in-subinterp + - pattern: | + $SOCKET = new java.net.Socket("...", $PORT); + - metavariable-comparison: + comparison: $PORT in [23,21,80] + metavariable: $PORT + severity: WARNING + - id: java_crypto_rule-SpringFTPRequest languages: - - python - message: Found user controlled content in `run_in_subinterp`. This is dangerous because it allows a malicious actor to run arbitrary Python code. + - java + message: "This pattern detects configurations where the Spring Integration FTP plugin \nis used to set up connections to FTP servers. FTP is an insecure protocol \nthat transmits data, including potentially sensitive information, in plaintext. \nThis can expose personal identifiable information (PII) or other sensitive data \nto interception by attackers during transmission. \n\nTo mitigate the vulnerability, switch to a secure protocol such as SFTP or FTPS \nthat encrypts the connection to prevent data exposure. Ensure that any method \nused to set the host for an FTP session does not use plaintext FTP. \n\nSecure Code Example:\n```\npublic SessionFactory safe(FtpSessionFactoryProperties properties) {\n DefaultFtpSessionFactory ftpSessionFactory = new DefaultFtpSessionFactory();\n ftpSessionFactory.setHost(\"sftp://example.com\");\n ftpSessionFactory.setPort(properties.getPort());\n ftpSessionFactory.setUsername(properties.getUsername());\n ftpSessionFactory.setPassword(properties.getPassword());\n ftpSessionFactory.setClientMode(properties.getClientMode().getMode());\n return ftpSessionFactory;\n}\n```\n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: HIGH + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A03:2021 - Injection + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + - https://docs.spring.io/spring-integration/api/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.html#setClientMode-int- + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - vuln technology: - - python + - spring + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information mode: taint - options: - symbolic_propagation: true pattern-sinks: - patterns: - - pattern-either: - - pattern: | - _testcapi.run_in_subinterp($PAYLOAD, ...) - - pattern: | - test.support.run_in_subinterp($PAYLOAD, ...) - - focus-metavariable: $PAYLOAD - - pattern-not: | - _testcapi.run_in_subinterp("...", ...) - - pattern-not: | - test.support.run_in_subinterp("...", ...) + - pattern: | + (org.springframework.integration.ftp.session.DefaultFtpSessionFactory + $SF).setHost($URL); + - focus-metavariable: $URL pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession + - pattern: | + "=~/^ftp://.+/i" severity: WARNING - - fix-regex: - count: 1 - regex: unsafe_load - replacement: safe_load - id: python.lang.security.deserialization.avoid-pyyaml-load.avoid-pyyaml-load + - id: java_crypto_rule-SpringHTTPRequestRestTemplate languages: - - python - message: Detected a possible YAML deserialization vulnerability. `yaml.unsafe_load`, `yaml.Loader`, `yaml.CLoader`, and `yaml.UnsafeLoader` are all known to be unsafe methods of deserializing YAML. An attacker with control over the YAML input could create special YAML input that allows the attacker to run arbitrary Python code. This would allow the attacker to steal files, download and install malware, or otherwise take over the machine. Use `yaml.safe_load` or `yaml.SafeLoader` instead. + - java + message: "This rule detects instances where Java Spring's RestTemplate API sends \nrequests to non-secure (http://) URLs. Sending data over HTTP is vulnerable \nas it does not use TLS encryption, exposing the data to interception, \nmodification, or redirection by attackers. \n\nTo mitigate this vulnerability, modify the request URLs to use HTTPS instead, \nwhich ensures that the data is encrypted during transit and prevents from\nMITM attacks. \n\nSecure Code Example:\n```\npublic void safe(Object obj) throws Exception {\n RestTemplate restTemplate = new RestTemplate();\n restTemplate.put(URI.create(\"https://example.com\"), obj);\n}\n``` \n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true + cwe: CWE-319 impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation - - https://nvd.nist.gov/vuln/detail/CVE-2017-18342 + - https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#delete-java.lang.String-java.util.Map- + - https://www.baeldung.com/rest-template + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - - audit + - vuln technology: - - pyyaml - patterns: - - pattern-inside: | - import yaml - ... - - pattern-not-inside: | - $YAML = ruamel.yaml.YAML(...) - ... - - pattern-either: - - pattern: yaml.unsafe_load(...) - - pattern: yaml.load(..., Loader=yaml.Loader, ...) - - pattern: yaml.load(..., Loader=yaml.UnsafeLoader, ...) - - pattern: yaml.load(..., Loader=yaml.CLoader, ...) - - pattern: yaml.load_all(..., Loader=yaml.Loader, ...) - - pattern: yaml.load_all(..., Loader=yaml.UnsafeLoader, ...) - - pattern: yaml.load_all(..., Loader=yaml.CLoader, ...) - severity: ERROR - - id: python.lang.security.deserialization.avoid-unsafe-ruamel.avoid-unsafe-ruamel + - spring + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information + mode: taint + pattern-sinks: + - patterns: + - pattern: | + (org.springframework.web.client.RestTemplate $RESTTEMP).$FUNC($URL, ...); + - focus-metavariable: $URL + - metavariable-regex: + metavariable: $FUNC + regex: (delete|doExecute|exchange|getForEntity|getForObject|headForHeaders|optionsForAllow|patchForObject|postForEntity|postForLocation|postForObject|put|execute) + pattern-sources: + - pattern: | + "=~/^http:\/\/.+/i" + severity: WARNING + - id: java_crypto_rule-TLSUnsafeRenegotiation languages: - - python - message: Avoid using unsafe `ruamel.yaml.YAML()`. `ruamel.yaml.YAML` can create arbitrary Python objects. A malicious actor could exploit this to run arbitrary code. Use `YAML(typ='rt')` or `YAML(typ='safe')` instead. + - java + message: "This code enables unsafe renegotiation in SSL/TLS connections, which is\nvulnerable to man-in-the-middle attacks. In such attacks, an attacker\ncould inject chosen plaintext at the beginning of the secure\ncommunication, potentially compromising the security of data transmission. If \nexploited, this vulnerability can lead to unauthorized access to sensitive \ndata, data manipulation, and potentially full system compromise depending on \nthe data and operations protected by the TLS session.\n\nTo mitigate this vulnerability, disable unsafe renegotiation in the Java \napplication. Ensure that only secure renegotiation is allowed by setting the \nsystem property `sun.security.ssl.allowUnsafeRenegotiation` to `false`. \n\nSecure code example:\n```\npublic void safe() {\n java.lang.System.setProperty(\"sun.security.ssl.allowUnsafeRenegotiation\", false);\n}\n```\n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true + cwe: CWE-319 impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://yaml.readthedocs.io/en/latest/basicuse.html?highlight=typ + - https://www.oracle.com/java/technologies/javase/tlsreadme.html + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - - audit + - vuln technology: - - ruamel.yaml - pattern-either: - - pattern: ruamel.yaml.YAML(..., typ='unsafe', ...) - - pattern: ruamel.yaml.YAML(..., typ='base', ...) - severity: ERROR - - id: python.lang.security.deserialization.pickle.avoid-shelve + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information + patterns: + - pattern: | + java.lang.System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", $TRUE); + - metavariable-pattern: + metavariable: $TRUE + pattern-either: + - pattern: | + true + - pattern: | + "true" + - pattern: | + Boolean.TRUE + severity: WARNING + - id: java_crypto_rule-TelnetRequest languages: - - python - message: Avoid using `shelve`, which uses `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. + - java + message: "Checks for attempts to connect through telnet. Telnet is an outdated\nprotocol that transmits all data, including sensitive information like\npasswords, in clear text. This exposes it to interception and\neavesdropping on unsecured networks.\n\nTo mitigate this issue, replace Telnet usage with more secure protocols \nsuch as SSH (Secure Shell), which provides encrypted communication. Use \nthe SSH functionality provided by libraries like JSch or Apache MINA SSHD \nfor secure data transmission.\n\nSecure Code Example:\n```\nimport com.jcraft.jsch.JSch;\nimport com.jcraft.jsch.Session;\n\npublic class SecureConnector {\n public static void main(String[] args) {\n try {\n JSch jsch = new JSch();\n Session session = jsch.getSession(\"username\", \"hostname\", 22);\n session.setPassword(\"password\");\n session.setConfig(\"StrictHostKeyChecking\", \"no\");\n session.connect();\n System.out.println(\"Connected securely.\");\n } catch (Exception e) {\n System.err.println(\"Secure connection failed: \" + e.getMessage());\n }\n }\n}\n```\n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true + cwe: CWE-319 impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://docs.python.org/3/library/pickle.html + - https://commons.apache.org/proper/commons-net/javadocs/api-3.6/org/apache/commons/net/telnet/TelnetClient.html + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - - audit + - vuln technology: - - python - pattern: shelve.$FUNC(...) + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information + pattern: | + (org.apache.commons.net.telnet.TelnetClient $TELNETCLIENT).connect(...); severity: WARNING - - id: python.lang.security.insecure-hash-algorithms-md5.insecure-hash-algorithm-md5 + - id: java_crypto_rule-UnirestHTTPRequest languages: - - python - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - java + message: "This application uses the Unirest library to send\nnetwork requests to URLs starting with 'http://'. Communicating over HTTP\nis considered insecure because it does not encrypt traffic with TLS\n(Transport Layer Security), exposing data to potential interception or\nmanipulation by attackers.\n\nTo mitigate the issue, modify the request URL to begin with 'https://' \ninstead of 'http://'. Using HTTPS ensures that the data is encrypted and \nsecure during transmission. Review all instances where HTTP is used and \nupdate them to use HTTPS to prevent security risks.\n\nSecure Code Example:\n```\nimport kong.unirest.core.Unirest;\n\npublic void safe() {\n Unirest.get(\"https://httpbin.org\")\n .queryString(\"fruit\", \"apple\")\n .queryString(\"droid\", \"R2D2\")\n .asString();\n}\n```\n" metadata: - asvs: - control_id: 6.2.2 Insecure Custom Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - bandit-code: B303 category: security confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + cwe: CWE-319 impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + - https://kong.github.io/unirest-java/#requests + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - vuln technology: - - python + - unirest + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information patterns: - - pattern: hashlib.md5(...) - - pattern-not: hashlib.md5(..., usedforsecurity=False, ...) + - pattern: | + Unirest.$METHOD("=~/[hH][tT][tT][pP]://.*/") severity: WARNING - - fix-regex: - regex: sha1 - replacement: sha256 - id: python.lang.security.insecure-hash-algorithms.insecure-hash-algorithm-sha1 + - id: java_crypto_rule-UseOfRC2 languages: - - python - message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - java + message: "Use of RC2, a deprecated cryptographic algorithm vulnerable to related-key\nattacks, was detected. Modern cryptographic standards recommend the\nadoption of algorithms that integrate message integrity to ensure the\nciphertext remains unaltered.\n\nTo mitigate the issue, use any of the below algorithms instead:\n1. `ChaCha20Poly1305` - Preferred for its simplicity and speed, suitable for \nenvironments where cryptographic acceleration is absent.\n2. `AES-256-GCM` - Highly recommended when hardware support is available, \ndespite being somewhat slower than `ChaCha20Poly1305`. It is crucial to avoid \nnonce reuse with AES-256-GCM to prevent security compromises.\n\nSecure code example using `ChaCha20Poly1305` in Java:\n```\npublic void encryptAndDecrypt() throws Exception {\n SecureRandom random = new SecureRandom();\n byte[] secretKey = new byte[32]; // 256-bit key\n byte[] nonce = new byte[12]; // 96-bit nonce\n random.nextBytes(secretKey);\n random.nextBytes(nonce);\n\n Cipher cipher = Cipher.getInstance(\"ChaCha20-Poly1305/None/NoPadding\");\n SecretKeySpec keySpec = new SecretKeySpec(secretKey, \"ChaCha20\");\n GCMParameterSpec spec = new GCMParameterSpec(128, nonce);\n\n cipher.init(Cipher.ENCRYPT_MODE, keySpec, spec);\n byte[] plaintext = \"Secret text\".getBytes(StandardCharsets.UTF_8);\n byte[] ciphertext = cipher.doFinal(plaintext);\n System.out.println(\"Encrypted: \" + Base64.getEncoder().encodeToString(ciphertext));\n\n cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);\n byte[] decrypted = cipher.doFinal(ciphertext);\n System.out.println(\"Decrypted: \" + new String(decrypted, StandardCharsets.UTF_8));\n}\n```\nFor more on Java Cryptography, refer:\nhttps://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html\n" metadata: - asvs: - control_id: 6.2.2 Insecure Custom Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - bandit-code: B303 category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + confidence: HIGH + cwe: CWE-327 impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + security-severity: MEDIUM + shortDescription: Use of a broken or risky cryptographic algorithm subcategory: - vuln technology: - - python - pattern: hashlib.sha1(...) + - java + pattern-either: + - pattern: | + javax.crypto.Cipher.getInstance("RC2") + - patterns: + - pattern-inside: | + class $CLS{ + ... + String $ALG = "RC2"; + ... + } + - pattern: | + javax.crypto.Cipher.getInstance($ALG); severity: WARNING - - id: python.lang.security.insecure-hash-function.insecure-hash-function + - id: java_crypto_rule-UseOfRC4 languages: - - python - message: Detected use of an insecure MD4 or MD5 hash function. These functions have known vulnerabilities and are considered deprecated. Consider using 'SHA256' or a similar function instead. + - java + message: "Use of RC4 was detected. RC4 is vulnerable to several types of attacks,\nincluding stream cipher attacks where attackers can recover plaintexts by\nanalyzing a large number of encrypted messages, and bit-flipping attacks\nthat can alter messages without knowing the encryption key.\n\nTo mitigate the issue, use any of the below algorithms instead:\n1. `ChaCha20Poly1305` - Preferred for its simplicity and speed, suitable for \nenvironments where cryptographic acceleration is absent.\n2. `AES-256-GCM` - Highly recommended when hardware support is available, \ndespite being somewhat slower than `ChaCha20Poly1305`. It is crucial to avoid \nnonce reuse with AES-256-GCM to prevent security compromises.\n\nSecure code example using `ChaCha20Poly1305` in Java:\n```\npublic void encryptAndDecrypt() throws Exception {\n SecureRandom random = new SecureRandom();\n byte[] secretKey = new byte[32]; // 256-bit key\n byte[] nonce = new byte[12]; // 96-bit nonce\n random.nextBytes(secretKey);\n random.nextBytes(nonce);\n\n Cipher cipher = Cipher.getInstance(\"ChaCha20-Poly1305/None/NoPadding\");\n SecretKeySpec keySpec = new SecretKeySpec(secretKey, \"ChaCha20\");\n GCMParameterSpec spec = new GCMParameterSpec(128, nonce);\n\n cipher.init(Cipher.ENCRYPT_MODE, keySpec, spec);\n byte[] plaintext = \"Secret text\".getBytes(StandardCharsets.UTF_8);\n byte[] ciphertext = cipher.doFinal(plaintext);\n System.out.println(\"Encrypted: \" + Base64.getEncoder().encodeToString(ciphertext));\n\n cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);\n byte[] decrypted = cipher.doFinal(ciphertext);\n System.out.println(\"Decrypted: \" + new String(decrypted, StandardCharsets.UTF_8));\n}\n```\nFor more information, refer:\nhttps://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions\n" metadata: - asvs: - control_id: 6.2.2 Insecure Custom Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + confidence: HIGH + cwe: CWE-327 impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://tools.ietf.org/html/rfc6151 - - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/hashlib_new_insecure_functions.py + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + security-severity: MEDIUM + shortDescription: Use of a broken or risky cryptographic algorithm subcategory: - - audit + - vuln technology: - - python + - java pattern-either: - - pattern: hashlib.new("=~/[M|m][D|d][4|5]/", ...) - - pattern: hashlib.new(..., name="=~/[M|m][D|d][4|5]/", ...) + - pattern: | + javax.crypto.Cipher.getInstance("RC4") + - patterns: + - pattern-inside: | + class $CLS{ + ... + String $ALG = "RC4"; + ... + } + - pattern: | + javax.crypto.Cipher.getInstance($ALG); severity: WARNING - - fix-regex: - regex: _create_unverified_context - replacement: create_default_context - id: python.lang.security.unverified-ssl-context.unverified-ssl-context + - id: java_csrf_rule-SpringCSRFDisabled languages: - - python - message: Unverified SSL context detected. This will permit insecure connections without verifying SSL certificates. Use 'ssl.create_default_context' instead. + - java + message: "The application fails to protect against Cross-Site Request Forgery (CSRF)\ndue to disabling Spring's CSRF protection features.\n\nThis vulnerability may allow attackers to carry out CSRF attacks by crafting \nmalicious links or forms on external websites. Victims who are tricked into \naccessing these links while authenticated in your application could inadvertently \nperform actions that the attacker intends, such as changing user information, \ninitiating transactions, or altering permissions.\n\nTo remediate this issue, remove the call to `HttpSecurity.csrf().disable()` or \nremove the custom `CsrfConfigurer`.\n\nFor more information on CSRF protection in Spring see:\nhttps://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html#servlet-csrf\n\nAdditionally, consider setting all session cookies to have the `SameSite=Strict` \nattribute. It should be noted that this may impact usability when sharing links \nacross other mediums.\nIt is recommended that a two cookie based approach is taken, as outlined in the\n[Top level\nnavigations](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-08#section-8.8.2)\nsection of the SameSite RFC.\n\nFor more information on CSRF see OWASP's guide:\nhttps://owasp.org/www-community/attacks/csrf\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-295: Improper Certificate Validation' + cwe: CWE-352 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Cross-Site Request Forgery (CSRF) + pattern-either: + - pattern: (org.springframework.security.config.annotation.web.builders.HttpSecurity $H). ... .csrf(...). ... .requireCsrfProtectionMatcher(...) + - pattern: (org.springframework.security.config.annotation.web.builders.HttpSecurity $H). ... .csrf(...). ... .disable(...) + - pattern: (org.springframework.security.config.annotation.web.configurers.CsrfConfigurer $C). ... .disable(); + severity: WARNING + - id: java_csrf_rule-UnrestrictedRequestMapping + languages: + - java + message: "Detected a method annotated with 'RequestMapping' that does not specify\nthe HTTP method. CSRF protections are not enabled for GET, HEAD, TRACE, or\nOPTIONS, and by default all HTTP methods are allowed when the HTTP method\nis not explicitly specified. This means that a method that performs state\nchanges could be vulnerable to CSRF attacks. Cross-Site Request Forgery (CSRF) \nis a security vulnerability where an attacker tricks a user into performing \nunintended actions on a web application where they are authenticated. This \ncan lead to unauthorized actions like changing user settings, transferring \nfunds, or altering passwords, all without the user's knowledge, by exploiting \nthe trust a web application has in the user's browser.\n\nTo mitigate, add the 'method' field and specify the HTTP method (such as \n'RequestMethod.POST').\n\nSecure Code Example:\n```\n@RequestMapping(value = \"/path\", method = RequestMethod.POST)\npublic void safe() {\n // State-changing operations performed within this method.\n}\n```\n" + metadata: + category: security + confidence: LOW + cwe: CWE-352 + cwe2021-top25: "true" + cwe2022-top25: "true" impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control references: - - https://docs.python.org/3/library/ssl.html#ssl-security - - https://docs.python.org/3/library/http.client.html#http.client.HTTPSConnection + - https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING + security-severity: MEDIUM + shortDescription: Cross-site request forgery (CSRF) + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING subcategory: - audit technology: - - python + - spring + vulnerability_class: + - Cross-Site Request Forgery (CSRF) patterns: - - pattern-either: - - pattern: ssl._create_unverified_context(...) - - pattern: ssl._create_default_https_context = ssl._create_unverified_context - severity: ERROR - - fix: defusedxml.etree.ElementTree.parse($...ARGS) - id: python.lang.security.use-defused-xml-parse.use-defused-xml-parse + - pattern-inside: | + @RequestMapping(...) + $RETURNTYPE $METHOD(...) { ... } + - pattern-not-inside: | + @RequestMapping(..., method = $X, ...) + $RETURNTYPE $METHOD(...) { ... } + - pattern: | + RequestMapping + severity: WARNING + - id: java_deserialization_rule-InsecureJmsDeserialization languages: - - python - message: The native Python `xml` library is vulnerable to XML External Entity (XXE) attacks. These attacks can leak confidential data and "XML bombs" can cause denial of service. Do not use this library to parse untrusted input. Instead the Python documentation recommends using `defusedxml`. + - java + message: "Deserialization of untrusted JMS ObjectMessage can lead to arbitrary \ncode execution. This vulnerability occurs when `ObjectMessage.getObject()` \nis called to deserialize the payload of an ObjectMessage, potentially \nallowing remote attackers to execute arbitrary code with the permissions \nof the JMS MessageListener application. \n\nTo mitigate the issue, avoid deserialization of untrusted data and \nconsider alternative message formats or explicit whitelisting of \nallowable classes for deserialization.\n\nTo implement allowlisting, override the ObjectInputStream#resolveClass() \nmethod to limit deserialization to allowed classes only. This prevents \ndeserialization of any class except those explicitly permitted, such as \nin the following example that restricts deserialization to the Bicycle \nclass only:\n\n```\n// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html\npublic class LookAheadObjectInputStream extends ObjectInputStream {\n public LookAheadObjectInputStream(InputStream inputStream) throws IOException {\n super(inputStream);\n }\n /**\n * Only deserialize instances of our expected Bicycle class\n */\n @Override\n protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {\n if (!desc.getName().equals(Bicycle.class.getName())) {\n throw new InvalidClassException(\"Unauthorized deserialization attempt\", desc.getName());\n }\n return super.resolveClass(desc);\n }\n}\n```\n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true + cwe: CWE-502 + cwe2021-top25: "true" + cwe2022-top25: "true" impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures references: - - https://docs.python.org/3/library/xml.html - - https://github.com/tiran/defusedxml - - https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing + - https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities-wp.pdf + security-severity: High + shortDescription: Deserialization of untrusted data subcategory: - vuln technology: - - python + - java + vulnerability_class: + - 'Insecure Deserialization ' patterns: - - pattern: xml.etree.ElementTree.parse($...ARGS) - - pattern-not: xml.etree.ElementTree.parse("...") + - pattern-inside: | + class $JMS_LISTENER implements MessageListener { + ... + public void onMessage(Message $JMS_MSG) { + ... + } + } + - pattern: $Y.getObject(...); severity: ERROR - - id: python.pycryptodome.security.insecure-cipher-algorithm-blowfish.insecure-cipher-algorithm-blowfish + - id: java_deserialization_rule-ServerDangerousObjectDeserialization languages: - - python - message: Detected Blowfish cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. + - java + message: "This application uses Java RMI (Remote Method Invocation) interfaces \nthat declare methods with parameters of arbitrary objects \n('$PARAMTYPE $PARAM') that could lead to insecure deserialization \nvulnerabilities. Insecure deserialization occurs when an application \ndeserializes data from untrusted sources without proper sanitization, \npotentially leading to arbitrary code execution, denial of service attacks, \nand other critical vulnerabilities.\n\nJava RMI allows for remote communication between applications by \ninvoking methods on remote objects. When complex objects are used \nas parameters in RMI method declarations, there is \na risk that a malicious actor could exploit the deserialization \nprocess to execute arbitrary code on the server. This vulnerability \nis especially significant if the parameter types are not among the safe, \nimmutable types like String, Integer, etc.\n\nTo mitigate this vulnerability, use an integer ID to look up your \nobject, or consider alternative serialization schemes such as JSON.\n\nSecure Code Example:\n```\nimport java.rmi.Remote;\nimport java.rmi.RemoteException;\n\npublic interface SafeTicketService extends Remote {\n // Using String, which is a safe, immutable type\n boolean registerTicket(String ticketID) throws RemoteException;\n\n // Using primitive data types and wrappers, which are safe\n void visitTalk(int talkID) throws RemoteException;\n void poke(Integer attendeeID) throws RemoteException;\n}\n```\n" metadata: - bandit-code: B304 category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM + confidence: LOW + cwe: CWE-502 + cwe2021-top25: "true" + cwe2022-top25: "true" + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures references: - - https://stackoverflow.com/questions/1135186/whats-wrong-with-xor-encryption - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 - subcategory: - - vuln + - https://frohoff.github.io/appseccali-marshalling-pickles/ + - https://book.hacktricks.xyz/network-services-pentesting/1099-pentesting-java-rmi + - https://youtu.be/t_aw1mDNhzI + - https://github.com/qtc-de/remote-method-guesser + - https://github.com/openjdk/jdk/blob/master/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java#L303C4-L331 + - https://mogwailabs.de/en/blog/2019/03/attacking-java-rmi-services-after-jep-290/ + security-severity: MEDIUM + shortDescription: Deserialization of untrusted data technology: - - pycryptodome - pattern-either: - - pattern: Cryptodome.Cipher.Blowfish.new(...) - - pattern: Crypto.Cipher.Blowfish.new(...) + - rmi + vulnerability_class: + - 'Insecure Deserialization ' + patterns: + - pattern-inside: | + interface $INTERFACE extends Remote { + ... + } + - pattern: | + $RETURNTYPE $METHOD($PARAMTYPE $PARAM) throws RemoteException; + - metavariable-pattern: + language: generic + metavariable: $PARAMTYPE + patterns: + - pattern-not: String + - pattern-not: java.lang.String + - pattern-not: boolean + - pattern-not: Boolean + - pattern-not: java.lang.Boolean + - pattern-not: byte + - pattern-not: Byte + - pattern-not: java.lang.Byte + - pattern-not: char + - pattern-not: Character + - pattern-not: java.lang.Character + - pattern-not: double + - pattern-not: Double + - pattern-not: java.lang.Double + - pattern-not: float + - pattern-not: Float + - pattern-not: java.lang.Float + - pattern-not: int + - pattern-not: Integer + - pattern-not: java.lang.Integer + - pattern-not: long + - pattern-not: Long + - pattern-not: java.lang.Long + - pattern-not: short + - pattern-not: Short + - pattern-not: java.lang.Short severity: WARNING - - id: python.pycryptodome.security.insecure-cipher-algorithm-des.insecure-cipher-algorithm-des + - id: java_deserialization_rule-SnakeYamlConstructor languages: - - python - message: Detected DES cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. + - java + message: "The application uses SnakeYAML org.yaml.snakeyaml.Yaml() constructor \nwith no arguments, which is vulnerable to deserialization attacks. \nWhen Yaml() (no-argument constructor) is used, SnakeYAML uses the \ndefault Constructor which can instantiate any Java object during \ndeserialization. This is risky because an attacker could craft malicious \nYAML files to execute arbitrary code or perform unauthorized actions.\n\nTo mitigate the issue and to safely use SnakeYaml to parse YAML data, \nalways make sure to only ever use a Yaml instance that is constructed \neither with a SafeConstructor or an instance constructed with a \nConstructor specifying a specific class. \n\nPlease note, if you want to use Constructor with a specific target class\nas a mitigation criteria, ensure that snakeyaml version is 2.0 or higher\nas Constructor class is vulnerable in snakeyaml versions lower than 2.0.\nRefer - https://github.com/google/security-research/security/advisories/GHSA-mjmj-j48q-9wg2\n\nSecure Code Examples:\n```\npublic void safeConstructorLoad(String toLoad) {\n // Configure LoaderOptions for safe deserialization\n LoaderOptions loaderOptions = new LoaderOptions();\n loaderOptions.setAllowDuplicateKeys(false);\n loaderOptions.setMaxAliasesForCollections(50);\n\n Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptipon()));\n yaml.load(toLoad);\n}\n\npublic void customConstructorLoad(String toLoad, Class goodClass) {\n // Use Constructor with a specific target class\n LoaderOptions loaderOptions = new LoaderOptions();\n Constructor customConstructor = new Constructor(goodClass, loaderOptions);\n\n Yaml yaml = new Yaml(customConstructor);\n yaml.load(toLoad);\n}\n```\n" metadata: - bandit-code: B304 category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM + confidence: LOW + cwe: CWE-502 + impact: HIGH likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures references: - - https://cwe.mitre.org/data/definitions/326.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 - subcategory: - - vuln + - https://securitylab.github.com/research/swagger-yaml-parser-vulnerability/#snakeyaml-deserialization-vulnerability + security-severity: HIGH + shortDescription: Deserialization of untrusted data technology: - - pycryptodome - pattern-either: - - pattern: Cryptodome.Cipher.DES.new(...) - - pattern: Crypto.Cipher.DES.new(...) - severity: WARNING - - id: python.pycryptodome.security.insecure-cipher-algorithm-rc2.insecure-cipher-algorithm-rc2 + - snakeyaml + patterns: + - pattern: | + $Y = new org.yaml.snakeyaml.Yaml(); + ... + $Y.load(...); + severity: ERROR + - id: java_endpoint_rule-ManuallyConstructedURLs languages: - - python - message: Detected RC2 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. + - java + message: | + User data flows into the host portion of this manually-constructed URL. + This could allow an attacker to send data to their own server, potentially + exposing sensitive data such as cookies or authorization information sent + with this request. They could also probe internal servers or other + resources that the server running this code can access. (This is called + server-side request forgery, or SSRF.) Do not allow arbitrary hosts. + Instead, create an allowlist for approved hosts hardcode the correct host, + or ensure that the user data can only affect the path or parameters. + + Example of using allowlist: + ``` + ArrayList allowlist = (ArrayList) + Arrays.asList(new String[] { "https://example.com/api/1", "https://example.com/api/2", "https://example.com/api/3"}); + + if(allowlist.contains(url)){ + ... + } + ``` metadata: - bandit-code: B304 category: security confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + cwe: CWE-918 + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A1:2017-Injection + - A10:2021-Server-Side Request Forgery references: - - https://cwe.mitre.org/data/definitions/326.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + security-severity: CRITICAL + shortDescription: Detect manually constructed URLs subcategory: - vuln technology: - - pycryptodome - pattern-either: - - pattern: Cryptodome.Cipher.ARC2.new(...) - - pattern: Crypto.Cipher.ARC2.new(...) - severity: WARNING - - id: python.pycryptodome.security.insecure-cipher-algorithm-rc4.insecure-cipher-algorithm-rc4 + - java + - spring + vulnerability_class: + - Server-Side Request Forgery (SSRF) + mode: taint + options: + interfile: true + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: "if($VALIDATION){\n ...\n new URL($ONEARG);\n ...\n} \n" + - pattern: | + $A = $VALIDATION; + ... + if($A){ + ... + new URL($ONEARG); + ... + } + - metavariable-pattern: + metavariable: $VALIDATION + pattern-either: + - pattern: "$AL.contains(...) \n" + - pattern: | + $AL.indexOf(...) != -1 + pattern-sinks: + - pattern-either: + - pattern: new URL($ONEARG) + - patterns: + - pattern-either: + - pattern: | + "$URLSTR" + ... + - pattern: | + "$URLSTR".concat(...) + - patterns: + - pattern-inside: | + StringBuilder $SB = new StringBuilder("$URLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$URLSTR"; + ... + - pattern: $VAR += ... + - patterns: + - pattern: String.format("$URLSTR", ...) + - pattern-not: String.format("$URLSTR", "...", ...) + - patterns: + - pattern-inside: | + String $VAR = "$URLSTR"; + ... + - pattern: String.format($VAR, ...) + - metavariable-regex: + metavariable: $URLSTR + regex: http(s?)://%(v|s|q).* + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + severity: ERROR + - id: java_file_rule_rule-FilePathTraversalHttpServlet languages: - - python - message: Detected ARC4 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. + - java + message: "Detected a potential path traversal. A malicious actor could control\nthe location of this file, to include going backwards in the directory\nwith '../'. \n\nTo address this, ensure that user-controlled variables in file\npaths are sanitized. You may also consider using a utility method such as\norg.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file\nname from the path.\n\nExample code using FilenameUtils.getName(...)\n\n```\npublic void ok(HttpServletRequest request, HttpServletResponse response)\n throws ServletException, IOException {\n String image = request.getParameter(\"image\");\n File file = new File(\"static/images/\", FilenameUtils.getName(image));\n\n if (!file.exists()) {\n log.info(image + \" could not be created.\");\n response.sendError();\n }\n\n response.sendRedirect(\"/index.html\");\n}\n```\n" metadata: - bandit-code: B304 category: security confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + cwe: CWE-22 + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control references: - - https://cwe.mitre.org/data/definitions/326.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 - subcategory: - - vuln + - https://www.owasp.org/index.php/Path_Traversal + security-severity: CRITICAL + shortDescription: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN technology: - - pycryptodome - pattern-either: - - pattern: Cryptodome.Cipher.ARC4.new(...) - - pattern: Crypto.Cipher.ARC4.new(...) - severity: WARNING - - id: python.pycryptodome.security.insecure-cipher-algorithm.insecure-cipher-algorithm-xor + - java + vulnerability_class: + - Path Traversal + mode: taint + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (java.io.File $FILE) = ... + - pattern: | + (java.io.FileOutputStream $FOS) = ... + - pattern: | + new java.io.FileInputStream(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); ... + for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { + ... + } + - pattern: | + $COOKIE.getValue(...) + - patterns: + - pattern-inside: | + $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(...); + ... + - pattern: | + $PARAM = $VALS[$INDEX]; + severity: ERROR + - id: java_ftp_rule-FTPInsecureTransport languages: - - python - message: Detected XOR cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. + - java + message: "This rule identifies instances where the application uses FTP (File\nTransfer Protocol) for transferring files. FTP transmits data in clear\ntext, allowing usernames, passwords, and other sensitive information to be\nintercepted by attackers. Consider using secure alternatives like SFTP\n(SSH File Transfer Protocol) or FTPS (FTP Secure) that provide encryption\nto protect data in transit.\n\nRemediation Strategy: To mitigate the risks associated with using unencrypted\nFTP, the application should switch to a secure file transfer protocol like\nSFTP or FTPS. Below is an example of how to implement FTPS in a Java\napplication.\n\n``` \nimport org.apache.commons.net.ftp.FTPSClient;\n\npublic class FTPSExample {\n public static void main(String[] args) {\n String server = \"ftps.example.com\";\n int port = 21;\n String user = \"your_username\";\n String pass = \"your_password\";\n\n FTPSClient ftpsClient = new FTPSClient();\n try {\n ftpsClient.connect(server, port);\n ftpsClient.login(user, pass);\n // Perform file operations\n\n ftpsClient.logout();\n ftpsClient.disconnect();\n } catch (Exception e) {\n e.printStackTrace();\n }\n }\n} \n```\n" metadata: - bandit-code: B304 category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW + cwe: CWE-319 + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://stackoverflow.com/questions/1135186/whats-wrong-with-xor-encryption - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 + - https://www.codejava.net/java-se/ftp/connect-and-login-to-a-ftp-server + - https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - vuln technology: - - pycryptodome + - java + vulnerability: Insecure Transport pattern-either: - - pattern: Cryptodome.Cipher.XOR.new(...) - - pattern: Crypto.Cipher.XOR.new(...) + - pattern: | + (org.apache.commons.net.ftp.FTPClient $FTPCLIENT).connect(...); + - pattern: | + URL $URL = new URL("=~/^[fF][tT][pP]://.*/"); + ... + URLConnection $CONN = $URL.openConnection(...); severity: WARNING - - id: python.pycryptodome.security.insecure-hash-algorithm-md2.insecure-hash-algorithm-md2 + - id: java_inject_rule-DangerousGroovyShell languages: - - python - message: Detected MD2 hash algorithm which is considered insecure. MD2 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - java + message: "This application implements unsafe invocations of methods within the\n`groovy.lang.GroovyShell` or `groovy.lang.GroovyClassLoader` classes,\nwhich are used to evaluate or compile Groovy code dynamically. When\nuser-controlled input is directly passed to `parse`, `evaluate`, or\n`parseClass` methods, it can lead to Remote Code Execution (RCE), where an\nattacker can execute arbitrary code on the server. This could potentially\nallow an attacker to gain unauthorized access to system resources, modify\ninternal application states, or execute commands on the server depending\non the level of permissions assigned to the application process.\n\nTo mitigate this vulnerability, always validate and sanitize all user inputs \nbefore using them in dynamic code evaluations. Consider using safer alternatives \nto executing dynamic code if possible. If dynamic code execution is absolutely \nnecessary, use strict allowlists of safe inputs and context-specific validation.\n\nSecure Code Example:\n\n```\nimport groovy.lang.GroovyShell;\n\nclass SafeDynamicEvaluation {\n private static final Set ALLOWED_EXPRESSIONS = new HashSet<>(Arrays.asList(\n \"println 'Hello World!'\",\n \"println 'Goodbye World!'\"));\n\n public static void test4(String[] args, ClassLoader loader) throws Exception {\n GroovyShell shell = new GroovyShell();\n String userInput = args[0];\n\n // Validate the user input against the allowlist\n if (ALLOWED_EXPRESSIONS.contains(userInput)) {\n shell.evaluate(userInput);\n // shell.parse(userInput);\n } else {\n throw new IllegalArgumentException(\"Invalid or unauthorized command.\");\n }\n }\n}\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW + cwe: CWE-94 + cwe2022-top25: "true" + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A1:2017-Injection + - A03:2021-Injection references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 - subcategory: - - vuln + - https://owasp.org/Top10/A03_2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code ('Code Injection') + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#GROOVY_SHELL technology: - - pycryptodome - pattern-either: - - pattern: Crypto.Hash.MD2.new(...) - - pattern: Cryptodome.Hash.MD2.new (...) - severity: WARNING - - id: python.pycryptodome.security.insecure-hash-algorithm-md4.insecure-hash-algorithm-md4 + - groovy + vulnerability_class: + - Code Injection + patterns: + - pattern-either: + - pattern: | + (groovy.lang.GroovyShell $SHELL).parse(...) + - pattern: | + (groovy.lang.GroovyShell $SHELL).evaluate(...) + - pattern: | + (groovy.lang.GroovyClassLoader $SHELL).parseClass(...) + - pattern-not: | + $SHELL.parse("...",...) + - pattern-not: | + $SHELL.evaluate("...",...) + - pattern-not: | + $SHELL.parseClass("...",...) + - pattern-not-inside: | + if($ALLOWLIST.contains($INPUT)){ + ... + } + severity: ERROR + - id: java_inject_rule-EnvInjection languages: - - python - message: Detected MD4 hash algorithm which is considered insecure. MD4 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - java + message: "Detected input from a HTTPServletRequest going into the environment\nvariables of an 'exec' command. The user input is passed directly to\nthe Runtime.exec() function to set an environment variable. This allows \nmalicious input from the user to modify the command that will be executed.\nTo remediate this, do not pass user input directly to Runtime.exec().\nValidate any user input before using it to set environment variables \nor command arguments. Consider using an allow list of allowed values\nrather than a deny list. If dynamic commands must be constructed, use\na map to look up valid values based on user input instead of using \nthe input directly.\nExample of safely executing an OS command:\n```\npublic void doPost(HttpServletRequest request, HttpServletResponse response)\n throws ServletException, IOException {\n response.setContentType(\"text/html;charset=UTF-8\");\n\n String param = \"\";\n if (request.getHeader(\"UserDefined\") != null) {\n param = request.getHeader(\"UserDefined\");\n }\n\n param = java.net.URLDecoder.decode(param, \"UTF-8\");\n String cmd = \"/bin/cmd\";\n\n String[] allowList = {\"FOO=true\",\"FOO=false\",\"BAR=true\", \"BAR=false\"}\n if(Arrays.asList(allowList).contains(param)){\n String[] argsEnv = {param};\n }\n \n Runtime r = Runtime.getRuntime();\n\n try {\n Process p = r.exec(cmd, argsEnv);\n printOSCommandResults(p, response); \n } catch (IOException e) {\n System.out.println(\"Problem executing command\");\n response.getWriter()\n .println(org.owasp.esapi.ESAPI.encoder().encodeForHTML(e.getMessage()));\n return;\n }\n```\n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + cwe: CWE-78 impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A1:2017-Injection + - A03:2021-Injection references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + - https://owasp.org/Top10/A03_2021-Injection + security-severity: HIGH + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') subcategory: - vuln technology: - - pycryptodome - pattern-either: - - pattern: Crypto.Hash.MD4.new(...) - - pattern: Cryptodome.Hash.MD4.new (...) - severity: WARNING - - id: python.pycryptodome.security.insecure-hash-algorithm-md5.insecure-hash-algorithm-md5 + - java + vulnerability_class: + - Other + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: | + if($VALIDATION){ + ... + } + - patterns: + - pattern-inside: | + $A = $VALIDATION; + ... + - pattern: | + if($A){ + ... + } + - metavariable-pattern: + metavariable: $VALIDATION + pattern-either: + - pattern: | + $AL.contains(...) + pattern-sinks: + - pattern-either: + - patterns: + - pattern: (java.lang.Runtime $R).exec($CMD, $ENV_ARGS, ...); + - focus-metavariable: $ENV_ARGS + - patterns: + - pattern: (ProcessBuilder $PB).environment().put($...ARGS); + - focus-metavariable: $...ARGS + - patterns: + - pattern: | + $ENV = (ProcessBuilder $PB).environment(); + ... + $ENV.put($...ARGS); + - focus-metavariable: $...ARGS + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + $FUNC(..., $VAR, ...) { + ... + } + - pattern: $VAR + severity: ERROR + - id: java_inject_rule-MongodbNoSQLi languages: - - python - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - java + message: | + Detected non-constant data passed into a NoSQL query using the 'where' + evaluation operator. If this data can be controlled by an external user, + this is a NoSQL injection. Ensure data passed to the NoSQL query is not + user controllable, or properly sanitize the data. Ideally, avoid using the + 'where' operator at all and instead use the helper methods provided by + com.mongodb.client.model.Filters with comparative operators such as eq, + ne, lt, gt, etc. + + Secure Code Example: + ``` + MongoDatabase database = mongoClient.getDatabase("mydb"); + MongoCollection collection = database.getCollection("users"); + + // Secure usage with Filters.eq: + String username = request.getParameter("username"); + collection.find(Filters.eq("username", username)); + ``` metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM + confidence: LOW + cwe: CWE-943 + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A1:2017-Injection + - A03:2021-Injection references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + - https://owasp.org/Top10/A03_2021-Injection + - https://www.mongodb.com/docs/manual/tutorial/query-documents/ + - https://www.mongodb.com/docs/manual/reference/operator/query/where/ + security-severity: CRITICAL + shortDescription: Improper neutralization of special elements in data query logic subcategory: - - vuln + - audit technology: - - pycryptodome - pattern-either: - - pattern: Crypto.Hash.MD5.new(...) - - pattern: Cryptodome.Hash.MD5.new (...) - severity: WARNING - - id: python.pycryptodome.security.insecure-hash-algorithm.insecure-hash-algorithm-sha1 + - nosql + - mongodb + vulnerability_class: + - Improper Validation + patterns: + - pattern-either: + - pattern: (com.mongodb.BasicDBObject $QUERY).put("$where", $INPUT); + - pattern: | + (HashMap $MAP).put("$where", $INPUT); + ... + (com.mongodb.BasicDBObject $QUERY).putAll($MAP); + - pattern: (com.mongodb.BasicDBObject $QUERY).append("$where", $INPUT); + - pattern: new com.mongodb.BasicDBObject("$where", $INPUT); + - pattern: | + (HashMap $MAP).put("$where", $INPUT); + ... + new com.mongodb.BasicDBObject($MAP); + - pattern: | + (HashMap $MAP).put("$where", $INPUT); + ... + String json = new JSONObject($MAP).toString(); + ... + (com.mongodb.BasicDBObject $QUERY).parse((String $JSON)); + - pattern: com.mongodb.BasicDBObjectBuilder.start().add("$where", $INPUT); + - pattern: com.mongodb.BasicDBObjectBuilder.start().append("$where", $INPUT); + - pattern: com.mongodb.BasicDBObjectBuilder.start("$where", $INPUT); + - pattern: | + (HashMap $MAP).put("$where", $INPUT); + ... + com.mongodb.BasicDBObjectBuilder.start($MAP); + - metavariable-pattern: + metavariable: $INPUT + patterns: + - pattern: | + ... + - pattern-not: | + "..." + severity: ERROR + - id: java_inject_rule-SeamLogInjection languages: - - python - message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - java + message: "The Seam logging API supports an expression language that allows developers to \nintroduce bean properties to log messages. The expression language can also be \nthe source to unwanted code execution. Expressions could be executed by dynamically\ninserting user-controlled input into the various logging calls. \n\nUse the [Seam logging API format specifier](https://docs.jboss.org/seam/2.1.2/reference/en-US/html/concepts.html#d0e4244) to ensure values are logged and expressions\nare not executed dynamically prior to output.\n\nExample logging call that safely logs the unfiltered values.\n```\nlog.info(\"This is a user controlled input = #0\", input);\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW + cwe: CWE-95 + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A1:2017-Injection + - A03:2021-Injection references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 - subcategory: - - vuln - technology: - - pycryptodome - pattern-either: - - pattern: Crypto.Hash.SHA.new(...) - - pattern: Cryptodome.Hash.SHA.new (...) - severity: WARNING - - id: python.pycryptodome.security.insufficient-dsa-key-size.insufficient-dsa-key-size + - https://owasp.org/Top10/A03_2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of directives in dynamically evaluated code ('Eval Injection') + patterns: + - pattern: | + $LOG.$INFO($X + $Y,...) + - pattern-either: + - pattern-inside: | + import org.jboss.seam.log.Log; + ... + - pattern-inside: | + org.jboss.seam.log.Log $LOG = ...; + ... + - metavariable-regex: + metavariable: $INFO + regex: (debug|error|fatal|info|trace|warn) + severity: ERROR + - id: java_inject_rule-SqlInjection languages: - - python - message: Detected an insufficient key size for DSA. NIST recommends a key size of 2048 or higher. + - java + message: | + SQL Injection is a critical vulnerability that can lead to data or system compromise. By + dynamically generating SQL query strings, user input may be able to influence the logic of + the SQL statement. This could lead to an adversary accessing information they should + not have access to, or in some circumstances, being able to execute OS functionality or code. + + Replace all dynamically generated SQL queries with parameterized queries. In situations where + dynamic queries must be created, never use direct user input, but instead use a map or + dictionary of valid values and resolve them using a user-supplied key. + + For example, some database drivers do not allow parameterized queries for `>` or `<` comparison + operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the + user + supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` + values to be used in the construction of the dynamic query. The same goes for other queries + where + column or table names are required but cannot be parameterized. + + Example using `PreparedStatement` queries: + ``` + // Some userInput + String userInput = "someUserInput"; + // Your connection string + String url = "..."; + // Get a connection from the DB via the DriverManager + Connection conn = DriverManager.getConnection(url); + // Create a prepared statement + PreparedStatement st = conn.prepareStatement("SELECT name FROM table where name=?"); + // Set each parameters value by the index (starting from 1) + st.setString(1, userInput); + // Execute query and get the result set + ResultSet rs = st.executeQuery(); + // Iterate over results + while (rs.next()) { + // Get result for this row at the provided column number (starting from 1) + String result = rs.getString(1); + // ... + } + // Close the ResultSet + rs.close(); + // Close the PreparedStatement + st.close(); + ``` + + Example on using CriteriaBuilder to build queries + ``` + public List findBySomeCriteria(EntityManager entityManager, String criteriaValue) { + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = criteriaBuilder.createQuery(YourEntity.class); + Root root = query.from(YourEntity.class); + + query.select(root).where(criteriaBuilder.equal(root.get("someProperty"), criteriaValue)); + + return entityManager.createQuery(query).getResultList(); + } + ``` + + For more information on SQL Injection see OWASP: + https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-89 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py - subcategory: - - vuln + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an SQL command ('SQL Injection') technology: - - pycryptodome - patterns: - - pattern-either: - - pattern: Crypto.PublicKey.DSA.generate(..., bits=$SIZE, ...) - - pattern: Crypto.PublicKey.DSA.generate($SIZE, ...) - - pattern: Cryptodome.PublicKey.DSA.generate(..., bits=$SIZE, ...) - - pattern: Cryptodome.PublicKey.DSA.generate($SIZE, ...) - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - severity: WARNING - - id: python.pycryptodome.security.insufficient-rsa-key-size.insufficient-rsa-key-size + - java + mode: taint + options: + taint_assume_safe_booleans: true + taint_assume_safe_numbers: true + pattern-propagators: + - from: $X + pattern: $LIST.add($X) + to: $LIST + - from: $X + pattern: $MAP.put(..., $X) + to: $MAP + - from: $X + pattern: $STR.concat($X) + to: $STR + - from: $X + pattern: $STR = String.format(..., $X, ...) + to: $STR + - from: $X + pattern: $STR = String.join(..., $X, ...) + to: $STR + - from: $X + pattern: $SB.append($X) + to: $SB + pattern-sanitizers: + - pattern: (CriteriaBuilder $CB).$ANY(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: (javax.jdo.PersistenceManager $PM).newQuery($ARG) + - pattern: (javax.jdo.PersistenceManager $PM).newQuery(..., $ARG) + - pattern: (javax.jdo.Query $Q).setFilter($ARG) + - pattern: (javax.jdo.Query $Q).setGrouping($ARG) + - pattern: org.hibernate.criterion.Restrictions.sqlRestriction($ARG, ...) + - pattern: (org.hibernate.Session $S).createQuery((String $ARG), ...) + - pattern: (org.hibernate.Session $S).createSQLQuery($ARG, ...) + - pattern: (org.hibernate.Session $S).connection().prepareStatement($ARG) + - pattern: (java.sql.Statement $S).executeQuery($ARG, ...) + - pattern: (java.sql.Statement $S).execute($ARG, ...) + - pattern: (java.sql.Statement $S).executeUpdate($ARG, ...) + - pattern: (java.sql.Statement $S).executeLargeUpdate($ARG, ...) + - pattern: (java.sql.Statement $S).addBatch($ARG, ...) + - pattern: (java.sql.PreparedStatement $S).executeQuery($ARG, ...) + - pattern: (java.sql.PreparedStatement $S).execute($ARG, ...) + - pattern: (java.sql.PreparedStatement $S).executeUpdate($ARG, ...) + - pattern: (java.sql.PreparedStatement $S).executeLargeUpdate($ARG, ...) + - pattern: (java.sql.PreparedStatement $S).addBatch($ARG, ...) + - pattern: (java.sql.Connection $S).prepareCall($ARG, ...) + - pattern: (java.sql.Connection $S).prepareStatement($ARG, ...) + - pattern: (java.sql.Connection $S).nativeSQL($ARG, ...) + - pattern: new org.springframework.jdbc.core.PreparedStatementCreatorFactory($ARG, ...) + - pattern: (org.springframework.jdbc.core.PreparedStatementCreatorFactory $F).newPreparedStatementCreator($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).batchUpdate($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).execute($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).query($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForList($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForMap($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForObject($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForObject($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForRowSet($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForInt($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForLong($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcOperations $O).update($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).batchUpdate($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).execute($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).query($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForList($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForMap($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForObject($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForRowSet($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForInt($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForLong($ARG, ...) + - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).update($ARG, ...) + - pattern: (io.vertx.sqlclient.SqlClient $O).query($ARG, ...) + - pattern: (io.vertx.sqlclient.SqlClient $O).preparedQuery($ARG, ...) + - pattern: (io.vertx.sqlclient.SqlConnection $O).prepare($ARG, ...) + - pattern: (org.apache.turbine.om.peer.BasePeer $O).executeQuery($ARG, ...) + - pattern: org.apache.torque.util.BasePeer.executeQuery($ARG, ...) + - pattern: org.apache.torque.util.BasePeer.executeStatement($ARG, ...) + - pattern: (javax.persistence.EntityManager $O).createQuery($ARG, ...) + - pattern: (javax.persistence.EntityManager $O).createNativeQuery($ARG, ...) + - pattern: (org.jdbi.v3.core.Handle $H).createQuery($ARG, ...) + - pattern: (org.jdbi.v3.core.Handle $H).createScript($ARG, ...) + - pattern: (org.jdbi.v3.core.Handle $H).createUpdate($ARG, ...) + - pattern: (org.jdbi.v3.core.Handle $H).execute($ARG, ...) + - pattern: (org.jdbi.v3.core.Handle $H).prepareBatch($ARG, ...) + - pattern: (org.jdbi.v3.core.Handle $H).select($ARG, ...) + - pattern: new org.jdbi.v3.core.statement.Script($H, $ARG) + - pattern: new org.jdbi.v3.core.statement.Update($H, $ARG) + - pattern: new org.jdbi.v3.core.statement.PreparedBatch($H, $ARG) + - focus-metavariable: $ARG + - patterns: + - pattern: (java.sql.Connection $S).createStatement(...).$SQLFUNC($ARG, ...) + - pattern-not: (java.sql.Connection $S).createStatement(...).$SQLFUNC("...") + - metavariable-regex: + metavariable: $SQLFUNC + regex: execute|executeQuery|createQuery|query|addBatch|nativeSQL|create|prepare + pattern-sources: + - pattern: (javax.servlet.http.HttpServletRequest $R).$METHOD(...) + - pattern: (java.util.Scanner $S).$METHOD(...) + - pattern: (java.util.stream.Stream).$METHOD(...) + - pattern: (java.util.StringJoiner $SJ).toString(...) + - pattern: (java.sql.ResultSet.getString $R).$METHOD(...) + - pattern: (java.lang.System $S).getProperty(...) + - pattern: (java.lang.System $S).getenv(...) + - pattern: (java.lang.StringBuilder $SB).toString(...) + - pattern: (java.io.FileInputStream $F).read(...) + - pattern: (java.io.FileReader $F).read(...) + - pattern: (java.net.Socket $S).getInputStream(...) + - pattern: (java.net.Socket $S).getOutputStream(...) + - pattern: (java.net.DatagramSocket $S).receive(...) + - pattern: (java.net.DatagramSocket $S).getInputStream(...) + - pattern: java.nio.file.Files.readAllBytes(...) + - pattern: java.nio.file.Files.readAllLines(...) + - pattern: java.nio.file.Files.lines(...) + - pattern: java.nio.file.Files.newBufferedReader(...) + - pattern: org.apache.commons.io.IOUtils.toString(...) + - pattern: org.apache.commons.io.IOUtils.readLines(...) + - pattern: org.apache.commons.io.IOUtils.toByteArray(...) + - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).readValue(...) + - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).treeToValue(...) + - pattern: $CLASS.$METHOD(..., (javax.servlet.http.HttpServletRequest $R), ...) + - pattern: $FUNC(..., (javax.servlet.http.HttpServletRequest $R), ...) + - patterns: + - pattern-inside: $FUNC(..., String $X, ...) { ... } + - focus-metavariable: $X + severity: ERROR + - id: java_traversal_rule-RelativePathTraversal languages: - - python - message: Detected an insufficient key size for RSA. NIST recommends a key size of 2048 or higher. + - java + message: "Detected user input controlling a file path. An attacker could control\nthe location of this file, to include going backwards in the directory\nwith '../'. \n\nTo address this, ensure that user-controlled variables in file\npaths are sanitized. You may also consider using a utility method such as\norg.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file\nname from the path.\n\nExample of using `org.apache.commons.io.FilenameUtils.getName(...)` to \nonly retrieve the file name from the path\n```\nString fileName = org.apache.commons.io.FilenameUtils.getName(userControlledInput);\nFile file = new File(\"/path/to/directory/\" + fileName);\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-23 + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A01:2021-Broken Access Control + - A5:2017-Broken Access Control references: - - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py - subcategory: - - vuln - technology: - - pycryptodome - patterns: - - pattern-either: - - pattern: Crypto.PublicKey.RSA.generate(..., bits=$SIZE, ...) - - pattern: Crypto.PublicKey.RSA.generate($SIZE, ...) - - pattern: Cryptodome.PublicKey.RSA.generate(..., bits=$SIZE, ...) - - pattern: Cryptodome.PublicKey.RSA.generate($SIZE, ...) - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - severity: WARNING - - id: python.pycryptodome.security.mode-without-authentication.crypto-mode-without-authentication + - https://owasp.org/www-community/attacks/Path_Traversal + security-severity: CRITICAL + shortDescription: Relative Path Traversal + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: new File(...) + - pattern: new java.io.File(...) + - pattern: new FileReader(...) + - pattern: new java.io.FileReader(...) + - pattern: new FileInputStream(...) + - pattern: new java.io.FileInputStream(...) + - pattern: (Paths $PATHS).get(...) + - patterns: + - pattern: | + $CLASS.$FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: ^(getResourceAsStream|getResource)$ + - patterns: + - pattern-either: + - pattern: new ClassPathResource($FILE, ...) + - pattern: ResourceUtils.getFile($FILE, ...) + - pattern: new FileOutputStream($FILE, ...) + - pattern: new java.io.FileOutputStream($FILE, ...) + - pattern: new StreamSource($FILE, ...) + - pattern: new javax.xml.transform.StreamSource($FILE, ...) + - pattern: FileUtils.openOutputStream($FILE, ...) + - focus-metavariable: $FILE + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + severity: ERROR + - id: java_xpathi_rule-XpathInjection languages: - - python - message: 'An encryption mode of operation is being used without proper message authentication. This can potentially result in the encrypted content to be decrypted by an attacker. Consider instead use an AEAD mode of operation like GCM. ' + - java + message: "The application processes `XPath` queries with potentially malicious input.\nAn adversary who is able to control the XPath query could potentially influence the logic\nof how data is retrieved, processed or even bypass protections.\n\nTo mitigate the vulnerability, avoid using user input in XPath queries.\nIf it cannot be avoided, validate the user input against an allowlist\nof expected values before using it in the query. \n\nFollowing is an example that demonstrates how to perform an XPath query \nusing user input validated against an allowlist.\n\nSecure code example:\n```\npublic class SecureXPathWithoutResolver {\n\n private static final List ALLOWED_AUTHORS = List.of(\"Author1\", \"Author2\", \"Author3\");\n\n public static void main(String[] args) {\n try {\n String userInput = \"Author1\"; // Example user input\n if (ALLOWED_AUTHORS.contains(userInput)) {\n // User input is safe to use\n DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n DocumentBuilder builder = factory.newDocumentBuilder();\n Document doc = builder.parse(\"path/to/your/xmlfile.xml\");\n\n XPathFactory xpathFactory = XPathFactory.newInstance();\n XPath xpath = xpathFactory.newXPath();\n\n // Safely embed the validated user input into the XPath expression\n String expression = String.format(\"//books/book[author='%s']\", userInput);\n NodeList nodes = (NodeList) xpath.evaluate(expression, doc, XPathConstants.NODESET);\n\n for (int i = 0; i < nodes.getLength(); i++) {\n System.out.println(nodes.item(i).getTextContent());\n }\n } else {\n throw new IllegalArgumentException(\"Input is not allowed.\");\n }\n } catch (Exception e) {\n e.printStackTrace();\n }\n }\n}\n```\n\nFor more information on XPath Injection see:\n- https://owasp.org/www-community/attacks/XPATH_Injection\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW + cwe: CWE-643 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - cryptography - patterns: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of data within XPath expressions ('XPath Injection') + mode: taint + pattern-sanitizers: + - patterns: + - pattern-inside: $MAP.getOrDefault($VAR,"..."); + - pattern: $VAR + - patterns: + - pattern-either: + - pattern: | + if($VALIDATION){ + ... + } + - patterns: + - pattern-inside: | + $A = $VALIDATION; + ... + - pattern: | + if($A){ + ... + } + - metavariable-pattern: + metavariable: $VALIDATION + pattern-either: + - pattern: | + $AL.contains(...) + - pattern: | + $AL.equals(...) + pattern-sinks: - pattern-either: - patterns: - - pattern-either: - - pattern: | - AES.new(..., $PYCRYPTODOME_MODE) - - pattern-not-inside: | - AES.new(..., $PYCRYPTODOME_MODE) + - pattern-inside: | + (javax.xml.xpath.XPath $XP). ... .evaluate($EXP, ...); + - pattern: $EXP + - patterns: + - pattern-inside: | + (javax.xml.xpath.XPath $XP). ... .compile($EXP, ...); + - pattern: $EXP + pattern-sources: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ).$FUNC(...) + - patterns: + - pattern-inside: | + $FUNC(..., $VAR, ...) { ... - HMAC.new - - metavariable-pattern: - metavariable: $PYCRYPTODOME_MODE - patterns: - - pattern-either: - - pattern: AES.MODE_CBC - - pattern: AES.MODE_CTR - - pattern: AES.MODE_CFB - - pattern: AES.MODE_OFB + } + - pattern: $VAR severity: ERROR - - fix-regex: - regex: MONGODB-CR - replacement: SCRAM-SHA-256 - id: python.pymongo.security.mongodb.mongo-client-bad-auth - languages: - - python - message: Warning MONGODB-CR was deprecated with the release of MongoDB 3.6 and is no longer supported by MongoDB 4.0 (see https://api.mongodb.com/python/current/examples/authentication.html for details). - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-477: Use of Obsolete Function' - impact: LOW - likelihood: LOW - references: - - https://cwe.mitre.org/data/definitions/477.html - subcategory: - - vuln - technology: - - pymongo - pattern: | - pymongo.MongoClient(..., authMechanism='MONGODB-CR') - severity: WARNING - - fix: | - $...PARAMS, httponly=True - id: python.pyramid.audit.authtkt-cookie-httponly-unsafe-default.pyramid-authtkt-cookie-httponly-unsafe-default + - id: java_xxe_rule-DisallowDoctypeDeclFalse languages: - - python - message: Found a Pyramid Authentication Ticket cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - java + message: "DOCTYPE declarations are enabled for $DBFACTORY. Without prohibiting\nexternal entity declarations, this is vulnerable to XML external entity\nattacks. In an XXE attack, an attacker can exploit the processing of external \nentity references within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise.\n\nTo mitigate this vulnerability, disable this by setting the feature\n\"http://apache.org/xml/features/disallow-doctype-decl\" to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\nentities declarations. This can be done by setting the features\n\"http://xml.org/sax/features/external-general-entities\" and\n\"http://xml.org/sax/features/external-parameter-entities\" to false.\n\nSecure Code Example: \n``` \npublic void GoodXMLInputFactory() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n} \n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW + confidence: HIGH + cwe: CWE-611 + cwe2021-top25: "true" + cwe2022-top25: "true" + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A05:2021 - Security Misconfiguration + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference technology: - - pyramid + - java + - xml + vulnerability_class: + - XML Injection patterns: - - pattern: pyramid.authentication.$FUNC($...PARAMS) - - metavariable-pattern: - metavariable: $FUNC - pattern-either: - - pattern: AuthTktCookieHelper - - pattern: AuthTktAuthenticationPolicy - - pattern-not: pyramid.authentication.$FUNC(..., httponly=$HTTPONLY, ...) - - pattern-not: pyramid.authentication.$FUNC(..., **$PARAMS, ...) - - focus-metavariable: $...PARAMS + - pattern: | + $DBFACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", + false); + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + } severity: WARNING - - fix: | - True - id: python.pyramid.audit.authtkt-cookie-httponly-unsafe-value.pyramid-authtkt-cookie-httponly-unsafe-value + - id: java_xxe_rule-DocumentBuilderFactoryDisallowDoctypeDeclMissing languages: - - python - message: Found a Pyramid Authentication Ticket cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - java + message: "DOCTYPE declarations are enabled for this DocumentBuilderFactory. Enabling \nDOCTYPE declarations without proper restrictions can make your application \nvulnerable to XML External Entity (XXE) attacks. \nIn an XXE attack, an attacker can exploit the processing of external entity \nreferences within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise. \n\nTo mitigate this vulnerability, disable this by setting the\nfeature \"http://apache.org/xml/features/disallow-doctype-decl\" to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\nentities declarations. This can be done by setting the features\n\"http://xml.org/sax/features/external-general-entities\" and\n\"http://xml.org/sax/features/external-parameter-entities\" to false.\n\nSecure Code Example (You can do either of the following):\n```\npublic void GoodDocumentBuilderFactory() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n dbf.newDocumentBuilder();\n}\n\npublic void GoodDocumentBuilderFactory2() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n dbf.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n dbf.newDocumentBuilder();\n}\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW + confidence: HIGH + cwe: CWE-611 + cwe2021-top25: "true" + cwe2022-top25: "true" + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A05:2021 - Security Misconfiguration + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference subcategory: - vuln technology: - - pyramid - patterns: - - pattern-either: + - java + - xml + vulnerability_class: + - XML Injection + mode: taint + pattern-sanitizers: + - by-side-effect: true + pattern-either: - patterns: - - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktCookieHelper(..., httponly=$HTTPONLY, ...) + - pattern-either: + - pattern: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); ... $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); ... $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + - focus-metavariable: $FACTORY - patterns: - - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., httponly=$HTTPONLY, ...) - - pattern: $HTTPONLY - - metavariable-pattern: - metavariable: $HTTPONLY - pattern: | - False + - pattern-either: + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", + true); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); + ... + } + ... + } + - pattern: $M($X) + - focus-metavariable: $X + pattern-sinks: + - patterns: + - pattern: | + $FACTORY.newDocumentBuilder(); + pattern-sources: + - by-side-effect: true + patterns: + - pattern: | + $FACTORY + - pattern-inside: | + $FACTORY = DocumentBuilderFactory.newInstance(); + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + ... + static { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + ... + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + ... + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } severity: WARNING - - fix: | - 'Lax' - id: python.pyramid.audit.authtkt-cookie-samesite.pyramid-authtkt-cookie-samesite + - id: java_xxe_rule-ExternalGeneralEntitiesTrue languages: - - python - message: Found a Pyramid Authentication Ticket without the samesite option correctly set. Pyramid cookies should be handled securely by setting samesite='Lax'. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - java + message: "This rule identifies instances in the code where an XML parser is\nconfigured to allow external general entities. Allowing the processing \nof external general entities without proper validation or restriction \ncan lead to XXE attacks. An attacker can craft an XML document to \nreference sensitive files on the server or external systems under the \nattacker's control, leading to data disclosure, denial of service, or \nserver-side request forgery (SSRF).\n\nTo mitigate this vulnerability, the application should be configured to \ndisable the use of external general entities in XML parsing. This can be \nachieved by setting the feature \n\"http://xml.org/sax/features/external-general-entities\" to false.\n\nSecure Code Example:\n```\nclass GoodSAXBuilder {\n public void GoodSAXBuilder1() throws ParserConfigurationException {\n SAXBuilder saxBuilder = new SAXBuilder();\n saxBuilder.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n }\n}\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' - impact: LOW - likelihood: LOW + cwe: CWE-611 + cwe2021-top25: "true" + cwe2022-top25: "true" + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A01:2021 - Broken Access Control + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference technology: - - pyramid - patterns: - - pattern-either: - - pattern: pyramid.authentication.AuthTktCookieHelper(..., samesite=$SAMESITE, ...) - - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., samesite=$SAMESITE, ...) - - pattern: $SAMESITE - - metavariable-regex: - metavariable: $SAMESITE - regex: (?!'Lax') + - java + - xml + vulnerability_class: + - XML Injection + pattern: | + $PARSER.setFeature("http://xml.org/sax/features/external-general-entities", + true); severity: WARNING - - fix-regex: - regex: (.*)\) - replacement: \1, secure=True) - id: python.pyramid.audit.authtkt-cookie-secure-unsafe-default.pyramid-authtkt-cookie-secure-unsafe-default + - id: java_xxe_rule-ExternalParameterEntitiesTrue languages: - - python - message: Found a Pyramid Authentication Ticket cookie using an unsafe default for the secure option. Pyramid cookies should be handled securely by setting secure=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - java + message: "This rule identifies instances in the code where the XML parser is\nconfigured to allow external parameter entities. Enabling external\nentities in XML parsing can lead to XML External Entity (XXE) attacks,\nwhere an attacker could exploit the XML parser to read sensitive files\nfrom the server, perform denial of service (DoS) attacks, or achieve\nserver-side request forgery (SSRF). This vulnerability occurs when the\napplication processes XML input that includes external entity references\nwithin an XML document.\n\nTo mitigate this vulnerability, the application should be configured to disable \nthe use of external entities in XML parsing. This can be achieved by setting the \nfeature \"http://xml.org/sax/features/external-parameter-entities\" to false.\n\nSecure Code Example: \n``` \ntry {\n DBFactory dbFactory = DocumentBuilderFactory.newInstance();\n // Disable external entities to mitigate XXE vulnerability\n dbFactory.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n dbFactory.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n // Additional configuration for secure parsing\n dbFactory.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n dbFactory.setXIncludeAware(false);\n dbFactory.setExpandEntityReferences(false);\n\n // Use the configured factory to create a document builder\n DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();\n // Parse an XML file using the secure document builder\n Document doc = dBuilder.parse(new InputSource(new StringReader(xmlData)));\n // Process the document as needed\n} catch (ParserConfigurationException | SAXException | IOException e) {\n // Handle exceptions appropriately\n} \n``` \n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW + cwe: CWE-611 + cwe2021-top25: "true" + cwe2022-top25: "true" + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A05:2021 - Security Misconfiguration + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference technology: - - pyramid - patterns: - - pattern-either: - - patterns: - - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., secure=$SECURE, ...) - - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktCookieHelper(...) - - patterns: - - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., secure=$SECURE, ...) - - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(...) + - java + - xml + vulnerability_class: + - XML Injection + pattern: | + $PARSER.setFeature("http://xml.org/sax/features/external-parameter-entities", + true); severity: WARNING - - fix: | - True - id: python.pyramid.audit.authtkt-cookie-secure-unsafe-value.pyramid-authtkt-cookie-secure-unsafe-value + - id: java_xxe_rule-SAXParserFactoryDisallowDoctypeDeclMissing languages: - - python - message: Found a Pyramid Authentication Ticket cookie without the secure option correctly set. Pyramid cookies should be handled securely by setting secure=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - java + message: "DOCTYPE declarations are enabled for this SAXParserFactory. Enabling DOCTYPE \ndeclarations without proper restrictions can make your application vulnerable to \nXML External Entity (XXE) attacks. \nIn an XXE attack, an attacker can exploit the processing of external entity \nreferences within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise.\n\nTo mitigate this vulnerability, disable DOCTYPE declarations by setting the\nfeature `http://apache.org/xml/features/disallow-doctype-decl` to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\nentities declarations. This can be done by setting the features\n`http://xml.org/sax/features/external-general-entities` and\n`http://xml.org/sax/features/external-parameter-entities` to false. \nNOTE: The previous links are not meant to be clicked. They are the literal\nconfig key values that are supposed to be used to disable these features.\n\nSecure Code Example (You can do either of the following):\n```\npublic void GoodSAXParserFactory() throws ParserConfigurationException {\n SAXParserFactory spf = SAXParserFactory.newInstance();\n spf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n spf.newSAXParser();\n}\n\npublic void GoodSAXParserFactory2() throws ParserConfigurationException {\n SAXParserFactory spf = SAXParserFactory.newInstance();\n spf.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n spf.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n spf.newSAXParser();\n} \n```\nFor more information, see\nhttps://semgrep.dev/docs/cheat-sheets/java-xxe/#3a-documentbuilderfactory.\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW + cwe: CWE-611 + cwe2021-top25: "true" + cwe2022-top25: "true" + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A05:2021 - Security Misconfiguration + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference technology: - - pyramid - patterns: - - pattern-either: + - java + - xml + vulnerability_class: + - XML Injection + mode: taint + pattern-sanitizers: + - by-side-effect: true + pattern-either: - patterns: - - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktCookieHelper(..., secure=$SECURE, ...) + - pattern-either: + - pattern: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + - focus-metavariable: $FACTORY - patterns: - - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., secure=$SECURE, ...) - - pattern: $SECURE - - metavariable-pattern: - metavariable: $SECURE - pattern: | - False + - pattern-either: + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", + true); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); + ... + } + ... + } + - pattern: $M($X) + - focus-metavariable: $X + pattern-sinks: + - patterns: + - pattern: $FACTORY.newSAXParser(); + pattern-sources: + - by-side-effect: true + patterns: + - pattern-either: + - pattern: | + $FACTORY = SAXParserFactory.newInstance(); + - patterns: + - pattern: $FACTORY + - pattern-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } severity: WARNING - - fix: | - True - id: python.pyramid.audit.csrf-origin-check-disabled-globally.pyramid-csrf-origin-check-disabled-globally - languages: - - python - message: Automatic check of the referrer for cross-site request forgery tokens has been explicitly disabled globally, which might leave views unprotected when an unsafe CSRF storage policy is used. Use 'pyramid.config.Configurator.set_default_csrf_options(check_origin=True)' to turn the automatic check for all unsafe methods (per RFC2616). - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-inside: | - $CONFIG.set_default_csrf_options(..., check_origin=$CHECK_ORIGIN, ...) - - pattern: $CHECK_ORIGIN - - metavariable-comparison: - comparison: $CHECK_ORIGIN == False - metavariable: $CHECK_ORIGIN - severity: ERROR - - fix: | - True - id: python.pyramid.audit.csrf-origin-check-disabled.pyramid-csrf-origin-check-disabled + - id: java_xxe_rule-TransformerfactoryDTDNotDisabled languages: - - python - message: Origin check for the CSRF token is disabled for this view. This might represent a security risk if the CSRF storage policy is not known to be secure. + - java + message: "This rule identifies configurations of the TransformerFactory class where\nDOCTYPE declarations are enabled. Enabling DOCTYPE declarations without\nproper restrictions can make your application vulnerable to XML External\nEntity (XXE) attacks. In an XXE attack, an attacker can exploit the\nprocessing of external entity references within an XML document to access\ninternal files, conduct denial-of-service attacks, or SSRF (Server Side\nRequest Forgery), potentially leading to sensitive information disclosure\nor system compromise.\n\nTo mitigate XXE vulnerabilities related to the TransformerFactory instance in \nJava, it is crucial to disable external DTD (Document Type Definition) and \nexternal stylesheet processing. This can be accomplished by setting the \nACCESS_EXTERNAL_DTD and ACCESS_EXTERNAL_STYLESHEET factory attributes to an \nempty string (\"\"). This approach prevents the parser from fetching and processing \nexternal references specified in the XML document.\n\nSecure Code Example:\n```\npublic static void configureTransformerFactory() throws TransformerConfigurationException {\n TransformerFactory factory = TransformerFactory.newInstance();\n // Disable access to external DTDs and stylesheets to prevent XXE\n factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, \"\");\n factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, \"\");\n}\n```\n" metadata: - asvs: - control_id: 4.2.2 CSRF - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V4-Access-Control.md#v42-operation-level-access-control - section: V4 Access Control - version: "4" category: security - confidence: MEDIUM - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW + cwe: CWE-611 + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A01:2021 - Broken Access Control + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference technology: - - pyramid - patterns: - - pattern-inside: | - from pyramid.view import view_config - ... - @view_config(..., check_origin=$CHECK_ORIGIN, ...) - def $VIEW(...): - ... - - pattern: $CHECK_ORIGIN - - metavariable-comparison: - comparison: $CHECK_ORIGIN == False - metavariable: $CHECK_ORIGIN + - java + - xml + mode: taint + pattern-sanitizers: + - by-side-effect: true + pattern-either: + - patterns: + - pattern-either: + - pattern: | + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + - pattern: | + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + - pattern: | + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + - pattern: | + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + - focus-metavariable: $FACTORY + - patterns: + - pattern-either: + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + } + ... + } + - pattern: $M($X) + - focus-metavariable: $X + pattern-sinks: + - patterns: + - pattern: $FACTORY.newTransformer(...); + pattern-sources: + - by-side-effect: true + patterns: + - pattern-either: + - pattern: | + $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); + - patterns: + - pattern: $FACTORY + - pattern-inside: | + class $C { + ... + $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + } + ... + } severity: WARNING - - fix-regex: - regex: (.*)\) - replacement: \1, httponly=True) - id: python.pyramid.audit.set-cookie-httponly-unsafe-default.pyramid-set-cookie-httponly-unsafe-default + - id: java_xxe_rule-XMLInputFactoryExternalEntitiesEnabled languages: - - python - message: Found a Pyramid cookie using an unsafe default for the httponly option. Pyramid cookies should be handled securely by setting httponly=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - java + message: "XML external entities are enabled for this XMLInputFactory. Enabling external \nentities can make the application vulnerable to XML external entity attacks. \nIn an XXE attack, an attacker can exploit the processing of external entity \nreferences within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise.\n\nTo mitigate this vulnerability, disable external entities by\nsetting \"javax.xml.stream.isSupportingExternalEntities\" to false.\n\nSecure Code Example:\n```\npublic GoodXMLInputFactory() {\n final XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();\n xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);\n xmlInputFactory.setProperty(\"javax.xml.stream.isSupportingExternalEntities\", false);\n}\n```\nFor more details, refer to https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.md#xmlinputfactory-a-stax-parser\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW + confidence: LOW + cwe: CWE-611 + cwe2021-top25: "true" + cwe2022-top25: "true" + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A05:2021 - Security Misconfiguration + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., httponly=$HTTPONLY, ...) - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(...) + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference + vulnerability_class: + - XML Injection + pattern: | + $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", + true); severity: WARNING - - fix: | - True - id: python.pyramid.audit.set-cookie-httponly-unsafe-value.pyramid-set-cookie-httponly-unsafe-value + - id: java_xxe_rule-XMLStreamRdr languages: - - python - message: Found a Pyramid cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - java + message: "External XML entities are a feature of XML parsers that allow \ndocuments to contain references to other documents or data. This \nfeature can be abused to read files, communicate with external\nhosts, exfiltrate data, or cause a Denial of Service (DoS).\nIn most XML parsers, the recommendation to protect against XXE is \nto disable the doctype feature.\nUnfortunately use of the `XMLInputFactory` requires that the doctypes \nfeature be enabled. Instead the application can set the `ACCESS_EXTERNAL_DTD` \nto an empty string and disable `javax.xml.stream.isSupportingExternalEntities`.\n\nSecure Code Example:\n```\n// Create an XMLInputFactory\nXMLInputFactory factory = XMLInputFactory.newFactory();\n// Set the ACCESS_EXTERNAL_DTD property to an empty string so it won't access\n// entities using protocols\n// (ref:\nhttps://docs.oracle.com/javase/8/docs/api/javax/xml/XMLConstants.html#ACCESS_EXTERNAL_DTD)\nfactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, \"\");\n// Additionally, disable support for resolving external entities\nfactory.setProperty(\"javax.xml.stream.isSupportingExternalEntities\", false);\n// Continue to work with the factory/stream parser\n```\n\nFor more information on XML security see OWASP's guide:\nhttps://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW - likelihood: LOW + cwe: CWE-611 owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/www-community/controls/SecureCookieAttribute - - https://owasp.org/www-community/HttpOnly - - https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#httponly-attribute - subcategory: - - vuln - technology: - - pyramid + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference ('XXE') patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(..., httponly=$HTTPONLY, ...) - - pattern: $HTTPONLY - - metavariable-pattern: - metavariable: $HTTPONLY - pattern: | - False + - pattern-not-inside: | + (javax.xml.stream.XMLInputFactory $FAC).setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + - pattern-not-inside: + patterns: + - pattern-either: + - pattern: | + (javax.xml.stream.XMLInputFactory $FAC).setProperty(XMLInputFactory.SUPPORT_DTD, $FALSE); + ... + - pattern: | + (javax.xml.stream.XMLInputFactory $FAC).setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, $FALSE); + ... + - pattern: | + (javax.xml.stream.XMLInputFactory $FAC).setProperty("javax.xml.stream.isSupportingExternalEntities", $FALSE); + ... + - metavariable-pattern: + metavariable: $FALSE + pattern-either: + - pattern: | + false + - pattern: | + Boolean.FALSE + - pattern: | + (javax.xml.stream.XMLInputFactory $FAC).createXMLStreamReader(...) severity: WARNING - - fix-regex: - regex: (.*)\) - replacement: \1, samesite='Lax') - id: python.pyramid.audit.set-cookie-samesite-unsafe-default.pyramid-set-cookie-samesite-unsafe-default + - id: javascript_exec_rule-child-process languages: - - python - message: Found a Pyramid cookie using an unsafe value for the samesite option. Pyramid cookies should be handled securely by setting samesite='Lax' in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - javascript + - typescript + message: | + OS command injection is a critical vulnerability that can lead to a full system + compromise as it may allow an adversary to pass in arbitrary commands or arguments + to be executed. + + User input should never be used in constructing commands or command arguments + to functions which execute OS commands. This includes filenames supplied by + user uploads or downloads. + + Ensure your application does not: + + - Use user-supplied information in the process name to execute. + - Use user-supplied information in an OS command execution function which does + not escape shell meta-characters. + - Use user-supplied information in arguments to OS commands. + + The application should have a hardcoded set of arguments that are to be passed + to OS commands. If filenames are being passed to these functions, it is + recommended that a hash of the filename be used instead, or some other unique + identifier. It is strongly recommended that a native library that implements + the same functionality be used instead of using OS system commands, due to the + risk of unknown attacks against third-party commands. + + When specifying the OS command, ensure the application uses the full path + information, otherwise the OS may attempt to look up which process to execute + and could be vulnerable to untrusted search path vulnerabilities (CWE-426). + + Example of safely executing an OS command: + ``` + const child_process = require('child_process'); + const fs = require('fs'); + const crypto = require('node:crypto'); + const { mkdtempSync } = require('node:fs'); + + function executeCommand(userFileData) { + // Create a temporary directory, preferably in an application directory + // that only the application has access to. + const fileDir = mkdtempSync('/tmp/tmpdir-'); + // Generate a random filename, do not use user input + const filePath = fileDir + path.sep + crypto.randomUUID(); + // Write the user-supplied data to the temporary file. + fs.writeFileSync(filePath, userFileData); + // Execute a program with a hardcoded path to the binary + child_process.exec(`/bin/cat ${filePath}`, (error, stdout, stderr) => { + // Delete the temporary directory and file if no longer needed + fs.rmSync(fileDir, { recursive: true, force: true }); + if (error) { + console.error(`exec error: ${error}`); + return; + } + console.log(`stdout: ${stdout}`); + console.error(`stderr: ${stderr}`); + }); + } + ``` + + For more information on OS command injection, see OWASP's guide: + https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html + + Detected non-literal calls to child_process.exec(). This could lead to a command + injection vulnerability. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' - impact: LOW - likelihood: LOW + cwe: CWE-78 + cwe2021-top25: true + cwe2022-top25: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A01:2021 - Broken Access Control + - A1:2017-Injection + - A03:2021-Injection references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control + - https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#do-not-use-dangerous-functions + security-severity: HIGH + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-child-process.js subcategory: - - vuln + - audit technology: - - pyramid - patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response + - javascript + vulnerability_class: + - Command Injection + mode: taint + options: + taint_unify_mvars: true + pattern-sanitizers: + - pattern: | + $CMD = "..." + - pattern: | + $CMD = ["...",...] + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $CP = require('child_process') ... - - pattern-inside: | - def $VIEW(...): + - pattern-inside: | + import * as $CP from 'child_process' ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + - pattern-inside: | + import $CP from 'child_process' ... - - pattern-not: $RESPONSE.set_cookie(..., samesite=$SAMESITE, ...) - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(...) - severity: WARNING - - fix: | - 'Lax' - id: python.pyramid.audit.set-cookie-samesite-unsafe-value.pyramid-set-cookie-samesite-unsafe-value + - pattern-either: + - pattern: $CP.exec($CMD,...) + - pattern: $CP.execSync($CMD,...) + - pattern: $CP.spawn($CMD,...) + - pattern: $CP.spawnSync($CMD,...) + - focus-metavariable: $CMD + pattern-sources: + - patterns: + - pattern-inside: | + function ... (...,$ARG,...) { + ... + } + - focus-metavariable: $ARG + severity: ERROR + - id: php_assert_rule-assert-use languages: - - python - message: Found a Pyramid cookie without the samesite option correctly set. Pyramid cookies should be handled securely by setting samesite='Lax' in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - php + message: Calling assert with user input is equivalent to eval'ing. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' - impact: LOW - likelihood: LOW + cwe: CWE-95 + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A01:2021 - Broken Access Control + - A1:2017-Injection + - A03:2021-Injection references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control + - https://www.php.net/manual/en/function.assert + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/AssertsSniff.php + security-severity: CRITICAL + shortDescription: Improper neutralization of directives in dynamically evaluated code ('Eval Injection') subcategory: - vuln technology: - - pyramid - patterns: + - php + vulnerability_class: + - Code Injection + mode: taint + pattern-sinks: + - patterns: + - pattern: assert($SINK, ...); + - pattern-not: assert("...", ...); + - pattern: $SINK + pattern-sources: - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(..., samesite=$SAMESITE, ...) - - pattern: $SAMESITE - - metavariable-regex: - metavariable: $SAMESITE - regex: (?!'Lax') - severity: WARNING - - fix-regex: - regex: (.*)\) - replacement: \1, secure=True) - id: python.pyramid.audit.set-cookie-secure-unsafe-default.pyramid-set-cookie-secure-unsafe-default + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - pattern: $_SERVER + - patterns: + - pattern: | + Route::$METHOD($ROUTENAME, function(..., $ARG, ...) { ... }) + - focus-metavariable: $ARG + severity: ERROR + - id: php_backticks_rule-backticks-use languages: - - python - message: Found a Pyramid cookie using an unsafe default for the secure option. Pyramid cookies should be handled securely by setting secure=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - php + message: Backticks use may lead to command injection vulnerabilities. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., secure=$SECURE, ...) - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(...) - severity: WARNING - - fix: | - True - id: python.pyramid.audit.set-cookie-secure-unsafe-value.pyramid-set-cookie-secure-unsafe-value + cwe: CWE-94 + cwe2022-top25: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + owasp: + - A1:2017-Injection + - A03:2021-Injection + references: + - https://www.php.net/manual/en/language.operators.execution.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/BackticksSniff.php + security-severity: CRITICAL + shortDescription: Improper control of generation of code ('Code Injection') + subcategory: + - audit + technology: + - php + vulnerability_class: + - Code Injection + pattern: '`...`;' + severity: ERROR + - id: php_crypto_rule-weak-crypto languages: - - python - message: Found a Pyramid cookie without the secure option correctly set. Pyramid cookies should be handled securely by setting secure=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + - php + message: Detected usage of weak crypto function. Consider using stronger alternatives. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW + cwe: CWE-328 + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A05:2021 - Security Misconfiguration + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + - https://www.php.net/manual/en/book.sodium.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php + security-severity: MEDIUM + shortDescription: Use of weak hash subcategory: - - vuln + - audit technology: - - pyramid + - php + vulnerability_class: + - Insecure Hashing Algorithm patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(..., secure=$SECURE, ...) - - pattern: $SECURE - - metavariable-pattern: - metavariable: $SECURE - pattern: | - False + - pattern: $FUNC(...); + - metavariable-regex: + metavariable: $FUNC + regex: crypt|md5|md5_file|sha1|sha1_file|str_rot13 severity: WARNING - - fix: | - True - id: python.pyramid.security.csrf-check-disabled-globally.pyramid-csrf-check-disabled-globally + - id: php_eval_rule-eval-use languages: - - python - message: Automatic check of cross-site request forgery tokens has been explicitly disabled globally, which might leave views unprotected. Use 'pyramid.config.Configurator.set_default_csrf_options(require_csrf=True)' to turn the automatic check for all unsafe methods (per RFC2616). + - php + message: Evaluating non-constant commands. This can lead to command injection. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe: CWE-78 cwe2021-top25: true cwe2022-top25: true - impact: LOW - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A01:2021 - Broken Access Control + - A1:2017-Injection + - A03:2021-Injection references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control + - https://www.php.net/manual/en/function.eval + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/NoEvalsSniff.php + security-severity: CRITICAL + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') subcategory: - - vuln + - audit technology: - - pyramid + - php + vulnerability_class: + - Command Injection patterns: - - pattern-inside: | - $CONFIG.set_default_csrf_options(..., require_csrf=$REQUIRE_CSRF, ...) - - pattern: $REQUIRE_CSRF - - metavariable-comparison: - comparison: $REQUIRE_CSRF == False - metavariable: $REQUIRE_CSRF + - pattern: eval(...); + - pattern-not: eval('...'); severity: ERROR - - id: python.pyramid.security.direct-use-of-response.pyramid-direct-use-of-response + - id: php_exec_rule-exec-use languages: - - python - message: Detected data rendered directly to the end user via 'Response'. This bypasses Pyramid's built-in cross-site scripting (XSS) defenses and could result in an XSS vulnerability. Use Pyramid's template engines to safely render HTML. + - php + message: Executing non-constant commands. This can lead to command injection. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true + cwe: CWE-94 cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A1:2017-Injection + - A03:2021-Injection references: - - https://owasp.org/Top10/A03_2021-Injection + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/SystemExecFunctionsSniff.php + security-severity: CRITICAL + shortDescription: Improper control of generation of code ('Code Injection') subcategory: - - vuln + - audit technology: - - pyramid - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - pyramid.request.Response.text($SINK) - - pattern: | - pyramid.request.Response($SINK) - - pattern: | - $REQ.response.body = $SINK - - pattern: | - $REQ.response.text = $SINK - - pattern: | - $REQ.response.ubody = $SINK - - pattern: | - $REQ.response.unicode_body = $SINK - - pattern: $SINK - pattern-sources: - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession + - php + vulnerability_class: + - Code Injection + patterns: + - pattern: $FUNC(...); + - pattern-not: $FUNC('...', ...); + - metavariable-regex: + metavariable: $FUNC + regex: exec|passthru|proc_open|popen|shell_exec|system|pcntl_exec severity: ERROR - - fix-regex: - regex: format - replacement: bindparams - id: python.pyramid.security.sqlalchemy-sql-injection.pyramid-sqlalchemy-sql-injection + - id: php_file_rule-file-inclusion languages: - - python - message: Distinct, Having, Group_by, Order_by, and Filter in SQLAlchemy can cause sql injections if the developer inputs raw SQL into the before-mentioned clauses. This pattern captures relevant cases in which the developer inputs raw SQL into the distinct, having, group_by, order_by or filter clauses and injects user-input into the raw SQL with any function besides "bindparams". Use bindParams to securely bind user-input to SQL statements. + - php + message: Detected non-constant file inclusion. This can lead to local file inclusion (LFI) or remote file inclusion (RFI) if user input reaches this statement. LFI and RFI could lead to sensitive files being obtained by attackers. Instead, explicitly specify what to include. If that is not a viable solution, validate user input thoroughly. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-98 + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A1:2017-Injection + - A03:2021-Injection references: - - https://docs.sqlalchemy.org/en/14/tutorial/data_select.html#tutorial-selecting-data + - https://www.php.net/manual/en/function.include.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/EasyRFISniff.php + - https://en.wikipedia.org/wiki/File_inclusion_vulnerability#Types_of_Inclusion + security-severity: CRITICAL + shortDescription: Improper control of filename for include/require statement in PHP program ('PHP Remote File Inclusion') subcategory: - - vuln + - audit technology: - - pyramid + - php + vulnerability_class: + - Code Injection mode: taint - pattern-sinks: + pattern-sanitizers: - patterns: - - pattern-inside: | - $QUERY = $REQ.dbsession.query(...) - ... - pattern-either: - - pattern: | - $QUERY.$SQLFUNC("...".$FORMATFUNC(..., $SINK, ...)) - - pattern: | - $QUERY.join(...).$SQLFUNC("...".$FORMATFUNC(..., $SINK, ...)) - - pattern: $SINK - - metavariable-regex: - metavariable: $SQLFUNC - regex: (group_by|order_by|distinct|having|filter) + - pattern-inside: basename($PATH, ...) + - pattern-inside: linkinfo($PATH, ...) + - pattern-inside: readlink($PATH, ...) + - pattern-inside: realpath($PATH, ...) + - pattern-inside: include_safe(...) + pattern-sinks: + - patterns: + - pattern-inside: $FUNC(...); + - pattern: $VAR - metavariable-regex: - metavariable: $FORMATFUNC - regex: (?!bindparams) + metavariable: $FUNC + regex: \b(include|include_once|require|require_once)\b pattern-sources: - patterns: - - pattern-inside: | - from pyramid.view import view_config - ... - @view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - pattern: $_SERVER severity: ERROR - - id: python.sqlalchemy.security.audit.avoid-sqlalchemy-text.avoid-sqlalchemy-text + - id: php_ftp_rule-ftp-use languages: - - python - message: sqlalchemy.text passes the constructed SQL statement to the database mostly unchanged. This means that the usual SQL injection protections are not applied and this function is vulnerable to SQL injection if user input can reach here. Use normal SQLAlchemy operators (such as or_, and_, etc.) to construct SQL. + - php + message: FTP allows for unencrypted file transfers. Consider using an encrypted alternative. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW + cwe: CWE-319 + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql + - https://www.php.net/manual/en/intro.ftp.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/FringeFunctionsSniff.php + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - audit technology: - - sqlalchemy - mode: taint - pattern-sinks: - - pattern: | - sqlalchemy.text(...) - pattern-sources: - - patterns: - - pattern: | - $X + $Y - - metavariable-type: - metavariable: $X - type: string - - patterns: - - pattern: | - $X + $Y - - metavariable-type: - metavariable: $Y - type: string - - patterns: - - pattern: | - f"..." - - patterns: - - pattern: | - $X.format(...) - - metavariable-type: - metavariable: $X - type: string - - patterns: - - pattern: | - $X % $Y - - metavariable-type: - metavariable: $X - type: string - severity: ERROR - - fix-regex: - regex: format - replacement: bindparams - id: python.sqlalchemy.security.sqlalchemy-sql-injection.sqlalchemy-sql-injection + - php + vulnerability_class: + - Mishandled Sensitive Information + patterns: + - pattern: $FUNC(...); + - metavariable-regex: + metavariable: $FUNC + regex: ftp_.+ + severity: WARNING + - id: php_mcrypt_rule-mcrypt-use languages: - - python - message: Distinct, Having, Group_by, Order_by, and Filter in SQLAlchemy can cause sql injections if the developer inputs raw SQL into the before-mentioned clauses. This pattern captures relevant cases in which the developer inputs raw SQL into the distinct, having, group_by, order_by or filter clauses and injects user-input into the raw SQL with any function besides "bindparams". Use bindParams to securely bind user-input to SQL statements. + - php + message: Mcrypt functionality has been deprecated and/or removed in recent PHP versions. Consider using Sodium or OpenSSL. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW + cwe: CWE-676 + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A9:2017-Using Components with Known Vulnerabilities + - A06:2021-Vulnerable and Outdated Components references: - - https://owasp.org/Top10/A03_2021-Injection + - https://www.php.net/manual/en/intro.mcrypt.php + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php + security-severity: MEDIUM + shortDescription: Use of potentially dangerous function subcategory: - - vuln + - audit technology: - - sqlalchemy + - php + vulnerability_class: + - Dangerous Method or Function patterns: - - pattern-either: - - pattern: | - def $FUNC(...,$VAR,...): - ... - $SESSION.query(...).$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) - - pattern: | - def $FUNC(...,$VAR,...): - ... - $SESSION.query.join(...).$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) - - pattern: | - def $FUNC(...,$VAR,...): - ... - $SESSION.query.$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) - - pattern: | - def $FUNC(...,$VAR,...): - ... - query.$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) + - pattern: $FUNC(...); - metavariable-regex: - metavariable: $SQLFUNC - regex: (group_by|order_by|distinct|having|filter) - - metavariable-regex: - metavariable: $FORMATFUNC - regex: (?!bindparams) + metavariable: $FUNC + regex: (mcrypt_|mdecrypt_).+ severity: WARNING - - id: python.twilio.security.twiml-injection.twiml-injection + - id: php_phpinfo_rule-phpinfo-use languages: - - python - message: Using non-constant TwiML (Twilio Markup Language) argument when creating a Twilio conversation could allow the injection of additional TwiML commands + - php + message: The 'phpinfo' function may reveal sensitive information about your environment. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-91: XML Injection' - impact: MEDIUM - likelihood: HIGH + cwe: CWE-497 + cwe2021-top25: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - - A03:2021 - Injection + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control references: - - https://codeberg.org/fennix/funjection - subcategory: vuln + - https://www.php.net/manual/en/function.phpinfo + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/PhpinfosSniff.php + security-severity: MEDIUM + shortDescription: Exposure of sensitive system information to an unauthorized control sphere + subcategory: + - vuln technology: - - python - - twilio - - twiml - mode: taint - pattern-sanitizers: - - pattern: xml.sax.saxutils.escape(...) - - pattern: html.escape(...) - pattern-sinks: - - patterns: - - pattern: | - $CLIENT.calls.create(..., twiml=$SINK, ...) - - focus-metavariable: $SINK - pattern-sources: - - pattern: | - f"..." - - pattern: | - "..." % ... - - pattern: | - "...".format(...) - - patterns: - - pattern: $ARG - - pattern-inside: | - def $F(..., $ARG, ...): - ... + - php + vulnerability_class: + - Mishandled Sensitive Information + pattern: phpinfo(...); severity: WARNING - - id: ruby.aws-lambda.security.activerecord-sqli.activerecord-sqli + - id: properties_spring_rule-SpringActuatorFullyEnabled languages: - - ruby - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `Example.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]`' + - generic + message: "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints\nsuch as /actuator/env, /actuator/logfile, /actuator/heapdump and others.\nIf the application lacks proper security measures (e.g., authentication and \nauthorization), sensitive data could be accessed, compromising the application and \nits infrastructure. This configuration poses a serious risk in production \nenvironments or public-facing deployments.\n\nTo mitigate the risks, take the following measures:\n - Expose only the Actuator endpoints required for your use case\n - For production environments, restrict exposure to non-sensitive endpoints \n like `health` or `info`\n - Ensure Actuator endpoints are protected with authentication and authorization \n (e.g., via Spring Security)\n - Use environment-specific configurations to limit exposure in production\n\nSecure Code Example:\nInstead of include: \"*\", list only the endpoints you need to expose:\n```\nmanagement.endpoints.web.exposure.include=\"health,info,metrics\"\n```\n\nReferences:\n- https://docs.spring.io/spring-boot/reference/actuator/endpoints.html#actuator.endpoints.exposing\n- https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785\n- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators\n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true + cwe: CWE-497 impact: HIGH likelihood: MEDIUM owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://guides.rubyonrails.org/active_record_querying.html#finding-by-sql - subcategory: - - vuln + - A01:2021-Broken Access Control + - A3:2017-Sensitive Data Exposure + security-severity: Medium + shortDescription: Exposure of sensitive system information to an unauthorized control sphere technology: - - aws-lambda - - active-record - mode: taint - pattern-sinks: - - patterns: - - pattern: $QUERY - - pattern-either: - - pattern: ActiveRecord::Base.connection.execute($QUERY,...) - - pattern: $MODEL.find_by_sql($QUERY,...) - - pattern: $MODEL.select_all($QUERY,...) - - pattern-inside: | - require 'active_record' - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context) - ... - end + - java + paths: + include: + - '*properties' + pattern: management.endpoints.web.exposure.include=* severity: WARNING - - id: ruby.aws-lambda.security.mysql2-sqli.mysql2-sqli + - id: python_crypto_rule-HTTPConnectionPool languages: - - ruby - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use sanitize statements like so: `escaped = client.escape(user_input)`' + - python + message: "The application is using HTTPConnectionPool method. This method transmits\ndata in cleartext, which is vulnerable to MITM (Man in the middle)\nattacks. In MITM attacks, the data transmitted over the unencrypted\nconnection can be intercepted, read and/or modified by unauthorized\nparties which can lead to data integrity and confidentiality loss. \n\nTo mitigate this issue, use HTTPSConnectionPool instead, which encrypts \ncommunications and enhances security.\n\nSecure Code Example:\n```\nimport urllib3\nspool = urllib3.connectionpool.HTTPSConnectionPool(\"example.com\")\n```\n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH + cwe: CWE-319 + impact: MEDIUM likelihood: MEDIUM owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://github.com/brianmario/mysql2 + - https://urllib3.readthedocs.io/en/1.2.1/pools.html#urllib3.connectionpool.HTTPSConnectionPool + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information subcategory: - - vuln + - audit technology: - - aws-lambda - - mysql2 - mode: taint - pattern-sanitizers: - - pattern: $CLIENT.escape(...) - pattern-sinks: - - patterns: - - pattern: $QUERY - - pattern-either: - - pattern: $CLIENT.query($QUERY,...) - - pattern: $CLIENT.prepare($QUERY,...) - - pattern-inside: | - require 'mysql2' - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context) - ... - end + - python + pattern-either: + - pattern: urllib3.HTTPConnectionPool(...) + - pattern: urllib3.connectionpool.HTTPConnectionPool(...) severity: WARNING - - id: ruby.aws-lambda.security.pg-sqli.pg-sqli + - id: python_django_rule-django-raw-used languages: - - ruby - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `conn.exec_params(''SELECT $1 AS a, $2 AS b, $3 AS c'', [1, 2, nil])`' + - python + message: "SQL Injections are a critical type of vulnerability that can lead to data \nor system compromise. By dynamically generating SQL query strings, user \ninput may be able to influence the logic of the SQL statement. \nThis could lead to an adversary accessing information they should not \nhave access to, or in some circumstances, being able to execute OS functionality\nor code.\n\nReplace all dynamically generated SQL queries with parameterized queries. \nIn situations where dynamic queries must be created, never use direct user input,\nbut instead use a map or dictionary of valid values and resolve them using a user \nsupplied key.\n\nFor example, some database drivers do not allow parameterized queries for \n`>` or `<` comparison operators. In these cases, do not use a user supplied \n`>` or `<` value, but rather have the user supply a `gt` or `lt` value. \nThe alphabetical values are then used to look up the `>` and `<` values to be used \nin the construction of the dynamic query. The same goes for other queries where \ncolumn or table names are required but cannot be parameterized.\n\nData that is possible user-controlled from a python request is passed\nto `raw()` function. To remediate this issue, use django's QuerySets, \nwhich are built with query parameterization and therefore not vulnerable \nto sql injection. For example, you could use `Entry.objects.filter(date=2006)`\n\nIf for some reason this is not feasible, ensure calls including user-supplied \ndata pass it in to the `params` parameter of the `raw()` method.\nBelow is an example using `raw()`, passing in user-supplied data as `params`. \nThis will treat the query as a parameterized query and `params` as strictly data, \npreventing any possibility of SQL Injection.\n\n```\ndef test(request):\n uname = request.GET[\"username\"] \n res = User.objects.raw('SELECT * FROM myapp_user WHERE username = %s', (uname,))\n```\n\nFor more information on QuerySet see:\n- https://docs.djangoproject.com/en/5.0/ref/models/querysets/\n\nFor more information on SQL Injection see OWASP:\n- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-89 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://www.rubydoc.info/gems/pg/PG/Connection - subcategory: - - vuln - technology: - - aws-lambda - - postgres - - pg + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an SQL Command ('SQL Injection') mode: taint pattern-sinks: - patterns: - pattern: $QUERY - - pattern-either: - - pattern: $CONN.exec($QUERY,...) - - pattern: $CONN.exec_params($QUERY,...) - - pattern: $CONN.exec_prepared($QUERY,...) - - pattern: $CONN.async_exec($QUERY,...) - - pattern: $CONN.async_exec_params($QUERY,...) - - pattern: $CONN.async_exec_prepared($QUERY,...) - - pattern-inside: | - require 'pg' - ... + - pattern-inside: $MODEL.objects.raw($QUERY, ... ) pattern-sources: - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context) - ... - end - severity: WARNING - - id: ruby.aws-lambda.security.sequel-sqli.sequel-sqli + - pattern: $PARAM + - pattern-inside: "def $VIEW(...,$PARAM,...):\n ...\n return ... \n" + severity: ERROR + - id: python_django_rule-django-rawsql-used languages: - - ruby - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `DB[''select * from items where name = ?'', name]`' + - python + message: "SQL Injections are a critical type of vulnerability that can lead to data or system compromise. By \ndynamically generating SQL query strings, user input may be able to influence the logic of the SQL \nstatement. This could lead to an adversary accessing information they should not have access to, or in\nsome circumstances, being able to execute OS functionality or code.\n\nReplace all dynamically generated SQL queries with parameterized queries. In situations where dynamic \nqueries must be created, never use direct user input, but instead use a map or dictionary of valid values \nand resolve them using a user supplied key.\n\nFor example, some database drivers do not allow parameterized queries for `>` or `<` comparison operators. \nIn these cases, do not use a user supplied `>` or `<` value, but rather have the user supply a `gt` or `lt` \nvalue. The alphabetical values are then used to look up the `>` and `<` values to be used in the \nconstruction of the dynamic query. The same goes for other queries where column or table names are required \nbut cannot be parameterized.\n\nTo remediate this issue, do not use `raw` or `RawSQL` but use other `QuerySet` methods to achieve the same\ngoals. If for some reason this is not feasible, ensure calls including user-supplied data pass it in to \nthe `params` parameter of the `RawSQL` method.\n\nWhile not recommended due to [potential SQL Injection](https://docs.djangoproject.com/en/5.0/ref/models/expressions/#raw-sql-expressions), below is an example using `RawSQL`.\nPassing in user-supplied data as a `param` which will escape the input:\n\n```\n# If dealing with integer based user input, restrict the values to integers only using the\n# path configuration: path('/someview/', views.some_view, name='someview'),\n\n# views.py\ndef some_view(request, user_supplied_id):\n # Never use string interpolation in the `sql` parameter.\n # Never quote the `%s` string format such as `... where id='%s'` as this could lead to SQL Injection.\n # Pass the user supplied data only in the `params` parameter.\n for obj in DBObject.objects.all().annotate(\n val=RawSQL(sql=\"select id from some_secondary_table where id=%s\", params=[user_supplied_id])):\n # Work with the results from the query\n # ...\n```\n\nFor more information on QuerySets see:\n- https://docs.djangoproject.com/en/4.2/ref/models/querysets/#queryset-api\n\nFor more information on SQL Injection see OWASP:\n- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-89 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/jeremyevans/sequel#label-Arbitrary+SQL+queries - subcategory: - - vuln - technology: - - aws-lambda - - sequel + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of special elements used in an SQL Command ('SQL Injection') mode: taint pattern-sinks: - patterns: - pattern: $QUERY - - pattern-either: - - pattern: DB[$QUERY,...] - - pattern: DB.run($QUERY,...) - - pattern-inside: | - require 'sequel' - ... + - pattern-inside: django.db.models.expressions.RawSQL($QUERY, ... ) pattern-sources: - patterns: - - pattern: event + - pattern: $PARAM - pattern-inside: | - def $HANDLER(event, context) + def $VIEW(...,$PARAM,...): ... - end + return ... + severity: ERROR + - id: python_escaping_rule-django + languages: + - python + message: | + Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat + user input + as markup or script code. It is important to encode the data depending on the specific context + it + is used in. There are at least six context types: + + - Inside HTML tags `
context 1
` + - Inside attributes: `
` + - Inside event attributes `` + - Inside script blocks: `` + - Unsafe element HTML assignment: `element.innerHTML = "context 5"` + - Inside URLs: `link` + + Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if + user input + is ever output inside of script tags. + + User input that is displayed within the application must be encoded, sanitized or validated + to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be + taken + to not mix server-side templating with client-side templating, as the server-side templating + will + not encode things like {{ 7*7 }} which may execute client-side templating features. + + It is _NOT_ advised to encode user input prior to inserting into a data store. The data will + need to be + encoded depending on context of where it is output. It is much safer to force the displaying + system to + handle the encoding and not attempt to guess how it should be encoded. + + Consider using + [format_html](https://docs.djangoproject.com/en/4.2/ref/utils/#django.utils.html.format_html) + instead of + the `django.utils.safestring` methods. + + Example using `format_html`: + ``` + # Use format_html to create an HTML link, using href as the parameter + # which will be encoded automatically + format_html("
  • Some Link
  • ", href) + ``` + + For more information on XSS see OWASP: + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + metadata: + category: security + cwe: CWE-79 + owasp: + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + patterns: + - pattern-not-inside: django.utils.html.format_html(...) + - pattern-either: + - patterns: + - pattern: django.utils.safestring.SafeText(...) + - pattern-not: django.utils.safestring.SafeText("...") + - patterns: + - pattern: django.utils.safestring.SafeUnicode(...) + - pattern-not: django.utils.safestring.SafeUnicode("...") + - patterns: + - pattern: django.utils.safestring.SafeString(...) + - pattern-not: django.utils.safestring.SafeString("...") + - patterns: + - pattern: django.utils.safestring.SafeBytes(...) + - pattern-not: django.utils.safestring.SafeBytes("...") + - patterns: + - pattern: django.utils.safestring.mark_safe(...) + - pattern-not: django.utils.safestring.mark_safe("...") severity: WARNING - - id: ruby.aws-lambda.security.tainted-deserialization.tainted-deserialization + - id: python_flask_rule-path-traversal-open languages: - - ruby - message: Deserialization of a string tainted by `event` object found. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of `load` can cause remote code execution. Loading user input with MARSHAL, YAML or CSV can potentially be dangerous. If you need to deserialize untrusted data, you should use JSON as it is only capable of returning 'primitive' types such as strings, arrays, hashes, numbers and nil. + - python + message: "Found request data in a call to 'open'. An attacker can manipulate this input to access files outside the intended \ndirectory. This can lead to unauthorized access to sensitive files or directories. To prevent path traversal attacks, \navoid using user-controlled input in file paths. If you must use user-controlled input, validate and sanitize the \ninput to ensure it does not contain any path traversal sequences. For example, you can use the `os.path.join` function \nto safely construct file paths or validate that the absolute path starts with the directory which is whitelisted for \naccessing file. The following code snippet demonstrates how to validate a file path from user-controlled input:\n```\nimport os\n\ndef safe_open_file(filename, base_path):\n # Resolve the absolute path of the user-supplied filename\n absolute_path = os.path.abspath(filename)\n\n # Check that the absolute path starts with the base path\n if not absolute_path.startswith(base_path):\n raise ValueError(\"Invalid file path\")\n\n return open(absolute_path, 'r')\n```\nFor more information, see the OWASP Path Traversal page: https://owasp.org/www-community/attacks/Path_Traversal\n" metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true + cwe: CWE-22 impact: HIGH likelihood: MEDIUM owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control references: - - https://ruby-doc.org/core-3.1.2/doc/security_rdoc.html - - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb - subcategory: - - vuln + - https://owasp.org/www-community/attacks/Path_Traversal + security-severity: CRITICAL + shortDescription: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') technology: - - ruby - - aws-lambda - mode: taint - pattern-sinks: + - flask + pattern-either: - patterns: - - pattern: $SINK + - pattern: open(...) - pattern-either: - pattern-inside: | - YAML.load($SINK,...) - - pattern-inside: | - CSV.load($SINK,...) + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + open(..., <... $ROUTEVAR ...>, ...) - pattern-inside: | - Marshal.load($SINK,...) + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + with open(..., <... $ROUTEVAR ...>, ...) as $FD: + ... - pattern-inside: | - Marshal.restore($SINK,...) - pattern-sources: + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + $INTERIM = <... $ROUTEVAR ...> + ... + open(..., <... $INTERIM ...>, ...) + - pattern: open(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: open(..., <... flask.request.$W[...] ...>, ...) + - pattern: open(..., <... flask.request.$W(...) ...>, ...) + - pattern: open(..., <... flask.request.$W ...>, ...) - patterns: - - pattern: event - pattern-inside: | - def $HANDLER(event, context) + $INTERIM = <... flask.request.$W.get(...) ...> + ... + open(<... $INTERIM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERIM = <... flask.request.$W[...] ...> + ... + open(<... $INTERIM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERIM = <... flask.request.$W(...) ...> + ... + open(<... $INTERIM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERIM = <... flask.request.$W ...> + ... + open(<... $INTERIM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERIM = <... flask.request.$W.get(...) ...> + ... + with open(<... $INTERIM ...>, ...) as $F: ... - end - severity: WARNING - - id: ruby.aws-lambda.security.tainted-sql-string.tainted-sql-string - languages: - - ruby - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://rorsecurity.info/portfolio/ruby-on-rails-sql-injection-cheat-sheet - subcategory: - - vuln - technology: - - aws-lambda - mode: taint - pattern-sinks: + - pattern: open(...) - patterns: - - pattern-either: - - patterns: - - pattern: | - "...#{...}..." - - pattern-regex: (?i)(select|delete|insert|create|update|alter|drop)\b|\w+\s*!?[<>=].* - - patterns: - - pattern-either: - - pattern: Kernel::sprintf("$SQLSTR", ...) - - pattern: | - "$SQLSTR" + $EXPR - - pattern: | - "$SQLSTR" % $EXPR - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b|\w+\s*!?[<>=].* - - pattern-not-inside: | - puts(...) - pattern-sources: + - pattern-inside: | + $INTERIM = <... flask.request.$W[...] ...> + ... + with open(<... $INTERIM ...>, ...) as $F: + ... + - pattern: open(...) - patterns: - - pattern: event - pattern-inside: | - def $HANDLER(event, context) + $INTERIM = <... flask.request.$W(...) ...> + ... + with open(<... $INTERIM ...>, ...) as $F: ... - end + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERIM = <... flask.request.$W ...> + ... + with open(<... $INTERIM ...>, ...) as $F: + ... + - pattern: open(...) severity: ERROR - - id: ruby.lang.security.bad-deserialization.bad-deserialization + - id: python_flask_rule-tainted-sql-string languages: - - ruby - message: Checks for unsafe deserialization. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of load and object_load can cause remote code execution. Loading user input with MARSHAL or CSV can potentially be dangerous. Use JSON in a secure fashion instead. + - python + message: "Detected user input used to manually construct a SQL string. This is usually\nbad practice because manual construction could accidentally result in a SQL\ninjection. An attacker could use a SQL injection to steal or modify contents\nof the database. Instead, use a parameterized query which is available\nby default in most database engines. Alternatively, consider using an\nobject-relational mapper (ORM) such as SQLAlchemy which will protect your queries.\n\nSQL Injections are a critical type of vulnerability that can lead to data \nor system compromise. By dynamically generating SQL query strings, user \ninput may be able to influence the logic of an SQL statement. \nThis could lead to an malicious parties accessing information they should not \nhave access to, or in some circumstances, being able to execute OS functionality\nor code.\n\nReplace all dynamically generated SQL queries with parameterized queries. \nIn situations where dynamic queries must be created, never use direct user input,\nbut instead use a map or dictionary of valid values and resolve them using a user \nsupplied key.\n\nFor example, some database drivers do not allow parameterized queries for \n`>` or `<` comparison operators. In these cases, do not use a user supplied \n`>` or `<` value, but rather have the user supply a `gt` or `lt` value. \nThe alphabetical values are then used to look up the `>` and `<` values to be used \nin the construction of the dynamic query. The same goes for other queries where \ncolumn or table names are required but cannot be parameterized.\nData that is possible user-controlled from a python request is passed\nto `execute()` function. To remediate this issue, use SQLAlchemy statements\nwhich are built with query parameterization and therefore not vulnerable \nto sql injection.\n\nIf for some reason this is not feasible, ensure calls including user-supplied \ndata pass it in to the `params` parameter of the `execute()` method.\nBelow is an example using `execute()`, passing in user-supplied data as `params`. \nThis will treat the query as a parameterized query and `params` as strictly data, \npreventing any possibility of SQL Injection.\n\n```\nname = request.args.get('name')\nreq = text('SELECT * FROM student WHERE firstname = :x')\nresult = db.session.execute(req, {\"x\":name})\n```\nFor more information on QuerySets see:\n- https://docs.djangoproject.com/en/4.2/ref/models/querysets/#queryset-api\nFor more information on SQL Injections see OWASP:\n- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-89 owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb - subcategory: - - vuln - technology: - - ruby + - A1:2017-Injection + - A03:2021-Injection + security-severity: High + shortDescription: Improper neutralization of special elements used in an SQL Command ('SQL Injection') mode: taint pattern-sinks: - - pattern-either: - - pattern: | - CSV.load(...) - - pattern: | - Marshal.load(...) - - pattern: | - Marshal.restore(...) - - pattern: | - Oj.object_load(...) - - pattern: | - Oj.load($X) + - patterns: + - pattern-either: + - pattern: | + <... "$QUERYLIKE" ...> + - metavariable-regex: + metavariable: $QUERYLIKE + regex: .*\b(?i)(SELECT .+ FROM|WHERE|DELETE FROM|INSERT INTO| CREATE TABLE|UPDATE .+ SET|ALTER TABLE|ALTER COLUMN|DROP COLUMN|DROP TABLE|ORDER BY)\b.* pattern-sources: - pattern-either: - - pattern: params - - pattern: cookies + - pattern: flask.request.$ANYTHING + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR severity: ERROR - - id: ruby.lang.security.dangerous-exec.dangerous-exec + - id: python_flask_rule-flask-open-redirect languages: - - ruby - message: Detected non-static command inside $EXEC. Audit the input to '$EXEC'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + - python + message: |- + Data from request is passed to redirect(). This is an open redirect and could be exploited. Consider using 'url_for()' to generate links to known locations. If you must use a URL to unknown pages, consider using 'urlparse()' or similar and checking if the 'netloc' property is the same as your site's host name. For example: + + Example: + ```python + from flask import Flask, request, redirect, url_for + from urllib.parse import urlparse + + app = Flask(__name__) + + @app.route('/login') + def login(): + next = request.args.get('next') + if not next: + next = url_for('index') + if urlparse(next).netloc != urlparse(request.url).netloc: + return redirect(url_for('index')) + return redirect(next) + ``` + See the references for more information. + metadata: + category: security + confidence: LOW + cwe: CWE-601 + impact: MEDIUM + likelihood: LOW owasp: - - A03:2021 - Injection - references: - - https://guides.rubyonrails.org/security.html#command-line-injection - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_execute.rb + - A01:2021-Broken Access Control + - A5:2017-Broken Access Control + references: | + - https://flask-login.readthedocs.io/en/latest/#login-example + - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html#dangerous-url-redirect-example-1 + - https://docs.python.org/3/library/urllib.parse.html#url-parsing + security-severity: MEDIUM + shortDescription: URL redirection to untrusted site ('Open Redirect') subcategory: - - vuln + - audit technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: + - flask + patterns: + - pattern-inside: | + @$APP.route(...) + def $X(...): + ... + - pattern-not-inside: | + @$APP.route(...) + def $X(...): + ... + if <... werkzeug.urls.url_parse($V) ...>: + ... + - pattern-either: + - pattern: flask.redirect(<... flask.request.$W.get(...) ...>, ...) + - pattern: flask.redirect(<... flask.request.$W[...] ...>, ...) + - pattern: flask.redirect(<... flask.request.$W(...) ...>, ...) + - pattern: flask.redirect(<... flask.request.$W ...>, ...) - pattern: | - $EXEC(...) - - pattern-not: | - $EXEC("...","...","...",...) - - pattern-not: | - $EXEC(["...","...","...",...],...) - - pattern-not: | - $EXEC({...},"...","...","...",...) - - pattern-not: | - $EXEC({...},["...","...","...",...],...) - - metavariable-regex: - metavariable: $EXEC - regex: ^(system|exec|spawn|Process.exec|Process.spawn|Open3.capture2|Open3.capture2e|Open3.capture3|Open3.popen2|Open3.popen2e|Open3.popen3|IO.popen|Gem::Util.popen|PTY.spawn)$ - pattern-sources: - - patterns: + $V = flask.request.$W.get(...) + ... + flask.redirect(<... $V ...>, ...) - pattern: | - def $F(...,$ARG,...) - ... - end - - focus-metavariable: $ARG - - pattern: params - - pattern: cookies + $V = flask.request.$W[...] + ... + flask.redirect(<... $V ...>, ...) + - pattern: | + $V = flask.request.$W(...) + ... + flask.redirect(<... $V ...>, ...) + - pattern: | + $V = flask.request.$W + ... + flask.redirect(<... $V ...>, ...) + - pattern-not: flask.redirect(flask.request.path) + - pattern-not: flask.redirect(flask.request.path + ...) + - pattern-not: flask.redirect(f"{flask.request.path}...") severity: WARNING - - id: ruby.lang.security.divide-by-zero.divide-by-zero + - id: python_jwt_rule-jwt-none-alg languages: - - ruby - message: Detected a possible ZeroDivisionError. + - python + message: | + Detected use of the 'none' algorithm in a JWT token. + The 'none' algorithm assumes the integrity of the token has already + been verified. This would allow a malicious actor to forge a JWT token + that will automatically be verified. Do not explicitly use the 'none' + algorithm. Instead, use an algorithm such as 'HS256'. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-369: Divide By Zero' + cwe: CWE-327 impact: MEDIUM likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_divide_by_zero.rb + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + security-severity: MEDIUM + shortDescription: Use of a Broken or Risky Cryptographic Algorithm + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ subcategory: - vuln technology: - - ruby - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: $NUMER / 0 - - pattern: $NUMER - pattern-sources: - - patterns: - - pattern: $VAR - - metavariable-regex: - metavariable: $VAR - regex: ^\d*(?!\.)$ - severity: WARNING - - fix-regex: - regex: =\s*false - replacement: = true - id: ruby.lang.security.force-ssl-false.force-ssl-false + - jwt + pattern-either: + - pattern: jwt.encode(...,algorithm="none",...) + - pattern: jwt.decode(...,algorithms=[...,"none",...],...) + severity: ERROR + - id: python_pyramid_rule-pyramid-csrf-origin-check languages: - - ruby - message: Checks for configuration setting of force_ssl to false. Force_ssl forces usage of HTTPS, which could lead to network interception of unencrypted application traffic. To fix, set config.force_ssl = true. + - python + message: "Automatic check of the referrer for cross-site request forgery tokens\nhas been explicitly disabled globally, which might leave views unprotected\nwhen an unsafe CSRF storage policy is used. By passing `check_origin=False` \nto `set_default_csrf_options()` method, you opt out of checking the origin \nof the domain in the referrer header or the origin header, which can make \nthe application vulnerable to CSRF attacks, specially if CSRF token is not \nproperly implemented.\nCSRF attacks are a type of exploit where an attacker tricks a user into \nexecuting unwanted actions on a web application in which they are authenticated. \nIf a user is logged into a web application, an attacker could create a malicious \nlink or script on another site that causes the user's browser to make a request \nto the web application, carrying out an action without the user's consent.\n\nTo mitigate this vulnerability, use \n'pyramid.config.Configurator.set_default_csrf_options(check_origin=True)'\nto turn the automatic check for all unsafe methods (per RFC2616).\n\nSecure Code Example:\n```\ndef safe(config):\n config.set_csrf_storage_policy(CookieCSRFStoragePolicy())\n config.set_default_csrf_options(check_origin=True)\n```\n" metadata: category: security - confidence: HIGH - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: MEDIUM + confidence: MEDIUM + cwe: CWE-352 + cwe2021-top25: "true" + cwe2022-top25: "true" + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_force_ssl.rb + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + - https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/security.html + security-severity: MEDIUM + shortDescription: Cross-site request forgery (CSRF) subcategory: - vuln technology: - - ruby - pattern: config.force_ssl = false - severity: WARNING - - id: ruby.lang.security.hardcoded-http-auth-in-controller.hardcoded-http-auth-in-controller - languages: - - ruby - message: Detected hardcoded password used in basic authentication in a controller class. Including this password in version control could expose this credential. Consider refactoring to use environment variables or configuration files. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/basic_auth/index.markdown - subcategory: - - audit - technology: - - ruby - - secrets + - pyramid + vulnerability_class: + - Cross-Site Request Forgery (CSRF) patterns: - pattern-inside: | - class $CONTROLLER < ApplicationController - ... - http_basic_authenticate_with ..., :password => "$SECRET", ... - end - - focus-metavariable: $SECRET + $CONFIG.set_default_csrf_options(..., check_origin=$CHECK_ORIGIN, ...) + - pattern: | + $CHECK_ORIGIN + - metavariable-comparison: + comparison: $CHECK_ORIGIN == False + metavariable: $CHECK_ORIGIN severity: WARNING - - id: ruby.lang.security.hardcoded-secret-rsa-passphrase.hardcoded-secret-rsa-passphrase + - id: ruby_cookie_rule-CheckCookieStoreSessionSecurityAttributes languages: - ruby - message: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file. + message: "The detected issue pertains to a Rails application where the session \nconfiguration, specifically using cookie_store, has been identified \nwith the $KEY attribute set to false. This setting is potentially \ninsecure because it may relate to crucial security attributes such \nas HttpOnly or Secure flags not being enforced. In the context of \nweb applications, these flags play a vital role in enhancing session \nsecurity:\n\n- HttpOnly Flag: When enabled, this flag prevents client-side scripts\nfrom accessing the cookie. This mitigation is crucial for reducing \nthe risk of cross-site scripting (XSS) attacks, where an attacker \nmight attempt to steal session cookies.\n- Secure Flag: This flag ensures that cookies are sent over secure, \nencrypted connections only (HTTPS). It's a critical security measure \nthat helps prevent cookies from being intercepted by attackers when \ntransmitted over an unencrypted connection.\n\nTo mitigate the identified security risk and ensure that your Rails \napplication's session cookies are securely configured. \n\nSecure Code Example:\n```\n# config/initializers/session_store.rb\nRails.application.config.session_store :cookie_store, key: '_your_app_session',\n httponly: true,\n secure: Rails.env.production?\n```\n" metadata: category: security - confidence: HIGH - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-1004 owasp: - - A07:2021 - Identification and Authentication Failures + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration references: - - https://cwe.mitre.org/data/definitions/522.html - subcategory: - - vuln + - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-cookie-store-session-security-attributes.yaml + security-severity: LOW + shortDescription: Sensitive cookie without 'HttpOnly' and 'Secure' flags technology: - ruby - - secrets + - rails patterns: - pattern-either: - - pattern: OpenSSL::PKey::RSA.new(..., '...') - - pattern: OpenSSL::PKey::RSA.new(...).to_pem(..., '...') - - pattern: OpenSSL::PKey::RSA.new(...).export(..., '...') - patterns: + - pattern: | + :$KEY => false - pattern-inside: | - $OPENSSL = OpenSSL::PKey::RSA.new(...) - ... - - pattern-either: - - pattern: | - $OPENSSL.export(...,'...') - - pattern: | - $OPENSSL.to_pem(...,'...') - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $ASSIGN = '...' - ... - - pattern: OpenSSL::PKey::RSA.new(..., $ASSIGN) - - patterns: - - pattern-inside: | - def $METHOD1(...) - ... - $ASSIGN = '...' - ... - end - ... - def $METHOD2(...) - ... - end - - pattern: OpenSSL::PKey::RSA.new(..., $ASSIGN) - - patterns: - - pattern-inside: | - $ASSIGN = '...' - ... - def $METHOD(...) - $OPENSSL = OpenSSL::PKey::RSA.new(...) - ... - end - ... - - pattern-either: - - pattern: $OPENSSL.export(...,$ASSIGN) - - pattern: $OPENSSL.to_pem(...,$ASSIGN) - - patterns: - - pattern-inside: | - def $METHOD1(...) - ... - $OPENSSL = OpenSSL::PKey::RSA.new(...) - ... - $ASSIGN = '...' - ... - end - ... - - pattern-either: - - pattern: $OPENSSL.export(...,$ASSIGN) - - pattern: $OPENSSL.to_pem(...,$ASSIGN) - - patterns: - - pattern-inside: | - def $METHOD1(...) - ... - $ASSIGN = '...' - ... - end - ... - def $METHOD2(...) - ... - $OPENSSL = OpenSSL::PKey::RSA.new(...) - ... - end - ... - - pattern-either: - - pattern: $OPENSSL.export(...,$ASSIGN) - - pattern: $OPENSSL.to_pem(...,$ASSIGN) - severity: WARNING - - id: ruby.lang.security.insufficient-rsa-key-size.insufficient-rsa-key-size + ActionController::Base.session = {...} + - pattern: | + $MODULE::Application.config.session_store :cookie_store, ..., :$KEY => false, ... + - pattern: | + $CLASS.application.config.session_store :cookie_store, ..., $KEY: false, ... + - metavariable-regex: + metavariable: $KEY + regex: ^(session_)?(http_?only|secure)$ + severity: INFO + - id: ruby_cookie_rule-CookieSerialization + languages: + - ruby + message: "The rule warns of a significant security risk in applications that use \nRuby's Marshal module for deserializing cookies. Marshal can serialize \nand deserialize Ruby objects, which, while powerful, poses a risk if \nmisused. If an attacker crafts a malicious cookie that is deserialized, \nit could lead to remote code execution (RCE) on the server due to \nMarshal.load's ability to execute code in deserialized objects. To mitigate \nthis risk, developers are advised to switch from Marshal to JSON for cookie \nserialization. JSON is safer as it cannot execute arbitrary code, reducing \nthe threat of RCE vulnerabilities from deserialized user data. The hybrid \ncheck is just to warn users to migrate to :json for best practice.\n\nSecure code example:\n```\n# In Rails, configure the cookie serializer to :json\n# config/initializers/cookies_serializer.rb\nRails.application.config.action_dispatch.cookies_serializer = :json\n```\n\nAdditionally, always validate and sanitize user-supplied data as much \nas possible, even when using JSON, to further secure your application \nagainst various injection attacks.\n" + metadata: + category: security + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + references: + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/cookie-serialization.yaml + - https://robertheaton.com/2013/07/22/how-to-hack-a-rails-app-using-its-secret-token/ + security-severity: HIGH + shortDescription: Improper control of generation of code ('Code Injection') + technology: + - ruby + pattern-either: + - pattern: | + Rails.application.config.action_dispatch.cookies_serializer = :marshal + - pattern: | + Rails.application.config.action_dispatch.cookies_serializer = :hybrid + severity: ERROR + - id: ruby_crypto_rule-InsufficientRSAKeySize languages: - ruby - message: The RSA key size $SIZE is insufficent by NIST standards. It is recommended to use a key length of 2048 or higher. + message: "The RSA key size $SIZE is insufficent by NIST standards. It is \nrecommended to use a key length of 2048 or higher. The RSA algorithm, \nbeing widely used for secure data transmission, relies on key size \nfor its security. Smaller key sizes (e.g., 1024 bits and below) are \nmore susceptible to brute-force attacks, where an attacker uses \ncomputational power to decrypt data or forge signatures. \n\nTo address this security concern, ensure that all RSA keys are \ngenerated with a size of 2048 bits or more.\n\nFolowing is a secure code example:\n```\nrequire 'openssl'\n\n# Generate a new RSA key of 2048 bits\nrsa_key = OpenSSL::PKey::RSA.new(2048)\n\n# To export the RSA key\nprivate_key = rsa_key.to_pem\npublic_key = rsa_key.public_key.to_pem\n```\n" metadata: category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: HIGH + cwe: CWE-326 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/insufficient-rsa-key-size.yaml - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf - subcategory: - - vuln + security-severity: MEDIUM + shortDescription: Inadequate encryption strength technology: - ruby patterns: @@ -25454,227 +92407,337 @@ rules: comparison: $SIZE < 2048 metavariable: $SIZE severity: WARNING - - id: ruby.lang.security.md5-used-as-password.md5-used-as-password + - id: ruby_crypto_rule-WeakHashesMD5 languages: - ruby - message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Instead, use a suitable password hashing function such as bcrypt. You can use the `bcrypt` gem. + message: "The MD5 hashing algorithm is considered cryptographically weak and \nvulnerable to collision attacks, where two different inputs generate \nthe same output hash. When used for hashing sensitive data, attackers \ncan exploit this weakness to generate collisions, allowing them to bypass \nsecurity checks or masquerade malicious data as legitimate. This \nvulnerability is particularly critical in authentication mechanisms, \ndigital signatures, SSL/TLS certificates, and data integrity checks.\n\nRemediation:\nTo mitigate this vulnerability, replace the MD5 hashing algorithm with \nstronger cryptographic hash functions, such as SHA-256 or SHA-3. These \nalgorithms offer significantly improved security and are resistant to \ncollision attacks, making them suitable for cryptographic purposes in \nmodern applications.\n\nSecure Code example:\n```\nrequire 'openssl'\n\ndata = \"sensitive information\"\n# Using SHA-256\ndigest = OpenSSL::Digest::SHA256.new\nhash = digest.digest(data)\nhex_hash = digest.hexdigest(data)\n\n# Using SHA-3 (256 bits)\ndigest = OpenSSL::Digest::SHA3.new(256)\nhash2 = digest.digest(data)\nhex_hash2 = digest.hexdigest(data)\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: HIGH + cwe: CWE-328 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html - - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords - - https://github.com/returntocorp/semgrep-rules/issues/1609 - subcategory: - - vuln + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/weak-hashes-md5.yaml + - https://www.ibm.com/support/pages/security-bulletin-vulnerability-md5-signature-and-hash-algorithm-affects-sterling-integrator-and-sterling-file-gateway-cve-2015-7575 + security-severity: MEDIUM + shortDescription: Use of weak hash technology: - - md5 - mode: taint - pattern-sinks: - - patterns: - - pattern: $FUNCTION(...); - - metavariable-regex: - metavariable: $FUNCTION - regex: (?i)(.*password.*) - pattern-sources: - - pattern: Digest::MD5 + - ruby + pattern-either: + - pattern: Digest::MD5.base64digest $X + - pattern: Digest::MD5.hexdigest $X + - pattern: Digest::MD5.digest $X + - pattern: Digest::MD5.new + - pattern: OpenSSL::Digest::MD5.base64digest $X + - pattern: OpenSSL::Digest::MD5.hexdigest $X + - pattern: OpenSSL::Digest::MD5.digest $X + - pattern: OpenSSL::Digest::MD5.new severity: WARNING - - id: ruby.lang.security.no-eval.ruby-eval + - id: ruby_crypto_rule-WeakHashesSHA1 languages: - ruby - message: Use of eval with user-controllable input detected. This can lead to attackers running arbitrary code. Ensure external data does not reach here, otherwise this is a security vulnerability. Consider other ways to do this without eval. + message: "The SHA-1 hashing algorithm is no longer considered secure for\ncryptographic applications due to its vulnerability to collision attacks,\nwhere two different inputs produce the same output hash. SHA-1's\nsusceptibility to collision attacks undermines the security of\ncryptographic operations, allowing attackers to forge signatures or\nmanipulate data without detection. This poses significant risks in\nauthentication systems, data integrity validations, and secure\ncommunications. \n\nRemediation: To mitigate this vulnerability, replace the SHA1 hashing \nalgorithm with stronger cryptographic hash functions, such as SHA-256 \nor SHA-3. These algorithms offer significantly improved security and \nare resistant to collision attacks, making them suitable for cryptographic \npurposes in modern applications.\n\nSecure Code example : \n``` \nrequire 'openssl'\n\ndata = \"sensitive information\"\n# Using SHA-256\ndigest = OpenSSL::Digest::SHA256.new\nhash = digest.digest(data)\nhex_hash = digest.hexdigest(data)\n\n# Using SHA-3 (256 bits)\ndigest = OpenSSL::Digest::SHA3.new(256)\nhash2 = digest.digest(data)\nhex_hash2 = digest.hexdigest(data)\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-328 owasp: - - A03:2021 - Injection + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_evaluation.rb - subcategory: - - vuln + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/weak-hashes-sha1.yaml + - https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html + - https://shattered.io/ + security-severity: MEDIUM + shortDescription: Use of weak hash + technology: + - ruby + pattern-either: + - pattern: Digest::SHA1.$FUNC + - pattern: OpenSSL::Digest::SHA1.$FUNC + - pattern: OpenSSL::HMAC.$FUNC("sha1",...) + severity: WARNING + - id: ruby_csrf_rule-MissingCSRFProtection + languages: + - ruby + message: "Detected controller which does not enable cross-site request forgery\nprotections using `protect_from_forgery`. When a Rails application does \nnot use `protect_from_forgery` in its controllers, it is vulnerable to \nCSRF attacks. This vulnerability can allow attackers to submit unauthorized \nrequests on behalf of authenticated users, potentially leading to \nunauthorized actions being performed. \nTo mitigate this risk, Rails offers the `protect_from_forgery` method, \nwhich integrates CSRF token verification in every form submitted to \nyour application, ensuring that requests are legitimate. \nAdd `protect_from_forgery with: :exception` to your controller class. \nThe `with: :exception` option configures Rails to raise an exception \nif a CSRF token cannot be verified, providing an additional layer of security. \nThis approach ensures that unverified requests do not proceed silently, \nallowing for appropriate error handling and response measures.\n\nSecure Code Example:\n```\nclass YourController < ApplicationController\n protect_from_forgery with: :exception\n # Your controller actions here\nend\n```\nFor more information on CSRF, see OWASP guide:\nhttps://owasp.org/www-community/attacks/csrf\n" + metadata: + category: security + cwe: CWE-352 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + references: + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/missing-csrf-protection.yaml + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + security-severity: MEDIUM + shortDescription: Cross-site request forgery (CSRF) + technology: + - ruby + patterns: + - pattern: | + class $CONTROLLER < ActionController::Base + ... + end + - pattern-not: | + class $CONTROLLER < ActionController::Base + ... + protect_from_forgery + end + severity: WARNING + - id: ruby_deserialization_rule-BadDeserialization + languages: + - ruby + message: "In Ruby, objects can be serialized into strings using various methods \nand later reconstituted into objects. The `load` and `object_load` \nmethods, associated with modules like Marshal and CSV, is particularly \nrisky when used to deserialize data from untrusted sources. \nIf an attacker is able to manipulate the serialized data, they could \nexecute arbitrary code on the system when the data is deserialized. \nThis vulnerability can lead to remote code execution (RCE), where an \nattacker gains the ability to execute commands on the host machine. \nThe Marshal and CSV modules are often used for serialization and \ndeserialization in Ruby but they do not inherently sanitize or validate \nthe data being processed. This makes them unsafe for handling input from \nuntrusted sources.\n\nTo mitigate the risks associated with unsafe deserialization, it is \nrecommended to:\n- Avoid deserializing from untrusted sources\n- Use JSON for serialization/deserialization as JSON is considered \nsafer for data interchange between systems. However, it's crucial \nto use JSON securely by validating and sanitizing the input before \ndeserialization.\n\nSecure Code Example:\n```\nrequire 'json'\n\ndef safe_deserialize(json_data)\n # Validate and sanitize json_data before parsing\n begin\n parsed_data = JSON.parse(json_data)\n return parsed_data\n rescue JSON::ParserError => e\n puts \"Error parsing JSON data: #{e.message}\"\n return nil\n end\nend\n\n# Example usage\n# Example of input JSON string\njson_input = '{\"name\": \"John Doe\", \"age\": 30}' \nuser_data = safe_deserialize(json_input)\nputs user_data.inspect if user_data\n```\n\nAlways ensure that any data deserialized from JSON (or any format) is \nvalidated and sanitized according to the context of your application \nto prevent injection attacks or other security issues.\n" + metadata: + category: security + cwe: CWE-502 + owasp: + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + references: + - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/bad-deserialization.yaml + security-severity: HIGH + shortDescription: Deserialization of untrusted data technology: - ruby - - rails mode: taint pattern-sinks: - - patterns: - - pattern-either: - - pattern: $X.eval - - pattern: $X.class_eval - - pattern: $X.instance_eval - - pattern: $X.module_eval - - pattern: $X.eval(...) - - pattern: $X.class_eval(...) - - pattern: $X.instance_eval(...) - - pattern: $X.module_eval(...) - - pattern: eval(...) - - pattern: class_eval(...) - - pattern: module_eval(...) - - pattern: instance_eval(...) - - pattern-not: $M("...",...) + - pattern-either: + - pattern: | + Marshal.load(...) + - pattern: | + Marshal.restore(...) + - pattern: | + Oj.object_load(...) + - pattern: | + Oj.load($X) pattern-sources: - pattern-either: - pattern: params - pattern: cookies - - patterns: - - pattern: | - RubyVM::InstructionSequence.compile(...) - - pattern-not: | - RubyVM::InstructionSequence.compile("...") - severity: WARNING - - fix-regex: - regex: VERIFY_NONE - replacement: VERIFY_PEER - id: ruby.lang.security.ssl-mode-no-verify.ssl-mode-no-verify + severity: ERROR + - id: ruby_deserialization_rule-BadDeserializationEnv languages: - ruby - message: Detected SSL that will accept an unverified connection. This makes the connections susceptible to man-in-the-middle attacks. Use 'OpenSSL::SSL::VERIFY_PEER' instead. + message: "In Ruby, objects can be serialized into strings using various methods \nand later reconstituted into objects. The `load` and `object_load` \nmethods, associated with modules like Marshal and CSV, is particularly \nrisky when used to deserialize data from untrusted sources. \nIf an attacker is able to manipulate the serialized data, they could \nexecute arbitrary code on the system when the data is deserialized. \nThis vulnerability can lead to remote code execution (RCE), where an \nattacker gains the ability to execute commands on the host machine. \nThe Marshal and CSV modules are often used for serialization and \ndeserialization in Ruby but they do not inherently sanitize or validate \nthe data being processed. This makes them unsafe for handling input from \nuntrusted sources.\n\nTo mitigate the risks associated with unsafe deserialization, it is \nrecommended to:\n- Avoid deserializing from untrusted sources\n- Use JSON for serialization/deserialization as JSON is considered \nsafer for data interchange between systems. However, it's crucial \nto use JSON securely by validating and sanitizing the input before \ndeserialization.\n\nSecure Code Example:\n```\nrequire 'json'\n\ndef safe_deserialize(json_data)\n # Validate and sanitize json_data before parsing\n begin\n parsed_data = JSON.parse(json_data)\n return parsed_data\n rescue JSON::ParserError => e\n puts \"Error parsing JSON data: #{e.message}\"\n return nil\n end\nend\n\n# Example usage\n# Example of input JSON string\njson_input = '{\"name\": \"John Doe\", \"age\": 30}' \nuser_data = safe_deserialize(json_input)\nputs user_data.inspect if user_data\n```\n\nAlways ensure that any data deserialized from JSON (or any format) is \nvalidated and sanitized according to the context of your application \nto prevent injection attacks or other security issues.\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: HIGH + cwe: CWE-502 owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - subcategory: - - vuln + - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/bad-deserialization-env.yaml + security-severity: HIGH + shortDescription: Deserialization of untrusted data technology: - ruby - pattern: OpenSSL::SSL::VERIFY_NONE - severity: WARNING - - id: ruby.lang.security.weak-hashes-md5.weak-hashes-md5 + mode: taint + pattern-sinks: + - pattern-either: + - pattern: | + Marshal.load(...) + - pattern: | + Marshal.restore(...) + - pattern: | + Oj.object_load(...) + - pattern: | + Oj.load($X) + pattern-sources: + - pattern-either: + - pattern: request.env + severity: ERROR + - fix: Psych.safe_load($...ARGS) + id: ruby_deserialization_rule-BadDeserializationYAML languages: - ruby - message: Should not use md5 to generate hashes. md5 is proven to be vulnerable through the use of brute-force attacks. Could also result in collisions, leading to potential collision attacks. Use SHA256 or other hashing functions instead. + message: "Unsafe deserialization from YAML. \nYAML is a popular format for configuration files in Ruby applications \ndue to its readability and simplicity. However, the `load` method \nprovided by Ruby's YAML module can be dangerous when used to deserialize \ndata from untrusted sources. The method can instantiate objects based \non the YAML input, which can lead to remote code execution (RCE) if the \ninput contains malicious code. \n\nTo mitigate the risk of RCE through unsafe deserialization practices, \nconsider the following recommendations:\n- Prefer JSON for untrusted data: JSON is generally safer for \ndeserializing untrusted data because, by design, it does not support \nthe execution of arbitrary code. Ensure that any JSON deserialization \nis performed with caution, validating and sanitizing the input before \nuse.\n- Use safe YAML loading methods: If you must use YAML, prefer safe \nloading methods like `safe_load` instead of `load`. The `safe_load` method \nlimits the objects that can be deserialized, reducing the risk of \nexecuting arbitrary code.\n- Static YAML files: Loading YAML from static, trusted files (like \nconfiguration files that are not exposed to user input) is generally \nsafe. Ensure these files are securely managed and not modifiable by \nuntrusted sources.\n\nSecure Code Example:\n```\nrequire 'yaml'\nrequire 'json'\n\n# Safe YAML deserialization\ndef safe_load_yaml(file_path)\n YAML.safe_load(File.read(file_path), [Date, Time], [], true)\nend\n\n# Example of safely loading a static YAML file\nconfig_data = safe_load_yaml('config.yml')\nputs config_data.inspect\n\n# Safe JSON deserialization\ndef safe_load_json(json_input)\n # Always validate and sanitize input before deserialization\n JSON.parse(json_input)\nend\n\n# Example JSON input\njson_input = '{\"name\": \"Jack Monroe\", \"age\": 30}'\nuser_data = safe_load_json(json_input)\nputs user_data.inspect\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-328: Use of Weak Hash' - impact: HIGH - likelihood: LOW + cwe: CWE-502 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures references: - - https://www.ibm.com/support/pages/security-bulletin-vulnerability-md5-signature-and-hash-algorithm-affects-sterling-integrator-and-sterling-file-gateway-cve-2015-7575 - subcategory: - - vuln + - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/bad-deserialization-yaml.yaml + security-severity: HIGH + shortDescription: Deserialization of untrusted data technology: - ruby - pattern-either: - - pattern: Digest::MD5.base64digest $X - - pattern: Digest::MD5.hexdigest $X - - pattern: Digest::MD5.digest $X - - pattern: Digest::MD5.new - - pattern: OpenSSL::Digest::MD5.base64digest $X - - pattern: OpenSSL::Digest::MD5.hexdigest $X - - pattern: OpenSSL::Digest::MD5.digest $X - - pattern: OpenSSL::Digest::MD5.new - severity: WARNING - - id: ruby.lang.security.weak-hashes-sha1.weak-hashes-sha1 + - yaml + patterns: + - pattern: | + YAML.$LOAD($...ARGS) + - pattern-not: | + YAML.$LOAD(..., safe: true, ...) + - pattern-not: | + YAML.$LOAD("...", ...) + - pattern-not-inside: | + $FILE = File.read("...", ...) + ... + YAML.$LOAD(..., $FILE, ...) + - pattern-not-inside: | + $FILENAME = "..." + ... + $FILE = File.read($FILENAME, ...) + ... + YAML.$LOAD(..., $FILE, ...) + - pattern-not-inside: | + YAML.$LOAD(..., File.read("...", ...), ...) + - metavariable-regex: + metavariable: $LOAD + regex: load(?:_stream)?\b|parse_stream + severity: ERROR + - id: ruby_error_rule-DivideByZero languages: - ruby - message: Should not use SHA1 to generate hashes. There is a proven SHA1 hash collision by Google, which could lead to vulnerabilities. Use SHA256, SHA3 or other hashing functions instead. + message: "A ZeroDivisionError exception has been detected, this occurs when an arithmetic operation attempts to \ndivide a number by zero. This can happen in various contexts, such as \nprocessing user inputs, performing calculations with variables, or \nworking with data from external sources. Such errors not only disrupt \nthe normal flow of the application but also can be exploited in certain \nscenarios to cause harm (eg. possible dos) or extract information based \non the application's response to the error.\n\nTo prevent ZeroDivisionError exceptions and ensure application robustness:\n- Error handling: Implement error handling around division operations to \ncatch and manage ZeroDivisionError gracefully.\n- Validation: Always validate inputs that are used in division operations \nto ensure they are not zero or unexpected values.\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-328: Use of Weak Hash' - impact: MEDIUM - likelihood: LOW + cwe: CWE-369 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A6:2017-Security Misconfiguration + - A04:2021-Insecure Design references: - - https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html - - https://shattered.io/ - subcategory: - - vuln + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/divide-by-zero.yaml + security-severity: LOW + shortDescription: Divide a number by zero technology: - ruby + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: $NUMBER / 0 + - pattern: $NUMBER + pattern-sources: + - patterns: + - pattern: $VAR + - metavariable-regex: + metavariable: $VAR + regex: ^\d*(?!\.)$ + severity: WARNING + - id: ruby_escaping_rule-JSONEntityEscape + languages: + - ruby + message: "This rule checks if HTML escaping is globally disabled for JSON output, \nwhich can lead to Cross-Site Scripting (XSS) vulnerabilities. \nXSS attacks allow attackers to inject malicious scripts into web pages \nviewed by other users, compromising the integrity and confidentiality \nof user data. When HTML escaping is disabled, special HTML characters \nin JSON output are not converted to their entity equivalents, making \nit possible for an attacker to inject executable scripts into the web \napplication's output. \n\nTo mitigate this risk, ensure that HTML escaping is enabled when \ngenerating JSON output, particularly in web applications \nthat dynamically insert user-generated content into the DOM.\n\nSecure Code Example:\n```\n# For an initializer configuration (e.g., in config/initializers/active_support.rb)\n# Enable HTML entity escaping in JSON to prevent XSS\nActiveSupport.escape_html_entities_in_json = true\n\n# For application-wide configuration (e.g., in config/application.rb)\nmodule YourApplication\n class Application < Rails::Application\n # Enable HTML entity escaping in JSON to prevent XSS\n config.active_support.escape_html_entities_in_json = true\n end\nend\n```\n" + metadata: + category: security + cwe: CWE-79 + owasp: + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/json-entity-escape.yaml + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + technology: + - rails pattern-either: - - pattern: Digest::SHA1.$FUNC - - pattern: OpenSSL::Digest::SHA1.$FUNC - - pattern: OpenSSL::HMAC.$FUNC("sha1",...) + - pattern: | + ActiveSupport.escape_html_entities_in_json = false + - pattern: | + config.active_support.escape_html_entities_in_json = false severity: WARNING - - id: ruby.rails.security.audit.avoid-session-manipulation.avoid-session-manipulation + - id: ruby_eval_rule-NoEval languages: - ruby - message: This gets data from session using user inputs. A malicious user may be able to retrieve information from your session that you didn't intend them to. Do not use user input as a session key. + message: "The `eval` method in Ruby executes a string argument as Ruby code. When \n`eval` is used with input that can be controlled or manipulated by an \nexternal user, it can allow arbitrary code execution. This \nmeans an attacker could potentially execute malicious code on the server, \nleading to unauthorized access, data leakage, or server compromise.\n\nRemediation Steps:\n- Validate and sanitize input: If there's an absolute necessity to use \n`eval`, ensure that any user input is rigorously validated and sanitized \nto remove potentially harmful code. However, this is generally not \nrecommended due to the difficulty of securely sanitizing code.\n- Use safer alternatives: Depending on the requirement, consider using \nsafer alternatives to `eval`, such as `send` for calling methods dynamically \nor employing DSLs (Domain-Specific Languages) and safe parsing libraries \ndesigned for specific tasks.\n\nSecure Code Example:\n```\nclass Calculator\n def add(a, b)\n a + b\n end\nend\n\n# Safer alternative using send\ncalculator = Calculator.new\nmethod = params[:operation] # Example: 'add' or 'subtract'\na = params[:a].to_i\nb = params[:b].to_i\n\nif calculator.respond_to?(method)\n result = calculator.send(method, a, b)\nelse\n puts \"Invalid operation\"\nend\n```\n\nIn this example, `send` is used to dynamically call a method on the \nCalculator object based on user input. This approach is safer than \neval because it strictly limits the operations to those defined in \nthe class, preventing arbitrary code execution.\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-276: Incorrect Default Permissions' - cwe2021-top25: true - cwe2022-top25: true - help: | - ## Remediation - Session manipulation can occur when an application allows user-input in session keys. Since sessions are typically considered a source of truth (e.g. to check the logged-in user or to match CSRF tokens), allowing an attacker to manipulate the session may lead to unintended behavior. - - ## References - [Session Manipulation](https://brakemanscanner.org/docs/warning_types/session_manipulation/) - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-95 owasp: - - A01:2021 - Broken Access Control + - A1:2017-Injection + - A03:2021-Injection references: - - https://brakemanscanner.org/docs/warning_types/session_manipulation/ - shortDescription: Allowing an attacker to manipulate the session may lead to unintended behavior. - subcategory: - - vuln - tags: - - security + - https://owasp.org/Top10/A03_2021-Injection + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/no-eval.yaml + security-severity: HIGH + shortDescription: Improper neutralization of directives in dynamically evaluated code ('Eval Injection') technology: - rails mode: taint pattern-sinks: - - pattern: session[...] + - patterns: + - pattern-either: + - pattern: $X.eval + - pattern: $X.class_eval + - pattern: $X.instance_eval + - pattern: $X.module_eval + - pattern: $X.eval(...) + - pattern: $X.class_eval(...) + - pattern: $X.instance_eval(...) + - pattern: $X.module_eval(...) + - pattern: eval(...) + - pattern: class_eval(...) + - pattern: module_eval(...) + - pattern: instance_eval(...) + - pattern-not: $M("...",...) pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env + - pattern-either: + - pattern: params + - pattern: cookies + - patterns: + - pattern: | + RubyVM::InstructionSequence.compile(...) + - pattern-not: | + RubyVM::InstructionSequence.compile("...") + severity: ERROR + - id: ruby_exceptions_rule-DetailedExceptions + languages: + - ruby + message: "The `consider_all_requests_local` setting was found set to true, which enables detailed exception reports. This setting, \nwhile useful during development for debugging purposes, can \ninadvertently expose sensitive system or application information \nto end users when enabled in production environments. Such \ninformation exposure could potentially aid attackers in crafting \nfurther attacks against the system.\n\nIt is advisable to disable detailed exception reporting in production \nenvironments to prevent the leakage of sensitive information. \n\nSecure Configuration Example:\n```\n# config/environments/production.rb\nRails.application.config.consider_all_requests_local = false\n```\n" + metadata: + category: security + cwe: CWE-209 + owasp: + - A3:2017-Sensitive Data Exposure + - A05:2021-Security Misconfiguration + references: + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/detailed-exceptions.yaml + security-severity: MEDIUM + shortDescription: Generation of error message containing sensitive information + technology: + - rails + patterns: + - pattern-either: + - patterns: + - pattern: | + config.consider_all_requests_local = true + - patterns: + - pattern-inside: | + class $CONTROLLER < ApplicationController + ... + end + - pattern: | + def show_detailed_exceptions? (...) + ... + return $RETURN + end + - metavariable-pattern: + metavariable: $RETURN + patterns: + - pattern-not: | + false severity: WARNING - - id: ruby.rails.security.audit.avoid-tainted-file-access.avoid-tainted-file-access + - id: ruby_file_rule-AvoidTaintedFileAccess languages: - ruby - message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. + message: "The application dynamically constructs file or path information with user input. When an application uses data from \nuntrusted sources (like `params`, `cookies`, or `request.env`) to perform \nactions on the file system, it opens up potential vulnerabilities. \nA malicious actor could exploit this to access, modify, or delete \nfiles they shouldn't have access to, leading to information disclosure, \ndata loss, or server compromise. This type of vulnerability is often \nreferred to as a File Inclusion vulnerability or Path Traversal attack, \ndepending on the nature of the exploit.\n\nTo mitigate these risks, follow these best practices:\n- Validate and sanitize input: Ensure all user inputs are strictly \nvalidated and sanitized to prevent path traversal characters (like `../`) \nor other malicious patterns. Only allow filenames or paths that match \nspecific, safe patterns.\n- Use secure libraries: Utilize libraries or frameworks that abstract \nfile access in a secure manner, automatically handling the risks \nassociated with raw user input.\n- Least privilege principle: Run your application with the minimum \nnecessary file system permissions. Restrict the application's access \nto only those directories and files it absolutely needs.\n- Directory whitelisting: Maintain an allow list of permitted directories \nfor file operations, rejecting any requests for paths outside of these \ndirectories.\n\nSecure Code Example:\n```\ndef safe_file_read(filename)\n # Define a list of allowed files or use regex to validate the filename format\n allowed_files = ['allowed_file.txt', 'another_safe_file.txt']\n \n if allowed_files.include?(filename)\n file_path = Rails.root.join('safe_directory', filename)\n content = File.read(file_path)\n return content\n else\n raise \"Access to the requested file is not allowed.\"\n end\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-22 owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown - subcategory: - - vuln + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-file-access.yaml + security-severity: MEDIUM + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') technology: - rails mode: taint @@ -25722,27 +92785,174 @@ rules: - pattern: cookies - pattern: request.env severity: WARNING - - id: ruby.rails.security.audit.avoid-tainted-ftp-call.avoid-tainted-ftp-call + - id: ruby_file_rule-CheckRenderLocalFileInclude languages: - ruby - message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. + message: "The application dynamically constructs file or path information with user input when calling the `render` function. This can allow end\nusers to request arbitrary local files which may result in leaking\nsensitive information persisted on disk. Where possible, avoid letting\nusers specify template paths for `render`. If you must allow user input,\nuse an allow-list of known templates or normalize the user-supplied value\nwith `File.basename(...)`.\n\nTo mitigate this vulnerability, follow these steps:\n- Avoid direct user input: If possible, do not use user input \nto determine file paths. Use a mapping of user input to server-side \ndefined file paths instead.\n- Use `File.basename`: If user input must be used to specify a file, \nensure that the input is normalized using `File.basename` to extract \nthe filename without any directory path. This prevents directory \ntraversal attacks.\n- Path allow listing: Implement an allow list of permitted files or \ndirectories and check user input against this list before processing.\n\nSecure Code Example:\n```\nclass PagesController < ApplicationController\n # Allowlist\n def show\n valid_pages = ['home', 'about_us', 'contact']\n if valid_pages.include?(params[:page])\n render params[:page]\n else\n render 'not_found'\n end\n end\n\n # Sanitizing User Input\n def show\n # Sanitize the user input to extract just the file name\n page = File.basename(params[:page])\n # Optionally, further validate the sanitized input against an allow-list or other criteria\n render page\n end\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-22 owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown - subcategory: - - vuln + - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-render-local-file-include.yaml + security-severity: MEDIUM + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + technology: + - rails + mode: taint + pattern-sanitizers: + - patterns: + - pattern: $MAP[...] + - metavariable-pattern: + metavariable: $MAP + patterns: + - pattern-not-regex: params + - pattern: File.basename(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + render ..., file: $X + - pattern: | + render ..., inline: $X + - pattern: | + render ..., template: $X + - pattern: | + render ..., action: $X + - pattern: | + render $X, ... + - focus-metavariable: $X + pattern-sources: + - patterns: + - pattern: params[...] + severity: WARNING + - id: ruby_file_rule-CheckSendFile + languages: + - ruby + message: "The application dynamically constructs file or path information with user input when calling\nthe `send_file` method in Ruby. This practice can lead to a serious \nsecurity vulnerability known as Local File Inclusion (LFI), allowing \nattackers to read arbitrary files on the server. \nLFI vulnerabilities can lead to the exposure of sensitive information, \nsuch as configuration files, source code, or even data files, \nwhich could be exploited to gain further access or to mount more \nsevere attacks.\n\nTo mitigate this vulnerability, follow these steps:\n- Avoid direct user input: If possible, do not use user input \nto determine file paths. Use a mapping of user input to server-side \ndefined file paths instead.\n- Use `File.basename`: If user input must be used to specify a file, \nensure that the input is normalized using `File.basename` to extract \nthe filename without any directory path. This prevents directory \ntraversal attacks.\n- Path allow listing: Implement an allow list of permitted files or \ndirectories and check user input against this list before processing.\n\nSecure Code Example:\n```\ndef download\n filename = params[:filename]\n filepath = \"path/to/secure/directory/#{File.basename(filename)}\"\n\n # Optionally, further validate the resolved filepath against a whitelist\n\n if File.exist?(filepath) && !File.directory?(filepath)\n send_file filepath, x_sendfile: true\n else\n render plain: \"File not found\", status: :not_found\n end\nend\n```\n" + metadata: + category: security + cwe: CWE-73 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-send-file.yaml + security-severity: MEDIUM + shortDescription: External control of file name or path + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern: | + send_file ... + pattern-sources: + - pattern-either: + - pattern: | + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: WARNING + - id: ruby_filter_rule-CheckBeforeFilter + languages: + - ruby + message: "The application was found disabling controller checks by setting `skip_filter` \nor `skip_before_filter` with an `:except` option. This approach can \ninadvertently open up parts of your application to unauthorized access \nbecause it relies on a blocklist approach, where only specified actions \nare protected. \n\nA safer method of providing this functionality involves specifying \nexactly which controller actions should have checks applied using an \n`:only` option, effectively creating an allowlist. This method ensures \nthat only specified actions are affected, and any new actions added to \nthe controller will have the filters applied by default, adhering to the \nprinciple of secure by default.\n\nSecure Code Example:\n```\nclass UsersController < ApplicationController\n # Apply the filter only to these actions, making it clear and secure by default\n skip_before_action :authenticate_user!, only: [:new, :create]\nend\n```\n\nIn the secure example, `:authenticate_user!` filter is explicitly skipped \nonly for the `:new` and `:create actions`. This means any new action added \nto the UsersController in the future will have the `authenticate_user!` \nfilter applied by default, ensuring that new parts of the application \nare secure from the start. \n" + metadata: + category: security + cwe: CWE-749 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-before-filter.yaml + security-severity: LOW + shortDescription: Exposed dangerous method or function + technology: + - ruby + - rails + mode: search + patterns: + - pattern-either: + - pattern: | + skip_filter ..., :except => $ARGS + - pattern: | + skip_before_filter ..., :except => $ARGS + severity: WARNING + - id: ruby_find_rule-CheckUnscopedFind + languages: + - ruby + message: "The application was found calling the `find(...)` method with user-controlled input. If the \nActiveRecord model being searched against is sensitive, this may lead to \nInsecure Direct Object Reference (IDOR) behavior and allow users to read \narbitrary records. This could lead to data breaches, including the \nexposure of personal information, account takeovers, and other security \nissues.\n\nTo mitigate this risk, it's essential to scope queries to the current \nuser or another appropriate scope that ensures users can only access \ndata they are authorized to see. This is done by using ActiveRecord \nassociations and scopes to limit the records that can be retrieved. \n\nSecure Code Example:\n```\n# Secure way to scope the find to the current user's accounts\ndef show\n @account = current_user.accounts.find(params[:id])\nend\n```\n" + metadata: + category: security + cwe: CWE-639 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + references: + - https://brakemanscanner.org/docs/warning_types/unscoped_find/ + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-unscoped-find.yaml + security-severity: MEDIUM + shortDescription: Authorization bypass through user-controlled key + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $MODEL.find(...) + - pattern: $MODEL.find_by_id(...) + - pattern: $MODEL.find_by_id!(...) + - metavariable-regex: + metavariable: $MODEL + regex: '[A-Z]\S+' + pattern-sources: + - pattern-either: + - pattern: | + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: WARNING + - id: ruby_ftp_rule-AvoidTaintedFTPCall + languages: + - ruby + message: "The application was found calling the Net::FTP modules methods with\nuser supplied input. A malicious actor could use this to modify or access files\nthey should not have access to.\n\nDirectly incorporating user-controlled input from `params`, `cookies`, \nor `request.env` into FTP commands or connection setups can lead to \nvarious security vulnerabilities, including Remote Code Execution \n(RCE), unauthorized file access, and data exfiltration. It's crucial \nto validate, sanitize, and, where possible, avoid using user-controlled \ndata in sensitive operations like FTP transactions. Ensure that any input \nused in FTP operations is strictly controlled and validated against \nexpected patterns.\n\nRemediation Strategy:\nTo mitigate these risks, ensure that all user-provided input is strictly \nvalidated and sanitized before being used in FTP operations. \n- Verify the format and content of the input to ensure it meets expected \ncriteria.\n- Use allowlists to restrict the input to known safe values.\n- Employ built-in security features of the programming language or \nframework to escape or safely handle user input.\n\nSecure Code Example:\n```\nfilename = params[:filename]\n# Validate the filename to ensure it's a known, safe file\nraise \"Invalid filename\" unless filename =~ /\\A[\\w]+\\.\\w+\\z/\n\nNet::FTP.open('example.com', 'user', 'password') do |ftp|\n # Proceed with the FTP operation using the validated and sanitized filename\n ftp.getbinaryfile(filename, \"local_#{filename}\", 1024)\nend\n```\n" + metadata: + category: security + cwe: CWE-76 + owasp: + - A1:2017-Injection + - A03:2021-Injection + references: + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-ftp-call.yaml + security-severity: MEDIUM + shortDescription: Improper neutralization of equivalent special elements technology: + - ruby - rails mode: taint pattern-sinks: @@ -25759,25 +92969,20 @@ rules: - pattern: cookies - pattern: request.env severity: WARNING - - id: ruby.rails.security.audit.avoid-tainted-http-request.avoid-tainted-http-request + - id: ruby_http_rule-AvoidTaintedHTTPRequest languages: - ruby - message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. + message: "The application was found including unvalidated user input into `Net::HTTP` methods, \nwhich could lead to HTTP Parameter Pollution (HPP) or worse, Server Side Request Forgery (SSRF).\nSpecifically, it looks for methods like GET, POST, DELETE, etc., \nbeing called with parameters that could be controlled by an end-user. \nUsing untrusted input in such a manner without proper validation and \nsanitization can lead to a variety of security vulnerabilities, including \nSSRF, injection attacks, unintended data leaks, and unauthorized actions \nbeing performed on behalf of the attacker.\n\nEnsure all user-controlled input is validated against a strict set of rules \n(e.g., expected data types, patterns, and lengths) and sanitized to remove \nor encode potentially harmful characters before being used in HTTP requests. \nAdditionally, consider using higher-level abstractions or frameworks that \nautomatically handle some of these concerns.\n\nSecure Code Example:\n```\nrequire 'uri'\n\n# Validate and sanitize the user input before using it in the HTTP request\nbegin\n user_input = params[:url]\n uri = URI.parse(user_input)\n\n # Ensure the URI is HTTP/HTTPS and refers to a trusted domain\n if uri.scheme.match?(/\\Ahttps?\\z/) && uri.host == 'www.abc.com'\n response = Net::HTTP.get(uri)\n else\n raise \"Invalid URL\"\n end\nrescue URI::InvalidURIError\n puts \"Provided URL is not valid\"\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-918 owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) + - A1:2017-Injection + - A10:2021-Server-Side Request Forgery references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown - subcategory: - - vuln + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-http-request.yaml + security-severity: MEDIUM + shortDescription: Server side request forgery (SSRF) technology: - rails mode: taint @@ -25834,28 +93039,54 @@ rules: - pattern: cookies - pattern: request.env severity: WARNING - - id: ruby.rails.security.audit.avoid-tainted-shell-call.avoid-tainted-shell-call + - id: ruby_http_rule-CheckHTTPVerbConfusion languages: - ruby - message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. + message: "Found an improperly constructed control flow block with `request.get?`. \nRails will route HEAD requests as GET requests but they will fail the \n`request.get?` check, potentially causing unexpected behavior unless an \n`elsif` condition is used.\n\nSecure Code Example:\n```\nif request.get?\n # Handle GET request logic here\nelsif request.head?\n # Handle HEAD request logic here\nelse\n # Handle others if needed\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-754 owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A6:2017-Security Misconfiguration + - A04:2021-Insecure Design references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown - subcategory: - - vuln + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-http-verb-confusion.yaml + security-severity: MEDIUM + shortDescription: Improper check for unusual or exceptional conditions + technology: + - ruby + - rails + mode: search + patterns: + - pattern: | + if request.get? + ... + else + ... + end + - pattern-not-inside: | + if ... + elsif ... + ... + end + severity: WARNING + - id: ruby_injection_rule-AvoidTaintedShellCall + languages: + - ruby + message: "User input should never be used in constructing commands or command arguments\nto functions which execute OS related functionality. Using external \ninput without validation in functions like `Kernel.system`, `exec`, or any \noperations that interact with the shell or file system (`cat`, `delete` \netc.) poses a severe security risk. These patterns can lead to command \ninjection vulnerabilities, where an attacker could execute arbitrary \ncommands on the system the application is hosted on, leading to data \nbreaches, unauthorized access, or worse.\n\nTo prevent command injection vulnerabilities, validate and sanitize all \nuser input before using it in any system or shell operation. Additionally, \nconsider using safer alternatives for executing system commands that don't \ndirectly pass user input to the shell, such as parameterized APIs or \nfunctions that handle arguments safely.\n\nSecure Code Example:\n```\nuser_filename_key = params[:filename_key]\n\nallowed_filenames = {\n 'file1' => 'allowed_file_1.txt',\n 'file2' => 'allowed_file_2.txt',\n}\n\n# Validate and select the filename from the lookup table\nif allowed_filenames.has_key?(user_filename_key)\n safe_filename = allowed_filenames[user_filename_key]\n\n # Use a safer API to read file content without invoking the shell\n content = File.read(safe_filename)\nelse\n puts \"Invalid filename.\"\nend\n```\n" + metadata: + category: security + cwe: CWE-78 + owasp: + - A1:2017-Injection + - A03:2021-Injection + references: + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-shell-call.yaml + security-severity: HIGH + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') technology: - rails + - ruby mode: taint pattern-sinks: - patterns: @@ -25910,358 +93141,167 @@ rules: - pattern: cookies - pattern: request.env severity: ERROR - - id: ruby.rails.security.audit.sqli.ruby-pg-sqli.ruby-pg-sqli + - id: ruby_injection_rule-BadSend languages: - ruby - message: 'Detected string concatenation with a non-literal variable in a pg Ruby SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized queries like so: `conn.exec_params(''SELECT $1 AS a, $2 AS b, $3 AS c'', [1, 2, nil])` And you can use prepared statements with `exec_prepared`.' + message: "The application was found calling dynamic method invocations in Ruby. \nIn particular one of the methods of: `Object#send`, `Object#try`, `Object#__send__`, \nor `Object#public_send`. These methods are powerful Ruby features that allow \ncalling another method on an object \nby name, where the method's name is passed as a string or symbol. \nHowever, when combined with untrusted input, such as parameters from \nweb requests, they can lead to severe security vulnerabilities, including \narbitrary method execution and potentially arbitrary code execution.\n\nTo mitigate these risks, it's crucial to validate and sanitize any user \ninput that might determine which methods are invoked. Moreover, consider \nusing safer alternatives to direct method invocation based on user input, \nsuch as explicitly whitelisting allowed methods or using conditional logic \nto determine method calls.\n\nSecure Code Example:\n```\n# Secure method invocation with validation and allow lists\nmethod_name = params[:method].to_sym\nallowed_methods = [:allowed_method_1, :allowed_method_2, :safe_method]\n\nif allowed_methods.include?(method_name)\n result = object.public_send(method_name)\nelse\n raise \"Unauthorized method call\"\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-94 owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A1:2017-Injection + - A03:2021-Injection references: - - https://www.rubydoc.info/gems/pg/PG/Connection - subcategory: - - vuln + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/no-send.yaml + - https://the.igreque.info/posts/2016/01-object-send-considered-harmful-en.html + security-severity: HIGH + shortDescription: Improper control of generation of code ('Code Injection') technology: - - rails - mode: taint - pattern-propagators: - - from: $Y - pattern: $X << $Y - to: $X - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $CON = PG.connect(...) - ... - - pattern-inside: | - $CON = PG::Connection.open(...) - ... - - pattern-inside: | - $CON = PG::Connection.new(...) - ... - - pattern-either: - - pattern: | - $CON.$METHOD($X,...) - - pattern: | - $CON.$METHOD $X, ... - - focus-metavariable: $X - - metavariable-regex: - metavariable: $METHOD - regex: ^(exec|exec_params)$ - pattern-sources: - - pattern-either: - - pattern: | - params - - pattern: | - cookies - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-link-to.avoid-link-to + - ruby + pattern-either: + - pattern: | + $PARAM = params[...] + ... + $RES = $MOD.send($PARAM.$FUNC) + - pattern: | + $PARAM = params[...] + ... + $RES = $MOD.try($PARAM.$FUNC) + - pattern: | + $PARAM = params[...] + ... + $RES = $MOD.__send__($PARAM.$FUNC) + - pattern: | + $PARAM = params[...] + ... + $RES = $MOD.public_send($PARAM.$FUNC) + severity: ERROR + - id: ruby_injection_rule-DangerousExec languages: - ruby - message: This code includes user input in `link_to`. In Rails 2.x, the body of `link_to` is not escaped. This means that user input which reaches the body will be executed when the HTML is rendered. Even in other versions, values starting with `javascript:` or `data:` are not escaped. It is better to create and use a safer function which checks the body argument. + message: "OS command injection is a critical vulnerability that can lead to a full system\ncompromise as it may allow an adversary to pass in arbitrary commands or arguments\nto be executed.\n\nUser input should never be used in constructing commands or command arguments\nto functions which execute OS commands. This includes filenames supplied by\nuser uploads or downloads.\n\nTo mitigate this vulnerability, follow these best practices:\n- Validate input: Ensure that all user inputs are validated against a \nstrict pattern that only allows safe characters for the context. Reject \nany input that does not meet these criteria.\n- Sanitize input: When validation is not feasible, sanitize the input \nby escaping or removing potentially dangerous characters.\n- Use secure methods: Prefer using secure methods or libraries designed \nto execute system commands with parameters, which automatically handle \nproper escaping of user inputs, such as `Open3.capture3` in Ruby.\n- Least privilege: Run your application with the least privileges \nnecessary, limiting what an attacker can do if they manage to execute a \ncommand.\n\nSecure Code Example:\nInstead of directly interpolating user input into system commands, validate \nuser input against an allowlist, then use parameterized execution or safer \nAPIs like Open3:\n```\nrequire 'open3'\n\nuser_input = params[:user_input]\n# Define an allow list of permitted arguments\nallowed_arguments = ['allowed_argument1', 'allowed_argument2', 'allowed_argument3']\n\n# Validate user_input against the list\nif allowed_arguments.include?(user_input)\n # Using Open3 to safely execute system commands with allowed arguments\n stdout, stderr, status = Open3.capture3('grep', user_input, 'my_file.txt')\n if status.success?\n puts stdout\n else\n warn \"Error: #{stderr}\"\n end\nelse\n warn \"Error: Unpermitted argument.\"\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-94 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A1:2017-Injection + - A03:2021-Injection references: - - https://brakemanscanner.org/docs/warning_types/link_to/ - - https://brakemanscanner.org/docs/warning_types/link_to_href/ - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_link_to.rb - subcategory: - - vuln + - https://guides.rubyonrails.org/security.html#command-line-injection + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/dangerous-exec.yaml + security-severity: HIGH + shortDescription: Improper control of generation of code ('Code Injection') technology: + - ruby - rails mode: taint - pattern-sanitizers: + pattern-sinks: - patterns: - pattern: | - "...#{...}..." + $EXEC(...) - pattern-not: | - "#{...}..." - pattern-sinks: - - pattern: link_to(...) - pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - - pattern-either: - - pattern: $MODEL.url(...) - - pattern: $MODEL.uri(...) - - pattern: $MODEL.link(...) - - pattern: $MODEL.page(...) - - pattern: $MODEL.site(...) - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-redirect.avoid-redirect - languages: - - ruby - message: When a redirect uses user input, a malicious user can spoof a website under a trusted URL or access restricted parts of a site. When using user-supplied values, sanitize the value before using it for the redirect. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/redirect/ - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sanitizers: - - pattern: params.merge(:only_path => true) - - pattern: params.merge(:host => ...) - pattern-sinks: - - pattern: redirect_to(...) + $EXEC("...","...","...",...) + - pattern-not: | + $EXEC(["...","...","...",...],...) + - pattern-not: | + $EXEC({...},"...","...","...",...) + - pattern-not: | + $EXEC({...},["...","...","...",...],...) + - metavariable-regex: + metavariable: $EXEC + regex: ^(system|exec|spawn|Process.exec|Process.spawn|Open3.capture2|Open3.capture2e|Open3.capture3|Open3.popen2|Open3.popen2e|Open3.popen3|IO.popen|Gem::Util.popen|PTY.spawn)$ pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - - patterns: - - pattern: $MODEL.$X(...) - - pattern-not: $MODEL.$X("...") - - metavariable-pattern: - metavariable: $X - pattern-either: - - pattern: all - - pattern: create - - pattern: create! - - pattern: find - - pattern: find_by_sql - - pattern: first - - pattern: last - - pattern: new - - pattern: from - - pattern: group - - pattern: having - - pattern: joins - - pattern: lock - - pattern: order - - pattern: reorder - - pattern: select - - pattern: where - - pattern: find_by - - pattern: find_by! - - pattern: take - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-render-dynamic-path.avoid-render-dynamic-path - languages: - - ruby - message: Avoid rendering user input. It may be possible for a malicious user to input a path that lets them access a template they shouldn't. To prevent this, check dynamic template paths against a predefined allowlist to make sure it's an allowed template. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/dynamic_render_paths/ - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sinks: - patterns: - - pattern-inside: render($X => $INPUT, ...) - - pattern: $INPUT - - metavariable-pattern: - metavariable: $X - pattern-either: - - pattern: action - - pattern: template - - pattern: partial - - pattern: file - pattern-sources: + - pattern: | + def $F(...,$ARG,...) + ... + end + - focus-metavariable: $ARG - pattern: params - pattern: cookies - - pattern: request.env - severity: WARNING - - id: ruby.rails.security.brakeman.check-before-filter.check-before-filter - languages: - - ruby - message: 'Disabled-by-default Rails controller checks make it much easier to introduce access control mistakes. Prefer an allowlist approach with `:only => [...]` rather than `except: => [...]`' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-284: Improper Access Control' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_skip_before_filter.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: search - patterns: - - pattern-either: - - pattern: | - skip_filter ..., :except => $ARGS - - pattern: | - skip_before_filter ..., :except => $ARGS - - pattern: | - skip_before_action ..., :except => $ARGS severity: ERROR - - id: ruby.rails.security.brakeman.check-dynamic-render-local-file-include.check-dynamic-render-local-file-include - languages: - - generic - message: Found request parameters in a call to `render` in a dynamic context. This can allow end users to request arbitrary local files which may result in leaking sensitive information persisted on disk. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion - - https://github.com/presidentbeef/brakeman/blob/f74cb53ead47f0af821d98b5b41e16d63100c240/test/apps/rails2/app/views/home/test_render.html.erb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: search - paths: - include: - - '*.erb' - patterns: - - pattern: | - params[...] - - pattern-inside: | - render :file => ... - severity: WARNING - - id: ruby.rails.security.brakeman.check-http-verb-confusion.check-http-verb-confusion + - id: ruby_mass_assignment_rule-ModelAttrAccessible languages: - ruby - message: Found an improperly constructed control flow block with `request.get?`. Rails will route HEAD requests as GET requests but they will fail the `request.get?` check, potentially causing unexpected behavior unless an `elif` condition is used. + message: "The application was found permitting attributes which could lead to mass assignment\nvulnerabilities. Permitting attributes such as `admin`, `role`, `banned` etc, \nwithout proper authorization checks can lead to security issues like unauthorized \naccess or privilege escalation.\n\nRemediation Strategy\n- Explicitly permit attributes: Carefully review which attributes are \npermissible and avoid including sensitive ones in the list.\n- Role-based permissions: Implement checks that allow only authorized \nusers (e.g., administrators) to modify sensitive attributes.\n- Avoid using `params.permit!`: Use specific permit statements instead of \npermitting all parameters to ensure only expected attributes are allowed \nfor mass assignment.\n\nSecure Code Example:\n```\n# Secure: Conditionally permit sensitive attributes based on user role\ndef user_params\npermitted = params.require(:user).permit(:name, :email)\npermitted[:role] = params[:user][:role] if current_user.admin? && params[:user][:role].present?\npermitted\nend\n\ndef user_params2\n permitted_attributes = [:username, :email]\n # Only allow 'admin' attribute to be updated by users with admin role\n permitted_attributes << :admin if current_user.admin?\n params.require(:user).permit(*permitted_attributes)\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-650: Trusting HTTP Permission Methods on the Server Side' - impact: MEDIUM - likelihood: HIGH + cwe: CWE-915 owasp: - - A04:2021 - Insecure Design + - A6:2017-Security Misconfiguration + - A08:2021-Software and Data Integrity Failures references: - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails6/app/controllers/accounts_controller.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_verb_confusion.rb - subcategory: - - vuln + - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/model-attr-accessible.yaml + security-severity: MEDIUM + shortDescription: Improperly controlled modification of dynamically-determined object attributes technology: - ruby - rails - mode: search - patterns: + pattern-either: - pattern: | - if request.get? - ... - else - ... - end - - pattern-not-inside: | - if ... - elsif ... - ... - end - severity: ERROR - - id: ruby.rails.security.brakeman.check-rails-session-secret-handling.check-rails-session-secret-handling + ....permit(..., :admin, ...) + - pattern: | + ....permit(..., :role, ...) + - pattern: | + ....permit(..., :banned, ...) + - pattern: | + ....permit(..., :account_id, ...) + - pattern: | + attr_accessible ..., :admin, ... + - pattern: | + attr_accessible ..., :role, ... + - pattern: | + attr_accessible ..., :banned, ... + - pattern: | + attr_accessible ..., :account_id, ... + - pattern: | + params.permit! + severity: WARNING + - id: ruby_mass_assignment_rule-UnprotectedMassAssign languages: - ruby - message: Found a string literal assignment to a Rails session secret `$KEY`. Do not commit secret values to source control! Any user in possession of this value may falsify arbitrary session data in your application. Read this value from an environment variable, KMS, or file on disk outside of source control. + message: "Checks for calls to `without_protection` during mass assignment (which \nallows record creation from hash values). This can lead to users bypassing \npermissions protections. Using `:without_protection => true` makes your \napplication vulnerable to attackers who may craft malicious requests to \nmodify sensitive attributes, leading to unauthorized access or data \nmanipulation. For Rails 4 and higher, mass protection is on by default.\n\nTo mitigate this issue, don't use :without_protection => true. Instead, \nconfigure attr_accessible to control attribute access.\n\nSecure Code Example:\n```\nclass User < ActiveRecord::Base\n # Only name and email can be updated via mass assignment\n attr_accessible :name, :email\n\n # admin and account_id are not listed here, so they cannot be mass-assigned\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-540: Inclusion of Sensitive Information in Source Code' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-915 owasp: - - A01:2021 - Broken Access Control + - A6:2017-Security Misconfiguration + - A08:2021-Software and Data Integrity Failures references: - - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails4_with_engines/config/initializers/secret_token.rb - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3/config/initializers/secret_token.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_session_settings.rb - subcategory: - - vuln + - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/unprotected-mass-assign.yaml + security-severity: MEDIUM + shortDescription: Improperly controlled modification of dynamically-determined object attributes technology: - ruby - rails patterns: - pattern-either: - - patterns: - - pattern: | - :$KEY => "$LITERAL" - - pattern-inside: | - ActionController::Base.session = {...} - pattern: | - $RAILS::Application.config.$KEY = "$LITERAL" + $MOD.new(params[$CODE]) - pattern: | - Rails.application.config.$KEY = "$LITERAL" - - metavariable-regex: - metavariable: $KEY - regex: ^secret(_(token|key_base))?$ + $MOD.new(..., params[$CODE], :without_protection => true, ...) + - pattern-not-inside: | + attr_accessible $VAR + ... + $MOD.new(params[$CODE]) severity: WARNING - - id: ruby.rails.security.brakeman.check-redirect-to.check-redirect-to + - id: ruby_redirect_rule-CheckRedirectTo languages: - ruby - message: Found potentially unsafe handling of redirect behavior $X. Do not pass `params` to `redirect_to` without the `:only_path => true` hash value. + message: "The application was found handling redirect behavior with user-supplied input. \nDo not pass `params` to `redirect_to` without the `:only_path => true` \nhash value. Using `:only_path => true` ensures that the URL is interpreted \nas a relative path, not allowing redirection to an arbitrary external URL, \nthus mitigating the risk of open redirects. Alternatively, validate or \nsanitize the input to ensure it's safe and intended.\n\nSecure Code Example:\n```\n# Secure - Ensuring redirection is only to internal paths\ndef secure_redirect\n redirect_to params[:redirect_url], only_path: true\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-601 owasp: - - A01:2021 - Broken Access Control + - A1:2017-Injection + - A03:2021-Injection references: - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_redirect.rb - subcategory: - - vuln + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-redirect-to.yaml + security-severity: LOW + shortDescription: URL redirection to untrusted site 'open redirect' technology: - ruby - rails @@ -26320,25 +93360,118 @@ rules: - pattern: cookies - pattern: request.env - pattern: url_for(params[...],...,:only_path => false,...) - severity: WARNING - - id: ruby.rails.security.brakeman.check-regex-dos.check-regex-dos + severity: INFO + - id: ruby_reflection_rule-CheckUnsafeReflection languages: - ruby - message: Found a potentially user-controllable argument in the construction of a regular expressions. This may result in excessive resource consumption when applied to certain inputs, or when the user is allowed to control the match target. Avoid allowing users to specify regular expressions processed by the server. If you must support user-controllable input in a regular expression, use an allow-list to restrict the expressions users may supply to limit catastrophic backtracking. + message: "The application was found calling a reflection method with user-controllable\ninput. Reflection in Ruby allows a program to examine and modify its own \nstructure and behavior at runtime. When user input is used unsafely \nwith reflection methods (like `constantize`, `safe_constantize`, `const_get`, \n`qualified_const_get`), it poses a significant security risk, potentially \nleading to arbitrary code execution.\n\nTo mitigate these risks:\n- Avoid direct user input in reflection: Never use user-controllable input \ndirectly with reflection methods.\n- Validate and sanitize input: If user input must influence program behavior, \nrigorously validate and sanitize the input against a whitelist of allowed \nvalues.\n- Use indirect references: Instead of allowing direct specification of class \nor method names, map user inputs to a predefined set of allowed actions or \nclasses.\n- Do not provide user-controllable input to reflection functionality. \n- Do not call symbol conversion on user-controllable input.\n\nSecure Code Example:\n```\nclass SafeClassHandler\n ALLOWED_CLASSES = {\n 'user' => User,\n 'product' => Product\n }.freeze\n\n def self.handle_class_action(class_key)\n klass = ALLOWED_CLASSES[class_key]\n raise ArgumentError, \"Invalid class key\" unless klass\n\n klass.some_method\n end\nend\n\n# Example usage\nSafeClassHandler.handle_class_action(params[:class_key])\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-1333: Inefficient Regular Expression Complexity' - impact: MEDIUM - likelihood: HIGH + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + references: + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-unsafe-reflection.yaml + security-severity: HIGH + shortDescription: Improper control of generation of code ('Code Injection') + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern: $X + - pattern-either: + - pattern-inside: | + $X.constantize + - pattern-inside: | + $X. ... .safe_constantize + - pattern-inside: | + const_get(...) + - pattern-inside: | + qualified_const_get(...) + pattern-sources: + - pattern-either: + - pattern: | + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: ERROR + - id: ruby_reflection_rule-CheckUnsafeReflectionMethods + languages: + - ruby + message: "The application was found calling a reflection method with user-controllable\ninput. This practice can lead to unauthorized alteration of program behavior, \nincluding the potential execution of arbitrary code. Reflection methods \nallow dynamic execution of code, which is powerful but risky if not properly \nsanitized, as it could enable attackers to execute unintended methods or \nblocks.\n\nRemediation:\n- Validate and sanitize input: Ensure that any user input is strictly \nvalidated against a whitelist of allowed values before being passed to \nreflection methods. Avoid direct mapping of user input to method names \nor proc conversions.\n- Limit reflection use: Minimize the use of reflection with user input. \nPrefer direct method calls or other non-reflective approaches whenever \npossible.\n- Use safer alternatives: When dynamic behavior is necessary, use controlled \nmethods like `public_send` with proper input validation to reduce risk.\n\nSecure Code Example:\n```\n# Assume user input is to invoke a method on an object\nuser_method = params[:method_name]\n\n# Define an allow list of permissible methods\nallowed_methods = ['safe_method_1', 'safe_method_2']\n\nif allowed_methods.include?(user_method)\n # Using public_send for controlled method invocation\n result = my_object.public_send(user_method)\nelse\n raise 'Unauthorized method access'\nend\n```\n" + metadata: + category: security + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + references: + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-unsafe-reflection-methods.yaml + security-severity: HIGH + shortDescription: Improper control of generation of code ('Code Injection') + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern: $X + - pattern-either: + - pattern-inside: | + $X. ... .to_proc + - patterns: + - pattern-inside: | + $Y.method($Z) + - focus-metavariable: $Z + - patterns: + - pattern-inside: | + $Y.tap($Z) + - focus-metavariable: $Z + - patterns: + - pattern-inside: | + $Y.tap{ |$ANY| $Z } + - focus-metavariable: $Z + pattern-sources: + - pattern-either: + - pattern: | + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: ERROR + - id: ruby_regex_rule-CheckRegexDOS + languages: + - ruby + message: "The application was found constructing a regular expression with user-controllable\ninput. This may result in excessive resource consumption \nwhen applied to certain inputs, or when the user is allowed to control \nthe match target.\n\nTo mitigate the issue, avoid allowing users to specify regular expressions \nprocessed by the server. If you must support user-controllable input in a \nregular expression, use an allow-list to restrict the expressions users \nmay supply to limit catastrophic backtracking.\n\nSecure Code Example:\n```\n# Define an allow-list of safe, predefined patterns\nALLOWED_PATTERNS = {\n 'digits_only' => /^\\d+$/,\n 'letters_only' => /^[a-zA-Z]+$/,\n 'email_format' => /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/\n}\nuser_pattern_key = params[:pattern_key]\ntarget_data = params[:data]\n\nif ALLOWED_PATTERNS.key?(user_pattern_key)\n # Fetch the safe pattern from the allow-list\n safe_pattern = ALLOWED_PATTERNS[user_pattern_key]\n \n # Apply the regular expression safely\n if target_data.match(safe_pattern)\n # Do something\n else\n # Do something\n end\nelse\n # Handle case where the pattern is not allowed\nend\n```\n" + metadata: + category: security + cwe: CWE-1333 owasp: - - A03:2017 - Sensitive Data Exposure + - A6:2017-Security Misconfiguration + - A04:2021-Insecure Design references: - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_regex_dos.rb - subcategory: - - vuln + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-regex-dos.yaml + security-severity: MEDIUM + shortDescription: Inefficient regular expression complexity technology: - ruby - rails @@ -26379,182 +93512,166 @@ rules: - metavariable-regex: metavariable: $RECORD regex: '[A-Z][a-z]+' - severity: ERROR - - id: ruby.rails.security.brakeman.check-render-local-file-include.check-render-local-file-include + severity: WARNING + - id: ruby_regex_rule-CheckValidationRegex languages: - ruby - message: Found request parameters in a call to `render`. This can allow end users to request arbitrary local files which may result in leaking sensitive information persisted on disk. Where possible, avoid letting users specify template paths for `render`. If you must allow user input, use an allow-list of known templates or normalize the user-supplied value with `File.basename(...)`. + message: "An incorrectly-bounded regex was passed to `validates_format_of` \nor `validate ... format => ...`.\n\nRuby regex behavior is multiline by default and lines should be terminated \nby `\\A` for beginning of line and `\\Z` for end of line, respectively.\n\nSecure Code Example:\n```\nclass User < ApplicationRecord\n # Securely anchored from start to end of the string\n validates :username, format: { with: /\\A(?=.*[a-zA-Z])[a-zA-Z0-9]+\\z/ }\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: CWE-185 owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control references: - - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion - - https://github.com/presidentbeef/brakeman/blob/f74cb53/test/apps/rails2/app/controllers/home_controller.rb#L48-L60 - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render.rb - subcategory: - - vuln + - https://brakemanscanner.org/docs/warning_types/format_validation/ + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-validation-regex.yaml + security-severity: MEDIUM + shortDescription: Incorrect regular expression technology: - ruby - rails - vulnerability_class: - - Path Traversal - mode: taint - pattern-sanitizers: - - patterns: - - pattern: $MAP[...] - - metavariable-pattern: - metavariable: $MAP - patterns: - - pattern-not-regex: params - - pattern: File.basename(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - render ..., file: $X - - pattern: | - render ..., inline: $X - - pattern: | - render ..., template: $X - - pattern: | - render ..., action: $X - - pattern: | - render $X, ... - - focus-metavariable: $X - pattern-sources: - - patterns: - - pattern: params[...] + mode: search + patterns: + - pattern-either: + - pattern: | + validates ..., :format => <... $V ...>,... + - pattern: | + validates_format_of ..., :with => <... $V ...>,... + - metavariable-regex: + metavariable: $V + regex: /(.{2}(? 'posts#index', as: :posts + get 'posts/:id' => 'posts#show', as: :post + post 'posts' => 'posts#create' + + # Other CRUD actions for posts can be defined similarly + end + ``` metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-1022: Use of Web Link to Untrusted Target with window.opener Access' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-276 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control references: - - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#browser_compatibility - - https://github.com/presidentbeef/brakeman/blob/3f5d5d5/test/apps/rails5/app/views/users/show.html.erb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_reverse_tabnabbing.rb - subcategory: - - vuln + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-default-routes.yaml + security-severity: MEDIUM + shortDescription: Incorrect Default Permissions technology: - - ruby - rails - mode: search paths: include: - - '*.erb' + - '*routes.rb' patterns: - - pattern: | - _blank - - pattern-inside: | - target: ... - - pattern-not-inside: | - <%= ... rel: 'noopener noreferrer' ...%> - pattern-either: - - patterns: - - pattern-inside: | - <%= $...INLINERUBYDO do -%> - ... - <% end %> - - metavariable-pattern: - language: ruby - metavariable: $...INLINERUBYDO - patterns: - - pattern: | - link_to ... - - pattern-not: | - link_to "...", "...", ... - - patterns: - - pattern-not-inside: | - <%= ... do - %> - - pattern-inside: | - <%= $...INLINERUBY %> - - metavariable-pattern: - language: ruby - metavariable: $...INLINERUBY - patterns: - - pattern: | - link_to ... - - pattern-not: | - link_to '...', '...', ... - - pattern-not: | - link_to '...', target: ... + - pattern: map.connect ":controller/:action/:id" + - pattern: match ':controller(/:action(/:id(.:format)))' severity: WARNING - - id: ruby.rails.security.brakeman.check-secrets.check-secrets + - id: ruby_session_rule-AvoidSessionManipulation languages: - ruby - message: Found a Brakeman-style secret - a variable with the name password/secret/api_key/rest_auth_site_key and a non-empty string literal value. + message: "The application was found retrieving session data using user input. A \nmalicious user may be able to retrieve information from the session \nthat was not meant to be allowed. \nSession manipulation can occur when an application allows user-input in \nsession keys. Since sessions are typically considered a source of truth \n(e.g. to check the logged-in user or to match CSRF tokens), allowing an \nattacker to manipulate the session may lead to unintended behavior. \n\nTo mitigate this issue, never use user input as a session key. Instead, \nconsider an allow list approach to control access to session keys, \nensuring only predefined keys are accessible, and user input is not used\nto directly access the session key values. \n\nSecure Code Example:\n```\n# Define an allowed list of permitted session keys\nALLOWED_SESSION_KEYS = ['display_settings', 'locale']\n\nuser_provided_key = params[:key]\n\n# Validate the key against the list\nif ALLOWED_SESSION_KEYS.include?(user_provided_key)\n # Access the session value safely\n value = session[user_provided_key]\nelse\n raise \"Invalid session key provided.\"\nend\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-276 owasp: - - A01:2021 - Broken Access Control + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - - https://github.com/presidentbeef/brakeman/blob/3f5d5d5f00864cdf7769c50f5bd26f1769a4ba75/test/apps/rails3.1/app/controllers/users_controller.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_secrets.rb - subcategory: - - vuln + - https://brakemanscanner.org/docs/warning_types/session_manipulation/ + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-session-manipulation.yaml + security-severity: CRITICAL + shortDescription: Incorrect default permissions technology: - - ruby - rails - patterns: - - pattern: $VAR = "$VALUE" - - metavariable-regex: - metavariable: $VAR - regex: (?i)password|secret|(rest_auth_site|api)_key$ - - metavariable-regex: - metavariable: $VALUE - regex: .+ - severity: WARNING - - id: ruby.rails.security.brakeman.check-send-file.check-send-file + mode: taint + pattern-sinks: + - pattern: session[...] + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + severity: ERROR + - id: ruby_sql_rule-CheckSQL languages: - ruby - message: Allowing user input to `send_file` allows a malicious user to potentially read arbitrary files from the server. Avoid accepting user input in `send_file` or normalize with `File.basename(...)` + message: "SQL Injection is a critical vulnerability that can lead to data or system compromise. By\ndynamically generating SQL query strings, user input may be able to influence the logic of\nthe SQL statement. This could lead to an adversary accessing information they should\nnot have access to, or in some circumstances, being able to execute OS functionality or code.\n\nTo mitigate this issue, always use parameterized queries or the \nActiveRecord query interface, which ensures that inputs are properly \nescaped, preventing SQL injection attacks. Avoid string interpolation \nor concatenation with user-controlled input for constructing SQL queries.\n\nSecure Code Example:\n```\n# Secure: Using parameterized queries with ActiveRecord\nuser_id = params[:id]\nUser.where(\"id = ?\", user_id)\n\n# Secure: Using ActiveRecord's query methods, which automatically handle parameterization\n# Converting to integer as an additional layer of input sanitization\nuser_id = params[:id].to_i \nUser.where(id: user_id)\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-73: External Control of File Name or Path' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-89 owasp: - - A04:2021 - Insecure Design + - A1:2017-Injection + - A03:2021-Injection references: - - https://owasp.org/www-community/attacks/Path_Traversal - - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_send_file.rb - subcategory: - - vuln + - https://owasp.org/www-community/attacks/SQL_Injection + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-sql.yaml + security-severity: HIGH + shortDescription: Improper neutralization of special elements used in a SQL command ('SQL Injection') technology: - ruby - rails mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - patterns: + - pattern: $X + - pattern-either: + - pattern-inside: | + :$KEY => $X + - pattern-inside: | + ["...",$X,...] + - pattern: | + params[...].to_i + - pattern: | + params[...].to_f + - patterns: + - pattern: | + params[...] ? $A : $B + - metavariable-pattern: + metavariable: $A + patterns: + - pattern-not: | + params[...] + - metavariable-pattern: + metavariable: $B + patterns: + - pattern-not: | + params[...] pattern-sinks: - patterns: - - pattern: | - send_file ... + - pattern: $X + - pattern-not-inside: | + $P.where("...",...) + - pattern-not-inside: | + $P.where(:$KEY => $VAL,...) + - pattern-either: + - pattern-inside: | + $P.$M(...) + - pattern-inside: | + $P.$M("...",...) + - pattern-inside: | + class $P < ActiveRecord::Base + ... + end + - metavariable-regex: + metavariable: $M + regex: (where|find|first|last|select|minimum|maximum|calculate|sum|average) pattern-sources: - pattern-either: - pattern: | @@ -26570,7504 +93687,9127 @@ rules: - pattern: | request.env[...] severity: ERROR - - id: ruby.rails.security.brakeman.check-sql.check-sql + - fix-regex: + regex: =\s*false + replacement: = true + id: ruby_ssl_rule-ForceSSLFalse languages: - ruby - message: Found potential SQL injection due to unsafe SQL query construction via $X. Where possible, prefer parameterized queries. + message: "The application was found setting `force_ssl` to `false`. This setting\ncan expose the application to the risk of network\ninterception of unencrypted traffic. Enabling `force_ssl` by setting \n`config.force_ssl = true` in the application's configuration, specifically \nwithin `config/environments/production.rb`, forces the use of HTTPS, \nencrypting data in transit and safeguarding against eavesdropping or data \ntampering. \n" + metadata: + category: security + cwe: CWE-319 + owasp: + - A3:2017-Sensitive Data Exposure + - A04:2021-Insecure Design + references: + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/force-ssl-false.yaml + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + technology: + - ruby + pattern: config.force_ssl = false + severity: WARNING + - fix-regex: + regex: VERIFY_NONE + replacement: VERIFY_PEER + id: ruby_ssl_rule-SSLModeNoVerify + languages: + - ruby + message: "The application was found using `OpenSSL::SSL::VERIFY_NONE`.\nThis effectively disables the validation of TLS certificates.\n\nThis allows for an adversary who is in between the application and the \ntarget host to intercept potentially sensitive information or transmit \nmalicious data.\n\nTo remediate this issue, use 'OpenSSL::SSL::VERIFY_PEER' instead.\n" + metadata: + category: security + cwe: CWE-295 + owasp: + - A3:2017-Sensitive Data Exposure + - A07:2021-Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/ssl-mode-no-verify.yaml + security-severity: MEDIUM + shortDescription: Improper certificate validation + technology: + - ruby + pattern: OpenSSL::SSL::VERIFY_NONE + severity: WARNING + - id: ruby_xss_rule-AvoidLinkTo + languages: + - ruby + message: "This code includes user input in `link_to`. In Rails, the body of \n`link_to` is not escaped. This means that user input which reaches the \nbody will be executed when the HTML is rendered. Even in other versions, \nvalues starting with `javascript:` or `data:` are not escaped. \n\nMitigation Strategy:\nAlways sanitize user input used within `link_to` method calls. For versions of \nRails where `link_to` does not automatically escape the body, or when dealing \nwith schemes that are not escaped (`javascript:`, `data:`), manually escape or \nvalidate the input against a list of safe values. Consider using the `sanitize` \nhelper method or other Rails sanitization helpers to clean user input before \nrendering.\n\nSecure Code Example:\n```\nuser_input = params[:user_link_text]\n\n# This example uses the `sanitize` helper to ensure any HTML tags or JavaScript in the user input are escaped\nsafe_link_text = sanitize(user_input)\n\n# Use the sanitized text as the body of the `link_to` method\n<%= link_to safe_link_text, some_safe_path %>\n```\n" + metadata: + category: security + cwe: CWE-79 + owasp: + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + references: + - https://brakemanscanner.org/docs/warning_types/link_to/ + - https://brakemanscanner.org/docs/warning_types/link_to_href/ + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-link-to.yaml + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + technology: + - rails + mode: taint + pattern-sanitizers: + - patterns: + - pattern: | + "...#{...}..." + - pattern-not: | + "#{...}..." + pattern-sinks: + - pattern: link_to(...) + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + - pattern-either: + - pattern: $MODEL.url(...) + - pattern: $MODEL.uri(...) + - pattern: $MODEL.link(...) + - pattern: $MODEL.page(...) + - pattern: $MODEL.site(...) + severity: WARNING + - id: ruby_xss_rule-AvoidRenderInline + languages: + - ruby + message: "The application was found calling `render inline: ...` which renders an entire ERB template inline and is potentially dangerous.\nIf user supplied input is used, the application can be exploited by malicious \nactors via server-side template injection (SSTI) or cross-site scripting (XSS) attacks.\nInstead, consider using a partial or another safe rendering method.\n\nSecure Code Example:\n```\n# In your controller or view\nuser_input = params[:user_input]\nrender partial: 'users/user_input', locals: { user_input: user_input }\n\n# erb file\n\n\n
    \n <%= sanitize(user_input) %>\n
    \n```\n" + metadata: + category: security + cwe: CWE-79 + owasp: + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + references: + - https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#inline-renders---even-worse-than-xss + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-render-inline.yaml + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + technology: + - rails + pattern: 'render inline: ...' + severity: WARNING + - fix-regex: + regex: 'text:' + replacement: 'plain:' + id: ruby_xss_rule-AvoidRenderText + languages: + - ruby + message: "The application was found calling `render text: ...` which actually sets the \ncontent-type to 'text/html'. If external data can reach here, this exposes your \napplication to cross-site scripting (XSS) attacks. Instead, use `render plain: ...` to\nrender non-HTML text.\n" + metadata: + category: security + cwe: CWE-79 + owasp: + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + references: + - https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#inline-renders---even-worse-than-xss + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-render-text.yaml + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + technology: + - rails + pattern: 'render text: ...' + severity: WARNING + - id: ruby_xss_rule-ManualTemplateCreation + languages: + - ruby + message: "The application was identified manually creating ERB templates. Manual creation of templates\nmay expose your application to server-side template injection (SSTI) or\ncross-site scripting (XSS) attacks if user input is used to create the\ntemplate. Instead, create a '.erb' template file and use 'render'.\n\nSecure Code Example:\n```\n# Controller: messages_controller.rb\nclass MessagesController < ApplicationController\n def show\n # Safely assign user input to an instance variable\n @message_content = sanitize(params[:user_content])\n \n # Render the static .erb template\n render 'messages/show'\n end\nend\n\n\n
    \n Message: <%= @message_content %>\n
    \n```\n" + metadata: + category: security + cwe: CWE-79 + owasp: + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + references: + - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/manual-template-creation.yaml + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + technology: + - rails + pattern: ERB.new(...) + severity: WARNING + - id: yaml_spring_rule-SpringActuatorFullyEnabled + languages: + - yaml + message: "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints\nsuch as /actuator/env, /actuator/logfile, /actuator/heapdump and others.\nIf the application lacks proper security measures (e.g., authentication and \nauthorization), sensitive data could be accessed, compromising the application and \nits infrastructure. This configuration poses a serious risk in production \nenvironments or public-facing deployments.\n\nTo mitigate the risks, take the following measures:\n - Expose only the Actuator endpoints required for your use case\n - For production environments, restrict exposure to non-sensitive endpoints \n like `health` or `info`\n - Ensure Actuator endpoints are protected with authentication and authorization \n (e.g., via Spring Security)\n - Use environment-specific configurations to limit exposure in production\n\nSecure Code Example:\nInstead of include: \"*\", list only the endpoints you need to expose:\n```\nmanagement:\n endpoints:\n web:\n exposure:\n include: \"health,info,metrics\"\n```\n\nReferences:\n- https://docs.spring.io/spring-boot/reference/actuator/endpoints.html#actuator.endpoints.exposing\n- https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785\n- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators\n" + metadata: + category: security + confidence: MEDIUM + cwe: CWE-497 + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2021-Broken Access Control + - A3:2017-Sensitive Data Exposure + security-severity: Medium + shortDescription: Exposure of sensitive system information to an unauthorized control sphere + technology: + - java + patterns: + - pattern: | + management: + ... + endpoints: + ... + web: + ... + exposure: + ... + include: "*" + ... + severity: WARNING + - id: rules_lgpl_java_webview_rule-ignore-ssl-certificate-errors + languages: + - java + message: "Insecure WebView Implementation. leading to a security problem known as SSL certificate \nvalidation bypass. This occurs when the app fails to properly validate SSL certificates, \nallowing potentially malicious or spoofed certificates to be accepted, leading to a \nMan-in-the-Middle (MitM) attack where an attacker intercepts and manipulates communication \nbetween the app and the server. \n\nTo fix this security issue, you should properly handle SSL errors and only proceed with \nthe connection if the SSL certificate is valid and trusted. Here's an example code in Java:\n``` \npublic class MyWebViewClient extends WebViewClient { \n @Override\n public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {\n // Check the SSL error type\n switch (error.getPrimaryError()) {\n case SslError.SSL_UNTRUSTED:\n // Certificate is untrusted\n // Handle the error appropriately, such as showing an error message\n break;\n case SslError.SSL_EXPIRED:\n // Certificate has expired\n // Handle the error appropriately\n break;\n case SslError.SSL_IDMISMATCH:\n // Certificate hostname mismatch\n // Handle the error appropriately\n break;\n case SslError.SSL_NOTYETVALID:\n // Certificate is not yet valid\n // Handle the error appropriately\n break;\n }\n // Cancel the connection\n // This prevents the WebView from loading the content\n handler.cancel();\n }\n}\n```\n" + metadata: + category: security + cwe: CWE-295 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Improper certificate validation" + pattern: | + $RET onReceivedSslError(WebView $W, SslErrorHandler $H, SslError $E) { + ... + $H.proceed(); + } + severity: WARNING + - id: rules_lgpl_java_webview_rule-webview-debugging + languages: + - java + message: "Remote WebView debugging is enabled. This allows an attacker with\ndebugging access to interact with the webview and steal or corrupt data.\nTo fix these security issues, it is recommended to disable remote \ndebugging and restrict file access in the WebView. \nHere's how you can do it:\n```\nWebView webView = new WebView(context);\n\n// Disable remote debugging\nif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {\n WebView.setWebContentsDebuggingEnabled(false);\n}\n\n// Restrict file access from file URLs\nwebView.getSettings().setAllowFileAccessFromFileURLs(false);\n\n// Load a web page\nwebView.loadUrl(\"https://example.com\");\n```\n" + metadata: + category: security + cwe: CWE-489 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Active debug code + patterns: + - pattern-either: + - pattern: | + $WB.setWebContentsDebuggingEnabled(true); + - pattern: | + $X = true; + ... + $WB.setWebContentsDebuggingEnabled($X); + severity: WARNING + - id: rules_lgpl_java_webview_rule-webview-external-storage + languages: + - java + message: "WebView load files from external storage. Files in external storage can be\nmodified by any application.\n\nLoading files from external storage in a WebView can introduce security risks, \nas it allows web content to access potentially sensitive data stored on the \ndevice's external storage. This can lead to unauthorized access to user data, \nincluding personal files, credentials, or other sensitive information, by \nmalicious web content.\n\nTo fix this security issue, you should avoid loading files directly from external \nstorage in a WebView. Instead, you should use a Content Provider or a secure file \nstorage mechanism to access files and provide them to the WebView as content.\n\nHere's a general approach to fix this problem:\n(1) Use a Content Provider: If you need to load files from external storage in a WebView, \nconsider using a Content Provider to securely access the files. Content Providers \nprovide controlled access to files stored on external storage and allow you to define \npermissions for accessing them.\n(2) Secure File Storage: Store files containing sensitive data in a secure location, such \nas internal storage or encrypted storage, and provide access to them through a secure \nAPI. Avoid exposing sensitive files directly to the WebView.\n(3) Restrict WebView Access: Configure the WebView to restrict access to external resources \nand content. Use methods like setAllowFileAccess() to control file access and \nsetAllowContentAccess() to control access to content from other origins.\nHere's an example of how you can use a Content Provider to provide secure access to \nfiles in a WebView:\n```\n// Define the URI of the content provider for accessing files\nUri contentProviderUri = Uri.parse(\"content://com.example.myapp.provider/files\");\n// Load the content from the Content Provider into the WebView\nwebView.loadUrl(contentProviderUri.toString());\n```\nIn the above code, we define the URI of a Content Provider that provides access to files \nstored in the app's external storage. The content is loaded from the Content Provider into \nthe WebView using loadUrl(), which ensures that access to files is controlled and secure, \npreventing unauthorized access to sensitive data.\n" + metadata: + category: security + cwe: CWE-749 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Exposed dangerous method or function + patterns: + - pattern-either: + - pattern: | + $X = <... $E.getExternalStorageDirectory() ...>; + ... + $WV.loadUrl(<... $X ...>); + - pattern: | + $WV.loadUrl(<... $E.getExternalStorageDirectory().$F() ...>); + - pattern: | + $X = <... Environment.getExternalStorageDirectory().$F() ...>; + ... + $WV.loadUrl(<... $X ...>); + - pattern: | + $X = <... $E.getExternalFilesDir(...) ...>; + ... + $WV.loadUrl(<... $X ...>); + severity: ERROR + - id: rules_lgpl_java_webview_rule-webview-set-allow-file-access + languages: + - java + message: "WebView File System Access is enabled. An attacker able to inject \nscript into a WebView, could exploit the opportunity to unauthorized \naccess to sensitive user data or system files.\n\nTo fix this security issue, you should disable file access in the \nWebView or restrict it to specific directories. \nAn example:\n```\n// Create a WebView instance\nWebView webView = new WebView(context);\n// Disable file access in the WebView\nwebView.getSettings().setAllowFileAccess(false);\n```\n" + metadata: + category: security + cwe: CWE-73 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: External control of file name or path + pattern: $WB.setAllowFileAccess(true); + severity: WARNING + - id: rules_lgpl_javascript_crypto_rule-node-aes-ecb + languages: + - javascript + message: | + AES with ECB mode is deterministic in nature and not suitable for encrypting large amount of repetitive data. + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: + - pattern: | + $X.createCipheriv("=~/^aes-([0-9]+)-ecb$/i", ...) + - pattern: | + $X.createDecipheriv("=~/^aes-([0-9]+)-ecb$/i", ...) + severity: WARNING + - id: rules_lgpl_javascript_crypto_rule-node-aes-noiv + languages: + - javascript + message: | + AES algorithms requires an initialization vector (IV). Providing no or null IV in some implementation results to a 0 IV. Use of a deterministic IV makes dictionary attacks easier. + metadata: + category: security + cwe: CWE-327 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Use of a broken or risky cryptographic algorithm + patterns: + - pattern-either: + - pattern: | + $X.createCipheriv("=~/^aes-/i", $KEY, "", ...) + severity: WARNING + - id: rules_lgpl_javascript_crypto_rule-node-insecure-random-generator + languages: + - javascript + message: "This rule identifies use of cryptographically weak random number generators.\nUsing cryptographically weak random number generators like `crypto.pseudoRandomBytes()` \nand `Math.random()` for security-critical tasks can expose systems to significant \nvulnerabilities. Attackers might predict the generated random numbers, compromising \nthe integrity and confidentiality of cryptographic operations. This could lead to \nbreaches where sensitive data is accessed or manipulated, authentication mechanisms \nare bypassed, or secure communications are intercepted, ultimately undermining the \nsecurity of the entire system or application.\n\nMitigation strategy:\nReplace the use of these cryptographically weak random number generators with \n`crypto.randomBytes()`, a method provided by Node.js's `crypto` module that \ngenerates cryptographically secure random numbers. This method should be used \nfor all operations requiring secure randomness, such as generating keys, tokens, \nor any cryptographic material.\n\nSecure Code Example:\n```\nconst crypto = require('crypto');\nconst secureBytes = crypto.randomBytes(256);\nconsole.log(`Secure random bytes: ${secureBytes.toString('hex')}`);\n```\n" + metadata: + category: security + cwe: CWE-338 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Use of cryptographically weak pseudo-random number generator (PRNG) + pattern-either: + - patterns: + - pattern-inside: | + require('crypto') + ... + - pattern: | + $X.pseudoRandomBytes(...) + - pattern: | + Math.random(...) + severity: WARNING + - id: rules_lgpl_javascript_crypto_rule-node-md5 + languages: + - javascript + message: "The MD5 hashing algorithm is considered cryptographically weak and \nvulnerable to collision attacks, where two different inputs generate \nthe same output hash. When used for hashing sensitive data, attackers \ncan exploit this weakness to generate collisions, allowing them to bypass \nsecurity checks or masquerade malicious data as legitimate. This \nvulnerability is particularly critical in authentication mechanisms, \ndigital signatures, SSL/TLS certificates, and data integrity checks.\n\nRemediation:\nTo mitigate this vulnerability, replace the MD5 hashing algorithm with \nstronger cryptographic hash functions, such as SHA-256 or SHA-3. These \nalgorithms offer significantly improved security and are resistant to \ncollision attacks, making them suitable for cryptographic purposes in \nmodern applications.\n\nSecure Code example :\n```\nconst crypto = require('crypto');\nconst hash = crypto.createHash('sha256').update('sensitive data').digest('hex');\nconsole.log(hash); \n```\n" + metadata: + category: security + cwe: CWE-328 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Use of weak hash + pattern-either: + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $Y = $X.createHash('md5') + ... + - pattern: | + $Y.update("...") + - pattern: | + $X.createHash('md5').update("...") + - patterns: + - pattern-inside: | + require('crypto-js') + ... + - pattern: | + $X.MD5("...") + - patterns: + - pattern-either: + - pattern-inside: | + $M = require('md5') + ... + - pattern-inside: | + $M = require('blueimp-md5') + ... + - pattern-inside: | + $M = require('js-md5') + ... + - pattern: | + $M("...") + - patterns: + - pattern-inside: | + require('node-forge') + ... + - pattern-either: + - patterns: + - pattern-inside: | + $Y = $X.md.md5.create() + ... + - pattern: | + $Y.update("...") + - pattern: | + $X.md.md5.create().update("...") + - patterns: + - pattern-inside: | + $X = require('jshashes') + ... + $Y = new $X.MD5() + ... + - pattern: | + $Y.$METHOD("...") + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $X = require('create-hash') + ... + $Y = $X('md5') + ... + - pattern: | + $Y.update("...") + - patterns: + - pattern-inside: | + $X = require('create-hash') + ... + - pattern: "$X('md5').update(\"...\") \n" + severity: WARNING + - id: rules_lgpl_javascript_crypto_rule-node-sha1 + languages: + - javascript + message: "The SHA-1 hashing algorithm is no longer considered secure for\ncryptographic applications due to its vulnerability to collision attacks,\nwhere two different inputs produce the same output hash. SHA-1's\nsusceptibility to collision attacks undermines the security of\ncryptographic operations, allowing attackers to forge signatures or\nmanipulate data without detection. This poses significant risks in\nauthentication systems, data integrity validations, and secure\ncommunications. \n\nRemediation: To mitigate this vulnerability, replace the SHA1 hashing \nalgorithm with stronger cryptographic hash functions, such as SHA-256 \nor SHA-3. These algorithms offer significantly improved security and \nare resistant to collision attacks, making them suitable for cryptographic \npurposes in modern applications.\n\nSecure Code example: \n``` \nconst crypto = require('crypto'); \nconst hash = crypto.createHash('sha256').update('sensitive data').digest('hex'); \nconsole.log(hash); \n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-328 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/SQL_Injection - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/models/product.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_sql.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sanitizers: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Use of weak hash + pattern-either: - patterns: - pattern-either: - patterns: - - pattern: $X - - pattern-either: - - pattern-inside: | - :$KEY => $X - - pattern-inside: | - ["...",$X,...] - - pattern: | - params[...].to_i - - pattern: | - params[...].to_f - - patterns: + - pattern-inside: | + $Y = $X.createHash('sha1') + ... - pattern: | - params[...] ? $A : $B - - metavariable-pattern: - metavariable: $A - patterns: - - pattern-not: | - params[...] - - metavariable-pattern: - metavariable: $B - patterns: - - pattern-not: | - params[...] - pattern-sinks: + $Y.update("...") + - pattern: | + $X.createHash('sha1').update("...") + - patterns: + - pattern-inside: | + require('crypto-js') + ... + - pattern: | + $X.SHA1("...") - patterns: - - pattern: $X - - pattern-not-inside: | - $P.where("...",...) - - pattern-not-inside: | - $P.where(:$KEY => $VAL,...) - pattern-either: - pattern-inside: | - $P.$M(...) + $M = require('sha1') + ... - pattern-inside: | - $P.$M("...",...) - - pattern-inside: | - class $P < ActiveRecord::Base - ... - end - - metavariable-regex: - metavariable: $M - regex: (where|find|first|last|select|minimum|maximum|calculate|sum|average) - pattern-sources: - - pattern-either: + $M = require('js-sha1') + ... - pattern: | - cookies[...] - - patterns: + $M("...") + - patterns: + - pattern-inside: | + require('node-forge') + ... + - pattern-either: + - patterns: + - pattern-inside: | + $Y = $X.md.sha1.create() + ... + - pattern: | + $Y.update("...") - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] + $X.md.sha1.create().update("...") + - patterns: + - pattern-inside: | + $X = require('jshashes') + ... + $Y = new $X.SHA1() + ... - pattern: | - request.env[...] - severity: ERROR - - id: ruby.rails.security.brakeman.check-unsafe-reflection-methods.check-unsafe-reflection-methods - languages: - - ruby - message: Found user-controllable input to a reflection method. This may allow a user to alter program behavior and potentially execute arbitrary instructions in the context of the process. Do not provide arbitrary user input to `tap`, `method`, or `to_proc` - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails6/app/controllers/groups_controller.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unsafe_reflection_methods.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sinks: + $Y.$METHOD("...") - patterns: - - pattern: $X + - pattern-inside: | + require('hash.js') + ... - pattern-either: - - pattern-inside: | - $X. ... .to_proc - patterns: - pattern-inside: | - $Y.method($Z) - - focus-metavariable: $Z + $Y = $X.sha1() + ... + - pattern: | + $Y.update("...") + - pattern: | + $X.sha1().update("...") + - patterns: + - pattern-inside: | + $X = require('jssha') + ... + - pattern-either: + - pattern: | + new $X('SHA-1', ...).update("...") - patterns: - pattern-inside: | - $Y.tap($Z) - - focus-metavariable: $Z + $Y = new $X('SHA-1', ...) + ... + - pattern: | + $Y.update("...") + - patterns: + - pattern-either: + - pattern: | + $X('sha1').update("...") - patterns: - pattern-inside: | - $Y.tap{ |$ANY| $Z } - - focus-metavariable: $Z - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: + $Y = $X('sha1') + ... + - pattern: | + $Y.update("...") + - pattern: | + $X.subtle.digest('SHA-1', ...) + - patterns: + - pattern-either: - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - severity: ERROR - - id: ruby.rails.security.brakeman.check-unsafe-reflection.check-unsafe-reflection + $X.SHA1.digest(...) + - patterns: + - pattern-inside: | + $Y = $X.SHA1 + ... + - pattern: "$Y.digest(...) \n" + - patterns: + - pattern-either: + - pattern: | + $X.codec.hex.fromBits($SJCL) + - patterns: + - pattern-inside: | + $Y = $SJCL + ... + - pattern: | + $X.codec.hex.fromBits($Y) + - metavariable-pattern: + metavariable: $SJCL + pattern: | + $K.hash.sha1.hash("...") + severity: WARNING + - id: rules_lgpl_javascript_crypto_rule-node-timing-attack languages: - - ruby - message: Found user-controllable input to Ruby reflection functionality. This allows a remote user to influence runtime behavior, up to and including arbitrary remote code execution. Do not provide user-controllable input to reflection functionality. Do not call symbol conversion on user-controllable input. + - javascript + message: | + 'String comparisons using ''==='', ''!=='', ''!='' and ''=='' is vulnerable to timing attacks. More info: https://snyk.io/blog/node-js-timing-attack-ccc-ctf/' metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-208 owasp: - - A03:2021 - Injection - references: - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails2/app/controllers/application_controller.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unsafe_reflection.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern: $X - - pattern-either: - - pattern-inside: | - $X.constantize - - pattern-inside: | - $X. ... .safe_constantize - - pattern-inside: | - const_get(...) - - pattern-inside: | - qualified_const_get(...) - pattern-sources: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Observable timing discrepancy + patterns: + - pattern-not: if ($Z == null) { ... }; + - pattern-not: if ($Z === null) { ... }; + - pattern-not: if ($Z != null) { ... }; + - pattern-not: if ($Z !== null) { ... }; + - pattern-not: if ($Q != undefined) { ... }; + - pattern-not: if ($Q !== undefined) { ... }; + - pattern-not: if ($Q == undefined) { ... }; + - pattern-not: if ($Q === undefined) { ... }; + - pattern-not: return $Y == null; + - pattern-not: return $Y === null; + - pattern-not: return $Y != null; + - pattern-not: return $Y !== null; + - pattern-not: return $Y == undefined; + - pattern-not: return $Y === undefined; + - pattern-not: return $Y != undefined; + - pattern-not: return $Y !== undefined; - pattern-either: - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) + if (password == $X) { + ... + } + - pattern: | + if ($X == password) { + ... + } + - pattern: | + if (password === $X) { + ... + } + - pattern: | + if ($X === password) { + ... + } + - pattern: | + if (pass == $X) { + ... + } + - pattern: | + if ($X == pass) { + ... + } + - pattern: | + if (pass === $X) { + ... + } + - pattern: | + if ($X === pass) { + ... + } + - pattern: | + if (secret == $X) { + ... + } + - pattern: | + if ($X == secret) { + ... + } + - pattern: | + if (secret === $X) { + ... + } + - pattern: | + if ($X === secret) { + ... + } + - pattern: | + if (api == $X) { + ... + } + - pattern: | + if ($X == api) { + ... + } + - pattern: | + if (api === $X) { + ... + } + - pattern: | + if ($X === api) { + ... + } + - pattern: | + if (apiKey == $X) { + ... + } + - pattern: | + if ($X == apiKey) { + ... + } + - pattern: | + if (apiKey === $X) { + ... + } + - pattern: | + if ($X === apiKey) { + ... + } + - pattern: | + if (apiSecret == $X) { + ... + } + - pattern: | + if ($X == apiSecret) { + ... + } + - pattern: | + if (apiSecret === $X) { + ... + } + - pattern: | + if ($X === apiSecret) { + ... + } + - pattern: | + if (token == $X) { + ... + } + - pattern: | + if ($X == token) { + ... + } + - pattern: | + if (token === $X) { + ... + } + - pattern: | + if ($X === token) { + ... + } + - pattern: | + if (hash == $X) { + ... + } + - pattern: | + if ($X == hash) { + ... + } + - pattern: | + if (hash === $X) { + ... + } + - pattern: | + if ($X === hash) { + ... + } + - pattern: | + if (auth_token == $X) { + ... + } + - pattern: | + if ($X == auth_token) { + ... + } + - pattern: | + if (auth_token === $X) { + ... + } + - pattern: | + if ($X === auth_token) { + ... + } + - pattern: | + if (password != $X) { + ... + } + - pattern: | + if ($X != password) { + ... + } + - pattern: | + if (password !== $X) { + ... + } + - pattern: | + if ($X !== password) { + ... + } + - pattern: | + if (pass != $X) { + ... + } + - pattern: | + if ($X != pass) { + ... + } + - pattern: | + if (pass !== $X) { + ... + } + - pattern: | + if ($X !== pass) { + ... + } + - pattern: | + if (secret != $X) { + ... + } + - pattern: | + if ($X != secret) { + ... + } + - pattern: | + if (secret !== $X) { + ... + } + - pattern: | + if ($X !== secret) { + ... + } + - pattern: | + if (api != $X) { + ... + } + - pattern: | + if ($X != api) { + ... + } + - pattern: | + if (api !== $X) { + ... + } + - pattern: | + if ($X !== api) { + ... + } + - pattern: | + if (apiKey != $X) { + ... + } + - pattern: | + if ($X != apiKey) { + ... + } + - pattern: | + if (apiKey !== $X) { + ... + } + - pattern: | + if ($X !== apiKey) { + ... + } + - pattern: | + if (apiSecret != $X) { + ... + } + - pattern: | + if ($X != apiSecret) { + ... + } + - pattern: | + if (apiSecret !== $X) { + ... + } + - pattern: | + if ($X !== apiSecret) { + ... + } + - pattern: | + if (token != $X) { + ... + } + - pattern: | + if ($X != token) { + ... + } + - pattern: | + if (token !== $X) { + ... + } + - pattern: | + if ($X !== token) { + ... + } + - pattern: | + if (hash != $X) { + ... + } + - pattern: | + if ($X != hash) { + ... + } + - pattern: | + if (hash !== $X) { + ... + } + - pattern: | + if ($X !== hash) { + ... + } + - pattern: | + if (auth_token != $X) { + ... + } + - pattern: | + if ($X != auth_token) { + ... + } + - pattern: | + if (auth_token !== $X) { + ... + } + - pattern: | + if ($X !== auth_token) { + ... + } + - pattern: | + return $X === auth_token; + - pattern: | + return auth_token === $X; + - pattern: | + return $X === token; + - pattern: | + return token === $X; + - pattern: | + return $X === hash; + - pattern: | + return hash === $X; + - pattern: | + return $X === password; + - pattern: | + return password === $X; + - pattern: | + return $X === pass; + - pattern: | + return pass === $X; + - pattern: | + return $X === apiKey; + - pattern: | + return apiKey === $X; + - pattern: | + return $X === apiSecret; + - pattern: | + return apiSecret === $X; + - pattern: | + return $X === api_key; + - pattern: | + return api_key === $X; + - pattern: | + return $X === api_secret; + - pattern: | + return api_secret === $X; + - pattern: | + return $X === secret; + - pattern: | + return secret === $X; + - pattern: | + return $X === api; + - pattern: | + return api === $X; + - pattern: | + return $X == auth_token; + - pattern: | + return auth_token == $X; + - pattern: | + return $X == token; + - pattern: | + return token == $X; + - pattern: | + return $X == hash; + - pattern: | + return hash == $X; + - pattern: | + return $X == password; + - pattern: | + return password == $X; + - pattern: | + return $X == pass; + - pattern: | + return pass == $X; + - pattern: | + return $X == apiKey; + - pattern: | + return apiKey == $X; + - pattern: | + return $X == apiSecret; + - pattern: | + return apiSecret == $X; + - pattern: | + return $X == api_key; + - pattern: | + return api_key == $X; + - pattern: | + return $X == api_secret; + - pattern: | + return api_secret == $X; + - pattern: | + return $X == secret; + - pattern: | + return secret == $X; + - pattern: | + return $X == api; + - pattern: | + return api == $X; + - pattern: | + return $X !== auth_token; + - pattern: | + return auth_token !== $X; + - pattern: | + return $X !== token; + - pattern: | + return token !== $X; + - pattern: | + return $X !== hash; + - pattern: | + return hash !== $X; + - pattern: | + return $X !== password; + - pattern: | + return password !== $X; + - pattern: | + return $X !== pass; + - pattern: | + return pass !== $X; + - pattern: | + return $X !== apiKey; + - pattern: | + return apiKey !== $X; + - pattern: | + return $X !== apiSecret; + - pattern: | + return apiSecret !== $X; + - pattern: | + return $X !== api_key; + - pattern: | + return api_key !== $X; + - pattern: | + return $X !== api_secret; + - pattern: | + return api_secret !== $X; + - pattern: | + return $X !== secret; + - pattern: | + return secret !== $X; + - pattern: | + return $X !== api; + - pattern: | + return api !== $X; + - pattern: | + return $X != auth_token; + - pattern: | + return auth_token != $X; + - pattern: | + return $X != token; + - pattern: | + return token != $X; + - pattern: | + return $X != hash; + - pattern: | + return hash != $X; + - pattern: | + return $X != password; + - pattern: | + return password != $X; + - pattern: | + return $X != pass; + - pattern: | + return pass != $X; + - pattern: | + return $X != apiKey; + - pattern: | + return apiKey != $X; + - pattern: | + return $X != apiSecret; - pattern: | - params[...] + return apiSecret != $X; - pattern: | - request.env[...] - severity: ERROR - - id: ruby.rails.security.brakeman.check-unscoped-find.check-unscoped-find - languages: - - ruby - message: Found an unscoped `find(...)` with user-controllable input. If the ActiveRecord model being searched against is sensitive, this may lead to Insecure Direct Object Reference (IDOR) behavior and allow users to read arbitrary records. Scope the find to the current user, e.g. `current_user.accounts.find(params[:id])`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-639: Authorization Bypass Through User-Controlled Key' - impact: HIGH - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/unscoped_find/ - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/controllers/users_controller.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unscoped_find.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $MODEL.find(...) - - pattern: $MODEL.find_by_id(...) - - pattern: $MODEL.find_by_id!(...) - - metavariable-regex: - metavariable: $MODEL - regex: '[A-Z]\S+' - pattern-sources: - - pattern-either: + return $X != api_key; - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) + return api_key != $X; - pattern: | - params[...] + return $X != api_secret; - pattern: | - request.env[...] + return api_secret != $X; + - pattern: | + return $X != secret; + - pattern: | + return secret != $X; + - pattern: | + return $X != api; + - pattern: | + return api != $X; severity: WARNING - - id: ruby.rails.security.brakeman.check-validation-regex.check-validation-regex + - id: rules_lgpl_javascript_crypto_rule-node-tls-reject languages: - - ruby - message: $V Found an incorrectly-bounded regex passed to `validates_format_of` or `validate ... format => ...`. Ruby regex behavior is multiline by default and lines should be terminated by `\A` for beginning of line and `\Z` for end of line, respectively. + - javascript + message: "The application sets NODE_TLS_REJECT_UNAUTHORIZED to '0', which instructs Node.js to disable TLS/SSL certificate validation. \nThis configuration allows the application to accept self-signed certificates or certificates from untrusted authorities, \nundermining the TLS security model. Disabling TLS/SSL certificate validation compromises the integrity and confidentiality \nof data in transit between the client and server. It makes the application vulnerable to man-in-the-middle (MITM) attacks, \nwhere an attacker could intercept or alter the data being exchanged.\n\nMitigation Strategy:\nDo not disable TLS/SSL certificate validation in production environments. Ensure that NODE_TLS_REJECT_UNAUTHORIZED is \nset to '1' or is removed entirely from the production configuration (as the default configuration of validating SSL \ncertificate is safe).\n\nSecure Code Example:\n```\nconst https = require('https')\nprocess.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '1'\nconst req = https.request(options, res => {\n let data = ''\n res.on('data', chunk => {\n data += chunk\n })\n res.on('end', () => {\n console.log('Response Body:', data)\n })\n})\nreq.end()\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-185: Incorrect Regular Expression' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-295 owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/format_validation/ - - https://github.com/presidentbeef/brakeman/blob/aef6253a8b7bcb97116f2af1ed2a561a6ae35bd5/test/apps/rails3/app/models/account.rb - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/models/account.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_validation_regex.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: search + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Improper Certificate Validation patterns: - pattern-either: - pattern: | - validates ..., :format => <... $V ...>,... + $X.env.NODE_TLS_REJECT_UNAUTHORIZED = $VAL - pattern: | - validates_format_of ..., :with => <... $V ...>,... - - metavariable-regex: - metavariable: $V - regex: /(.{2}(? $X,...) - - focus-metavariable: $X - - patterns: - - pattern: | - "$SQLVERB#{$EXPR}..." - - pattern-not-inside: | - $FUNC("...", "...#{$EXPR}...",...) - - focus-metavariable: $SQLVERB - - pattern-regex: (?i)(select|delete|insert|create|update|alter|drop)\b - - patterns: - - pattern-either: - - pattern: Kernel::sprintf("$SQLSTR", $EXPR) - - pattern: | - "$SQLSTR" + $EXPR - - pattern: | - "$SQLSTR" % $EXPR - - pattern-not-inside: | - $FUNC("...", "...#{$EXPR}...",...) - - focus-metavariable: $EXPR - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b - pattern-sources: - - patterns: - - pattern-either: - - pattern: params - - pattern: request + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of special elements used in an SQL command (SQL Injection) + patterns: + - pattern-either: + - pattern-inside: | + $KNEX = require('knex') + ... + - pattern-inside: | + $KNEX = require('knex')(...) + ... + - pattern-either: + - pattern: | + $K.raw(<... $REQ.$QUERY.$VAR ...>, ...) + - pattern: | + $K.raw(<... $REQ.$QUERY ...>, ...) + - pattern: | + $SQL = <... $REQ.$QUERY.$VAR ...>; + ... + $K.raw(<... $SQL ...>, ...) + - pattern: | + $SQL = <... $REQ.$QUERY ...>; + ... + $K.raw(<... $SQL ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY.$VAR ...>; + ... + $SQL = <... $INP ...>; + ... + $K.raw(<... $SQL ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + $SQL = <... $INP ...>; + ... + $K.raw(<... $SQL ...>, ...) + - pattern: | + $K.whereRaw(<... $REQ.$QUERY.$VAR ...>, ...) + - pattern: | + $K.whereRaw(<... $REQ.$QUERY ...>, ...) + - pattern: | + $SQL = <... $REQ.$QUERY.$VAR ...>; + ... + $K.whereRaw(<... $SQL ...>, ...) + - pattern: | + $SQL = <... $REQ.$QUERY ...>; + ... + $K.whereRaw(<... $SQL ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY.$VAR ...>; + ... + $SQL = <... $INP ...>; + ... + $K.whereRaw(<... $SQL ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + $SQL = <... $INP ...>; + ... + $K.whereRaw(<... $SQL ...>, ...) severity: ERROR - - id: ruby.rails.security.injection.tainted-url-host.tainted-url-host + - id: rules_lgpl_javascript_database_rule-node-nosqli-injection languages: - - ruby - message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Use the `ssrf_filter` gem and guard the url construction with `SsrfFilter(...)`, or create an allowlist for approved hosts. + - javascript + message: | + Untrusted user input in findOne() function can result in NoSQL Injection. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM + cwe: CWE-943 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - - https://github.com/arkadiyt/ssrf_filter - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sanitizers: - - pattern: SsrfFilter - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: | - $URLSTR - - pattern-regex: \w+:\/\/#{.*} - - patterns: - - pattern-either: - - pattern: Kernel::sprintf("$URLSTR", ...) - - pattern: | - "$URLSTR" + $EXPR - - pattern: | - "$URLSTR" % $EXPR - - metavariable-pattern: - language: generic - metavariable: $URLSTR - pattern: $SCHEME:// ... - pattern-sources: - - patterns: - - pattern-either: - - pattern: params - - pattern: request - severity: WARNING - - id: rust.lang.security.args-os.args-os - languages: - - rust - message: 'args_os should not be used for security operations. From the docs: "The first element is traditionally the path of the executable, but it can be set to arbitrary text, and might not even exist. This means this property should not be relied upon for security purposes."' - metadata: - category: security - confidence: HIGH - cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' - impact: LOW - likelihood: LOW - references: - - https://doc.rust-lang.org/stable/std/env/fn.args_os.html - subcategory: audit - technology: - - rust - pattern: std::env::args_os() - severity: INFO - - id: rust.lang.security.args.args - languages: - - rust - message: 'args should not be used for security operations. From the docs: "The first element is traditionally the path of the executable, but it can be set to arbitrary text, and might not even exist. This means this property should not be relied upon for security purposes."' - metadata: - category: security - confidence: HIGH - cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' - impact: LOW - likelihood: LOW - references: - - https://doc.rust-lang.org/stable/std/env/fn.args.html - subcategory: audit - technology: - - rust - pattern: std::env::args() - severity: INFO - - id: rust.lang.security.current-exe.current-exe - languages: - - rust - message: 'current_exe should not be used for security operations. From the docs: "The output of this function should not be trusted for anything that might have security implications. Basically, if users can run the executable, they can change the output arbitrarily."' - metadata: - category: security - confidence: HIGH - cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' - impact: LOW - likelihood: LOW - references: - - https://doc.rust-lang.org/stable/std/env/fn.current_exe.html#security - subcategory: audit - technology: - - rust - pattern: std::env::current_exe() - severity: INFO - - id: rust.lang.security.insecure-hashes.insecure-hashes - languages: - - rust - message: Detected cryptographically insecure hashing function - metadata: - category: security - confidence: HIGH - cwe: 'CWE-328: Use of Weak Hash' - impact: MEDIUM - likelihood: LOW - references: - - https://github.com/RustCrypto/hashes - - https://docs.rs/md2/latest/md2/ - - https://docs.rs/md4/latest/md4/ - - https://docs.rs/md5/latest/md5/ - - https://docs.rs/sha-1/latest/sha1/ - subcategory: audit - technology: - - rust - pattern-either: - - pattern: md2::Md2::new(...) - - pattern: md4::Md4::new(...) - - pattern: md5::Md5::new(...) - - pattern: sha1::Sha1::new(...) - severity: WARNING - - id: rust.lang.security.reqwest-accept-invalid.reqwest-accept-invalid + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of special elements in data query logic + patterns: + - pattern-not-inside: | + $SANITIZE = require('mongo-sanitize') + ... + $SANITIZE(...) + ... + - pattern-not-inside: | + import $SANITIZE from 'mongo-sanitize' + ... + $SANITIZE(...) + ... + - pattern-not: | + $OBJ.findOne({$KEY : String(...).$FUNC()}, ...) + - pattern-not: | + $OBJ.findOne({$KEY : String(...).$FUNC}, ...) + - pattern-not: | + $OBJ.findOne({$KEY : String(...)}, ...) + - pattern-either: + - pattern: | + $OBJ.findOne({$KEY : <... $REQ.$FOO.$BAR ...> }, ...) + - pattern: | + $OBJ.findOne({$KEY: <... $REQ.$FOO ...> }, ...) + - pattern: | + $INP = <... $REQ.$FOO.$BAR ...>; + ... + $OBJ.findOne({$KEY : <... $INP ...> }, ...) + - pattern: | + $INP = <... $REQ.$FOO ...>; + ... + $OBJ.findOne({$KEY: <... $INP ...> }, ...) + - pattern: | + $QUERY = {$KEY: <... $REQ.$FOO.$BAR ...>}; + ... + $OBJ.findOne($QUERY, ...) + - pattern: | + $QUERY = {$KEY: <... $REQ.$FOO ...>}; + ... + $OBJ.findOne($QUERY, ...) + - pattern: | + $INP = <... $REQ.$FOO.$BAR ...>; + ... + $QUERY = {$KEY : <... $INP ...> }; + ... + $OBJ.findOne(<... $QUERY ...>, ...) + - pattern: | + $INP = <... $REQ.$FOO ...>; + ... + $QUERY = {$KEY : <... $INP ...> }; + ... + $OBJ.findOne(<... $QUERY ...>, ...) + - pattern: | + $QUERY[$KEY] = <... $REQ.$FOO.$BAR ...>; + ... + $OBJ.findOne($QUERY, ...) + - pattern: | + $QUERY[$KEY] = <... $REQ.$FOO ...>; + ... + $OBJ.findOne($QUERY, ...) + - pattern: | + $INP = <... $REQ.$FOO.$BAR ...>; + ... + $QUERY[$KEY] = <... $INP ...>; + ... + $OBJ.findOne(<... $QUERY ...>, ...) + - pattern: | + $INP = <... $REQ.$FOO ...>; + ... + $QUERY[$KEY] = <... $INP ...>; + ... + $OBJ.findOne(<... $QUERY ...>, ...) + severity: ERROR + - id: rules_lgpl_javascript_database_rule-node-nosqli-js-injection languages: - - rust - message: Dangerously accepting invalid TLS information + - javascript + message: | + Untrusted user input in MongoDB $where operator can result in NoSQL JavaScript Injection. metadata: category: security - confidence: HIGH - cwe: 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: LOW - references: - - https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.danger_accept_invalid_hostnames - - https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.danger_accept_invalid_certs - subcategory: vuln - technology: - - reqwest - pattern-either: - - pattern: reqwest::Client::builder(). ... .danger_accept_invalid_hostnames(true) - - pattern: reqwest::Client::builder(). ... .danger_accept_invalid_certs(true) - severity: WARNING - - id: rust.lang.security.reqwest-set-sensitive.reqwest-set-sensitive + cwe: CWE-943 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of special elements in data query logic + patterns: + - pattern-either: + - pattern: | + $OBJ.$FUNC({$where: <... $REQ.$FOO.$BAR ...>}, ...) + - pattern: | + $OBJ.$FUNC({$where: <... $REQ.$QUERY ...>}, ...) + - pattern: | + $NSQL = <... $REQ.$QUERY.$...>; + ... + $OBJ.$FUNC({$where: <... $NSQL ...>}, ...) + - pattern: | + $NSQL = <... $REQ.$QUERY ...>; + ... + $OBJ.$FUNC({$where: <... $NSQL ...>}, ...) + - pattern: | + $INP = $REQ.$FOO.$BAR; + ... + $QRY = {$where: <... $INP ...>}; + ... + $OBJ.$FUNC(<... $QRY ...>, ...) + - pattern: | + $INP = $REQ.$FOO; + ... + $QRY = {$where: <... $INP ...>}; + ... + $OBJ.$FUNC(<... $QRY ...>, ...) + - pattern: | + $QRY["$where"] = <... $REQ.$FOO ...>; + ... + $OBJ.$FUNC(<... $QRY ...>, ...) + - pattern: | + $QRY["$where"] = <... $REQ.$FOO.$BAR ...>; + ... + $OBJ.$FUNC(<... $QRY ...>, ...) + - pattern: | + $INP = $REQ.$FOO; + ... + $QRY["$where"] = <... $INP ...>; + ... + $OBJ.$FUNC(<... $QRY ...>, ...) + - pattern: | + $INP = $REQ.$FOO.$BAR; + ... + $QRY["$where"] = <... $INP ...>; + ... + $OBJ.$FUNC(<... $QRY ...>, ...) + severity: ERROR + - id: rules_lgpl_javascript_database_rule-node-sqli-injection languages: - - rust - message: Set sensitive flag on security headers with 'set_sensitive' to treat data with special care + - javascript + message: | + Untrusted input concatinated with raw SQL query can result in SQL Injection. metadata: category: security - confidence: MEDIUM - cwe: 'CWE-921: Storage of Sensitive Data in a Mechanism without Access Control' - impact: LOW - likelihood: LOW - references: - - https://docs.rs/reqwest/latest/reqwest/header/struct.HeaderValue.html#method.set_sensitive - subcategory: audit - technology: - - reqwest + cwe: CWE-89 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of special elements used in an SQL command (SQL Injection) patterns: - - pattern: | - let mut $HEADERS = header::HeaderMap::new(); - ... - let $HEADER_VALUE = <... header::HeaderValue::$FROM_FUNC(...) ...>; + - pattern-inside: | + require('$LIB') ... - $HEADERS.insert($HEADER, $HEADER_VALUE); + - metavariable-regex: + metavariable: $LIB + regex: \b(sql-client|mysql|pg|mssql|oracledb|sequelize)\b - pattern-not: | - let mut $HEADERS = header::HeaderMap::new(); - ... - let $HEADER_VALUE = <... header::HeaderValue::$FROM_FUNC(...) ...>; - ... - $HEADER_VALUE.set_sensitive(true); + $CON.query("..." + "...", ...) + - pattern-not: | + $SQL = "..."; ... - $HEADERS.insert($HEADER, $HEADER_VALUE); - - metavariable-pattern: - metavariable: $FROM_FUNC - pattern-either: - - pattern: from_static - - pattern: from_str - - pattern: from_name - - pattern: from_bytes - - pattern: from_maybe_shared - - metavariable-pattern: - metavariable: $HEADER - pattern-either: - - pattern: header::AUTHORIZATION - - pattern: '"Authorization"' - severity: INFO - - id: rust.lang.security.rustls-dangerous.rustls-dangerous + $CON.query(<... $SQL ...>, ...) + - pattern-either: + - pattern: | + $CON.query(<... $REQ.$QUERY ...>, ...) + - pattern: | + $SQL = <... $REQ.$QUERY ...>; + ... + $CON.query(<... $SQL ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + $SQL = <... $INP ...>; + ... + $CON.query(<... $SQL ...>, ...) + - pattern: | + $CON.query(`...${...}...`, ...) + - pattern: | + $CON.query("..."+...+"...", ...) + - pattern: | + $SQL = <... $INP ...>; + ... + $CON.query(<... $SQL ...>, ...) + severity: ERROR + - id: rules_lgpl_javascript_database_rule-sequelize-tls languages: - - rust - message: Dangerous client config used, ensure SSL verification + - javascript + message: | + 'The Sequelize connection string indicates that database server does not use TLS. Non TLS connections are susceptible to man in the middle (MITM) attacks.' metadata: category: security - confidence: HIGH - cwe: 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: LOW - references: - - https://docs.rs/rustls/latest/rustls/client/struct.DangerousClientConfig.html - - https://docs.rs/rustls/latest/rustls/client/struct.ClientConfig.html#method.dangerous - subcategory: vuln - technology: - - rustls - pattern-either: - - pattern: rustls::client::DangerousClientConfig - - pattern: $CLIENT.dangerous().set_certificate_verifier(...) + cwe: CWE-319 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + patterns: - pattern: | - let $CLIENT = rustls::client::ClientConfig::dangerous(...); - ... - $CLIENT.set_certificate_verifier(...); + { + host: $HOST, + database: $DATABASE, + dialect: $DIALECT + } + - pattern-not: | + { + host: $HOST, + database: $DATABASE, + dialect: "postgres", + dialectOptions: { + ssl: true + } + } + - pattern-not: | + { + host: $HOST, + database: $DATABASE, + dialect: $DIALECT, + dialectOptions: { + ssl: { ... } + } + } + - metavariable-regex: + metavariable: $DIALECT + regex: '[''"](mariadb|mysql|postgres|oracle)[''"]' severity: WARNING - - id: rust.lang.security.ssl-verify-none.ssl-verify-none + - id: rules_lgpl_javascript_database_rule-sequelize-tls-cert-validation languages: - - rust - message: SSL verification disabled, this allows for MitM attacks + - javascript + message: "The Sequelize connection string indicates that TLS certificate validation \nof database server is disabled. This is equivalent to not having TLS. An \nattacker can present any invalid certificate and Sequelize will make database \nconnection ignoring certificate errors. This setting make the connection\nsusceptible to man in the middle (MITM) attacks. Not applicable to SQLite database.\n" metadata: category: security - confidence: HIGH - cwe: 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: LOW - references: - - https://docs.rs/openssl/latest/openssl/ssl/struct.SslContextBuilder.html#method.set_verify - subcategory: vuln - technology: - - openssl - pattern: $BUILDER.set_verify(openssl::ssl::SSL_VERIFY_NONE) - severity: WARNING - - id: rust.lang.security.temp-dir.temp-dir + cwe: CWE-295 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: HIGH + shortDescription: Improper certificate validation + patterns: + - pattern: | + { + host: $HOST, + database: $DATABASE, + dialect: $DIALECT, + dialectOptions: { + ssl: { + rejectUnauthorized: false + } + } + } + - metavariable-regex: + metavariable: $DIALECT + regex: '[''"](mariadb|mysql|postgres)[''"]' + severity: ERROR + - id: rules_lgpl_javascript_database_rule-sequelize-weak-tls languages: - - rust - message: 'temp_dir should not be used for security operations. From the docs: ''The temporary directory may be shared among users, or between processes with different privileges; thus, the creation of any files or directories in the temporary directory must use a secure method to create a uniquely named file. Creating a file or directory with a fixed or predictable name may result in “insecure temporary file” security vulnerabilities.''' + - javascript + message: | + 'The Sequelize connection string indicates that an older version of TLS is in use. TLS1.0 and TLS1.1 are deprecated and should be used. By default, Sequelize use TLSv1.2 but it''s recommended to use TLS1.3. Not applicable to SQLite database.' metadata: category: security - confidence: HIGH - cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' - impact: LOW - likelihood: LOW - references: - - https://doc.rust-lang.org/stable/std/env/fn.temp_dir.html - subcategory: audit - technology: - - rust - pattern: std::env::temp_dir() - severity: INFO - - id: rust.lang.security.unsafe-usage.unsafe-usage + cwe: CWE-757 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: CRITICAL + shortDescription: Selection of Less-Secure Algorithm During Negotiation (Algorithm Downgrade) + patterns: + - pattern-inside: | + { + host: $HOST, + database: $DATABASE, + dialect: $DIALECT, + dialectOptions: + { ssl: ... } + } + - pattern-either: + - pattern: | + { + minVersion: 'TLSv1' + } + - pattern: | + { + minVersion: 'TLSv1.1' + } + - metavariable-regex: + metavariable: $DIALECT + regex: '[''"](mariadb|mysql|postgres)[''"]' + severity: ERROR + - id: rules_lgpl_javascript_dos_rule-layer7-object-dos languages: - - rust - message: Detected 'unsafe' usage, please audit for secure usage + - javascript + message: "This application is looping over user controlled objects, which can lead to a layer 7 denial of service vulnerability.\n\nA layer 7 denial of service attack refers to overloading the application layer of the OSI model, typically layer 7. \nThis can happen when user-controlled input such as objects, arrays, strings, etc. are iterated or looped over without proper validation or limits in place.\n\nFor example, if a user can control the size of an array or object passed into the application, \nthey could create an extremely large input that gets looped over. This would consume excessive CPU cycles or memory, \npotentially crashing or slowing down the application.\n\nTo prevent this, limits should be set on the number of iterations, input sizes, recursion depth, etc.\n\nSample case of secure array looped over with user-controlled input\n```\n// Potential DoS if req.body.list.length is large.\napp.post('/dos/layer7-object-dos/for-loop/1', function (req, res) {\n var list = req.body.list;\n for (let i = 0; i <= 10; i++) {\n if(!list[i]){\n // return;\n } \n }\n res.send(\"res\")\n});\n```\n\nImplementing protections against layer 7 denial of service attacks is important for securing modern web applications and APIs.\n" metadata: category: security - confidence: HIGH - cwe: 'CWE-242: Use of Inherently Dangerous Function' - impact: LOW - likelihood: LOW - references: - - https://doc.rust-lang.org/std/keyword.unsafe.html - subcategory: audit - technology: - - rust - pattern: unsafe { ... } - severity: INFO - - id: scala.jwt-scala.security.jwt-scala-hardcode.jwt-scala-hardcode + cwe: CWE-606 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Unchecked input for loop condition + mode: taint + pattern-sinks: + - patterns: + - pattern: | + for(...; $COND; ...){...} + - focus-metavariable: $COND + - metavariable-pattern: + metavariable: $COND + pattern-either: + - pattern: | + Object.Keys($VAR).length + - pattern: $VAR.length + - patterns: + - pattern-either: + - pattern: $OBJ.forEach + - pattern: $OBJ.map + - pattern: Object.keys($OBJ).map + - pattern: $OBJ.filter + - pattern: $OBJ.reduce + - pattern: $OBJ.reduceRight + - focus-metavariable: $OBJ + pattern-sources: + - patterns: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern: $REQ.$FUNC. ... + - metavariable-regex: + metavariable: $FUNC + regex: ^(body|params|query|baseUrl|cookies|hostname|subdomains|ip|ips|originalUrl|path)$ + severity: WARNING + - id: rules_lgpl_javascript_dos_rule-regex-dos languages: - - scala - message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' + - javascript + message: | + Ensure that the regex used to compare with user supplied input is safe from regular expression denial of service. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-185 owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://jwt-scala.github.io/jwt-scala/ - subcategory: - - vuln - technology: - - scala + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Incorrect regular expression patterns: - - pattern-inside: | - import pdi.jwt.$DEPS - ... - pattern-either: - - pattern: $JWT.encode($X, "...", ...) - - pattern: $JWT.decode($X, "...", ...) - - pattern: $JWT.decodeRawAll($X, "...", ...) - - pattern: $JWT.decodeRaw($X, "...", ...) - - pattern: $JWT.decodeAll($X, "...", ...) - - pattern: $JWT.validate($X, "...", ...) - - pattern: $JWT.isValid($X, "...", ...) - - pattern: $JWT.decodeJson($X, "...", ...) - - pattern: $JWT.decodeJsonAll($X, "...", ...) - - patterns: - - pattern-either: - - pattern: $JWT.encode($X, $KEY, ...) - - pattern: $JWT.decode($X, $KEY, ...) - - pattern: $JWT.decodeRawAll($X, $KEY, ...) - - pattern: $JWT.decodeRaw($X, $KEY, ...) - - pattern: $JWT.decodeAll($X, $KEY, ...) - - pattern: $JWT.validate($X, $KEY, ...) - - pattern: $JWT.isValid($X, $KEY, ...) - - pattern: $JWT.decodeJson($X, $KEY, ...) - - pattern: $JWT.decodeJsonAll($X, $KEY, ...) - - pattern: $JWT.encode($X, this.$KEY, ...) - - pattern: $JWT.decode($X, this.$KEY, ...) - - pattern: $JWT.decodeRawAll($X, this.$KEY, ...) - - pattern: $JWT.decodeRaw($X, this.$KEY, ...) - - pattern: $JWT.decodeAll($X, this.$KEY, ...) - - pattern: $JWT.validate($X, this.$KEY, ...) - - pattern: $JWT.isValid($X, this.$KEY, ...) - - pattern: $JWT.decodeJson($X, this.$KEY, ...) - - pattern: $JWT.decodeJsonAll($X, this.$KEY, ...) - - pattern-either: - - pattern-inside: | - class $CL { - ... - $KEY = "..." - ... - } - - pattern-inside: | - object $CL { - ... - $KEY = "..." - ... - } - - metavariable-pattern: - metavariable: $JWT - patterns: - - pattern-either: - - pattern: Jwt - - pattern: JwtArgonaut - - pattern: JwtCirce - - pattern: JwtJson4s - - pattern: JwtJson - - pattern: JwtUpickle + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $REGEX.test(<... $REQ ...>) + - pattern: | + $REGEX.test(<... $REQ.$QUERY ...>) + - pattern: | + $REGEX.test(<... $REQ.$BODY.$PARAM ...>) + - pattern: | + $INP = <... $REQ ...>; + ... + $REGEX.test(<... $INP ...>) + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + $REGEX.test(<... $INP ...>) + - pattern: | + $INP = <... $REQ.$BODY.$PARAM ...>; + ... + $REGEX.test(<... $INP ...>) + - pattern: | + /.../g.exec(<... $REQ ...>) + - pattern: | + /.../g.exec(<... $REQ.$QUERY ...>) + - pattern: | + /.../.exec(<... $REQ.$BODY.$PARAM ...>) + - pattern: | + $INP = <... $REQ ...>; + ... + /.../.exec(<... $INP ...>) + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + /.../.exec(<... $INP ...>) + - pattern: | + $INP = <... $REQ.$BODY.$PARAM ...>; + ... + /.../.exec(<... $INP ...>) + - pattern: | + $RE = /.../; + ... + $RE.exec(<... $REQ ...>) + - pattern: | + $RE = /.../; + ... + $RE.exec(<... $REQ.$QUERY ...>) + - pattern: | + $RE = /.../; + ... + $RE.exec(<... $REQ.$BODY.$PARAM ...>) severity: WARNING - - id: scala.lang.correctness.positive-number-index-of.positive-number-index-of + - id: rules_lgpl_javascript_electronjs_rule-electron-allow-http languages: - - scala - message: Flags scala code that look for values that are greater than 0. This ignores the first element, which is most likely a bug. Instead, use indexOf with -1. If the intent is to check the inclusion of a value, use the contains method instead. + - javascript + message: | + Application can load content over HTTP and that makes the app vulnerable to Man in the middle attacks. metadata: - category: correctness - confidence: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://blog.codacy.com/9-scala-security-issues/ - technology: - - scala + category: security + cwe: CWE-319 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: CRITICAL + shortDescription: Cleartext Transmission of Sensitive Information patterns: - pattern-either: - - patterns: - - pattern: | - $OBJ.indexOf(...) > $VALUE - - metavariable-comparison: - comparison: $VALUE >= 0 - metavariable: $VALUE - - patterns: - - pattern: | - $OBJ.indexOf(...) >= $SMALLERVAL - - metavariable-comparison: - comparison: $SMALLERVAL > 0 - metavariable: $SMALLERVAL - severity: WARNING - - id: scala.lang.security.audit.documentbuilder-dtd-enabled.documentbuilder-dtd-enabled + - pattern: | + new BrowserWindow({webPreferences: {allowRunningInsecureContent: true}}) + - pattern: | + var $X = {webPreferences: {allowRunningInsecureContent: true}}; + severity: ERROR + - id: rules_lgpl_javascript_electronjs_rule-electron-blink-integration languages: - - scala - message: Document Builder being instantiated without calling the `setFeature` functions that are generally used for disabling entity processing. User controlled data in XML Document builder can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. + - javascript + message: | + Blink's expirimental features are enabled in this application. Some of the features may affect the security of the application. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + cwe: CWE-272 owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - scala + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Least privilege violation patterns: - pattern-either: - pattern: | - $DF = DocumentBuilderFactory.newInstance(...) - ... - $DB = $DF.newDocumentBuilder(...) - - patterns: - - pattern: $DB = DocumentBuilderFactory.newInstance(...) - - pattern-not-inside: | - ... - $X = $DB.newDocumentBuilder(...) - - pattern: $DB = DocumentBuilderFactory.newInstance(...).newDocumentBuilder(...) - - pattern-not-inside: | - ... - $DB.setXIncludeAware(true) - ... - $DB.setNamespaceAware(true) - ... - $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - - pattern-not-inside: | - ... - $DB.setXIncludeAware(true) - ... - $DB.setNamespaceAware(true) - ... - $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - ... - $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) - - pattern-not-inside: | - ... - $DB.setXIncludeAware(true) - ... - $DB.setNamespaceAware(true) - ... - $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - - pattern-not-inside: | - ... - $DB.setXIncludeAware(true) - ... - $DB.setNamespaceAware(true) - ... - $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - ... - $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + new BrowserWindow({webPreferences: {enableBlinkFeatures: '...'}}) + - pattern: | + var $X = {webPreferences: {enableBlinkFeatures: '...'}}; severity: WARNING - - id: scala.lang.security.audit.io-source-ssrf.io-source-ssrf + - id: rules_lgpl_javascript_electronjs_rule-electron-context-isolation languages: - - scala - message: A parameter being passed directly into `fromURL` most likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server running this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. + - javascript + message: | + Disabling context isolation can introduce Prototype Pollution vulnerabilities. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW + cwe: CWE-1321 owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - - https://www.scala-lang.org/api/current/scala/io/Source$.html#fromURL(url:java.net.URL)(implicitcodec:scala.io.Codec):scala.io.BufferedSource - subcategory: - - audit - technology: - - scala + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Improperly controlled modification of object prototype attributes ('Prototype Pollution') patterns: - pattern-either: - - pattern: Source.fromURL($URL,...) - - pattern: Source.fromURI($URL,...) - - pattern-inside: | - import scala.io.$SOURCE - ... - - pattern-either: - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = $A { - ... - } - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = { - ... - } + - pattern: | + new BrowserWindow({webPreferences: {contextIsolation: false}}) + - pattern: | + var $X = {webPreferences: {contextIsolation: false}}; severity: WARNING - - id: scala.lang.security.audit.rsa-padding-set.rsa-padding-set + - id: rules_lgpl_javascript_electronjs_rule-electron-disable-websecurity languages: - - scala - message: Usage of RSA without OAEP (Optimal Asymmetric Encryption Padding) may weaken encryption. This could lead to sensitive data exposure. Instead, use RSA with `OAEPWithMD5AndMGF1Padding` instead. + - javascript + message: | + Disabling webSecurity will disable the same-origin policy and allows the execution of insecure code from any domain. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-780: Use of RSA Algorithm without OAEP' - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: CWE-346 owasp: - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - resources: - - https://blog.codacy.com/9-scala-security-issues/ - subcategory: - - audit - technology: - - scala - - cryptography + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: CRITICAL + shortDescription: Origin validation error patterns: - - pattern: | - $VAR = $CIPHER.getInstance($MODE) - - metavariable-regex: - metavariable: $MODE - regex: .*RSA/.*/NoPadding.* - severity: WARNING - - id: scala.lang.security.audit.sax-dtd-enabled.sax-dtd-enabled + - pattern-either: + - pattern: | + new BrowserWindow({webPreferences: {webSecurity: false}}) + - pattern: | + var $X = {webPreferences: {webSecurity: false}}; + severity: ERROR + - id: rules_lgpl_javascript_electronjs_rule-electron-experimental-features languages: - - scala - message: XML processor being instantiated without calling the `setFeature` functions that are generally used for disabling entity processing. User controlled data in XML Parsers can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. + - javascript + message: | + Experimental features are not expected to be in production ready applications. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-272 owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - scala + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: CRITICAL + shortDescription: Least privilege violation patterns: - pattern-either: - - pattern: $SR = new SAXReader(...) - pattern: | - $SF = SAXParserFactory.newInstance(...) - ... - $SR = $SF.newSAXParser(...) - - patterns: - - pattern: $SR = SAXParserFactory.newInstance(...) - - pattern-not-inside: | - ... - $X = $SR.newSAXParser(...) - - pattern: $SR = SAXParserFactory.newInstance(...).newSAXParser(...) - - pattern: $SR = new SAXBuilder(...) - - pattern-not-inside: | - ... - $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - - pattern-not-inside: | - ... - $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - ... - $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) - - pattern-not-inside: | - ... - $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - - pattern-not-inside: | - ... - $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - ... - $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + new BrowserWindow({webPreferences: {experimentalFeatures: true}}) + - pattern: | + var $X = {webPreferences: {experimentalFeatures: true}}; severity: WARNING - - id: scala.lang.security.audit.scalac-debug.scalac-debug + - id: rules_lgpl_javascript_electronjs_rule-electron-nodejs-integration languages: - - generic - message: Scala applications built with `debug` set to true in production may leak debug information to attackers. Debug mode also affects performance and reliability. Remove it from configuration. + - javascript + message: | + Node integration exposes node.js APIs to the electron app and this can introduce remote code execution vulnerabilities to the application if the app is vulnerable to Cross Site Scripting (XSS). metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-489: Active Debug Code' - impact: LOW - likelihood: LOW - owasp: A05:2021 - Security Misconfiguration - references: - - https://docs.scala-lang.org/overviews/compiler-options/index.html - subcategory: - - audit - technology: - - scala - - sbt - paths: - include: - - '*.sbt*' + cwe: CWE-272 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Least privilege violation patterns: - pattern-either: - - pattern: scalacOptions ... "-Vdebug" - - pattern: scalacOptions ... "-Ydebug" + - pattern: | + new BrowserWindow({webPreferences: {nodeIntegration: true}}) + - pattern: | + var $X = {webPreferences: {nodeIntegration: true}}; severity: WARNING - - id: scala.lang.security.audit.tainted-sql-string.tainted-sql-string + - id: rules_lgpl_javascript_eval_rule-eval-nodejs + languages: + - javascript + message: | + User controlled data in eval() or similar functions may result in Server Side Injection or Remote Code Injection + metadata: + category: security + cwe: CWE-95 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: HIGH + shortDescription: Improper neutralization of directives in dynamically evaluated code ('Eval Injection') + patterns: + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + new Function(..., <... $REQ.$QUERY.$VAR ...>, ...) + - pattern: | + new Function(..., <... $REQ.$QUERY ...>, ...) + - pattern: | + eval(..., <... $REQ.$QUERY.$VAR ...>, ...) + - pattern: | + eval(..., <... $REQ.$QUERY ...>, ...) + - pattern: | + setTimeout(..., <... $REQ.$QUERY.$VAR ...>, ...) + - pattern: | + setTimeout(..., <... $REQ.$QUERY ...>, ...) + - pattern: | + setInterval(..., <... $REQ.$QUERY.$VAR ...>, ...) + - pattern: | + setInterval(..., <... $REQ.$QUERY ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY.$VAR ...>; + ... + new Function(..., <... $INP ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + new Function(..., <... $INP ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY.$VAR ...>; + ... + eval(..., <... $INP ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + eval(..., <... $INP ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY.$VAR ...>; + ... + setTimeout(..., <... $INP ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + setTimeout(..., <... $INP ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY.$VAR ...>; + ... + setInterval(..., <... $INP ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + setInterval(..., <... $INP ...>, ...) + severity: ERROR + - id: rules_lgpl_javascript_eval_rule-eval-require languages: - - scala - message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. + - javascript + message: "Passing untrusted user input directly into the require() function without proper \nvalidation or sanitization can possibly cause a vulnerability known as remote code execution (RCE). \nAn attacker could manipulate the input to load and execute arbitrary code from external sources, \npotentially leading to severe security breaches such as data theft, system compromise, \nor unauthorized access.\nTo mitigate this risk, it's crucial to validate and sanitize user input\nthoroughly before passing it to functions like require(), ensuring that only trusted and safe inputs are utilized.\n\nFollowing is an example of secure validation against allowlist to prevent the vulnerability:\n```\n// Define a list of explicitly allowed packages for require\nconst allowedPkgs = [\n 'package1',\n 'package2',\n 'package3'\n];\n\napp.get(\"/eval/require/7\", async (req, res) => {\n var isAllowed = allowedPkgs.includes(req.query.name); \n if (isAllowed) {\n // ok: rules_lgpl_javascript_eval_rule-eval-require\n var cp = require(req.query.name);\n cp.exec('ls', (error, stdout, stderr) => {\n console.log(\"exec output : \\n\", stdout)\n }); \n }\n res.send(\"Please check console logs.\");\n});\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: CWE-706 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html - subcategory: - - vuln - technology: - - scala + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Use of incorrectly-resolved name or reference mode: taint pattern-sanitizers: - - pattern-either: - - patterns: - - pattern-either: - - pattern: $LOGGER.$METHOD(...) - - pattern: $LOGGER(...) - - metavariable-regex: - metavariable: $LOGGER - regex: (i?)log.* - - patterns: - - pattern: $LOGGER.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (i?)(trace|info|warn|warning|warnToError|error|debug) - pattern-sinks: - patterns: - pattern-either: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR".format(...) - - patterns: - - pattern-inside: | - $SB = new StringBuilder("$SQLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$SQLSTR" - ... - - pattern: $VAR += ... - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b - - patterns: - - pattern-either: - - pattern: s"..." - - pattern: f"..." - - pattern-regex: | - .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - - pattern-not-inside: println(...) + - pattern: "if($VALIDATION){\n...\nrequire($REQ, ...) \n...\n} \n" + - pattern: | + $A = $VALIDATION + ... + if($A){ + ... + require($REQ, ...) + ... + } + - metavariable-pattern: + metavariable: $VALIDATION + pattern-either: + - pattern: "$AL.includes(...) \n" + - pattern: | + $AL.indexOf(...) !== -1 + - pattern: | + $AL.find(...) !== undefined + - pattern: | + $ALS.has(...) + pattern-sinks: + - patterns: + - pattern: | + require($REQ, ...) + - focus-metavariable: $REQ pattern-sources: - patterns: - - pattern: $PARAM - - pattern-either: - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = $A { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = $A(...) { - ... - } + - pattern-inside: | + function ($REQ, $RES, ...) {...} + - focus-metavariable: $REQ severity: ERROR - - id: scala.lang.security.audit.xmlinputfactory-dtd-enabled.xmlinputfactory-dtd-enabled + - id: rules_lgpl_javascript_eval_rule-grpc-insecure-connection languages: - - scala - message: XMLInputFactory being instantiated without calling the setProperty functions that are generally used for disabling entity processing. User controlled data in XML Document builder can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. + - javascript + - typescript + message: | + Found an insecure gRPC connection. This creates a connection without encryption to a gRPC client/server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + cwe: CWE-502 owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - scala + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: CRITICAL + shortDescription: Deserialization of Untrusted Data patterns: - - pattern-not-inside: | - ... - $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", false) - pattern-either: - - pattern: $XMLFACTORY = XMLInputFactory.newFactory(...) - - pattern: $XMLFACTORY = XMLInputFactory.newInstance(...) - - pattern: $XMLFACTORY = new XMLInputFactory(...) - severity: WARNING - - id: scala.play.security.conf-csrf-headers-bypass.conf-csrf-headers-bypass + - pattern-inside: | + require('grpc') + ... + - pattern-inside: | + import $MOD from 'grpc' + ... + - pattern: $CREDENTIALS.createInsecure() + severity: ERROR + - id: rules_lgpl_javascript_eval_rule-node-deserialize languages: - - generic - message: Possibly bypassable CSRF configuration found. CSRF is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. Make sure that Content-Type black list is configured and CORS filter is turned on. + - javascript + - typescript + message: | + User controlled data in 'unserialize()' or 'deserialize()' function can result in Object Injection or Remote Code Injection. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW + cwe: CWE-502 owasp: - - A01:2021 - Broken Access Control - references: - - https://www.playframework.com/documentation/2.8.x/Migration25#CSRF-changes - - https://owasp.org/www-community/attacks/csrf - subcategory: - - vuln - technology: - - scala - - play - paths: - include: - - '*.conf' + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: CRITICAL + shortDescription: Deserialization of Untrusted Data patterns: - pattern-either: - - pattern: X-Requested-With = "*" - - pattern: Csrf-Token = "..." - - pattern-inside: | - bypassHeaders {... - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."application/x-www-form-urlencoded"..."multipart/form-data"..."text/plain"...] - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."application/x-www-form-urlencoded"..."text/plain"..."multipart/form-data"...] - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."multipart/form-data"..."application/x-www-form-urlencoded"..."text/plain"...] - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."multipart/form-data"..."text/plain"..."application/x-www-form-urlencoded"...] - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."text/plain"..."application/x-www-form-urlencoded"..."multipart/form-data"...] - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."text/plain"..."multipart/form-data"..."application/x-www-form-urlencoded"...] - ... - ...} + - pattern: | + require('node-serialize').unserialize(...) + - pattern-inside: | + $MOD = require('node-serialize') + ... + - pattern-inside: | + import $MOD from 'node-serialize' + ... + - pattern: | + $MOD.unserialize(...) severity: ERROR - - id: scala.play.security.conf-insecure-cookie-settings.conf-insecure-cookie-settings + - id: rules_lgpl_javascript_eval_rule-sandbox-code-injection languages: - - generic - message: Session cookie `Secure` flag is explicitly disabled. The `secure` flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the `Secure` flag by setting `secure` to `true` in configuration file. + - javascript + message: | + Unrusted data in `sandbox` can result in code injection. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW + cwe: CWE-94 owasp: - - A05:2021 - Security Misconfiguration - references: - - https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#security - - https://www.playframework.com/documentation/2.8.x/SettingsSession#Session-Configuration - subcategory: - - vuln - technology: - - play - - scala - paths: - include: - - '*.conf' + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code (Code Injection) patterns: - - pattern: secure = false - pattern-inside: | - session = { - ... - } - severity: WARNING - - id: scala.play.security.tainted-html-response.tainted-html-response - languages: - - scala - message: Detected a request with potential user-input going into an `Ok()` response. This bypasses any view or template environments, including HTML escaping, which may expose this application to cross-site scripting (XSS) vulnerabilities. Consider using a view technology such as Twirl which automatically escapes HTML views. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - scala - - play - mode: taint - pattern-sanitizers: + require('sandbox') + ... - pattern-either: - - pattern: org.apache.commons.lang3.StringEscapeUtils.escapeHtml4(...) - - pattern: org.owasp.encoder.Encode.forHtml(...) - pattern-sinks: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - pattern-either: - - pattern: Html.apply(...) - - pattern: Ok(...).as(HTML) - - pattern: Ok(...).as(ContentTypes.HTML) - - patterns: - - pattern: Ok(...).as($CTYPE) - - metavariable-regex: - metavariable: $CTYPE - regex: '"[tT][eE][xX][tT]/[hH][tT][mM][lL]"' - - patterns: - - pattern: Ok(...).as($CTYPE) - - pattern-not: Ok(...).as("...") - - pattern-either: - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = $A { - ... - } - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = { - ... - } - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern: $REQ - - pattern-either: - - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - patterns: - - pattern: $PARAM - - pattern-either: - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { - ... - } - severity: WARNING - - id: scala.play.security.tainted-slick-sqli.tainted-slick-sqli + - pattern: | + $S.run(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: | + $CODE = <... $REQ.$QUERY.$FOO ...>; + ... + $S.run(<... $CODE ...>,...) + - pattern: | + new $SANDBOX(...).run(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: | + $CODE = <... $REQ.$QUERY.$FOO ...>; + ... + new $SANDBOX(...).run(<... $CODE ...>,...) + - pattern: | + $S.run(<... $REQ.$BODY ...>,...) + - pattern: | + $CODE = <... $REQ.$BODY ...>; + ... + $S.run(<... $CODE ...>,...) + - pattern: | + new $SANDBOX(...).run(<... $REQ.$BODY ...>,...) + - pattern: |- + $CODE = <... $REQ.$BODY ...>; + ... + new $SANDBOX(...).run(<... $CODE ...>,...) + severity: ERROR + - id: rules_lgpl_javascript_eval_rule-serializetojs-deserialize languages: - - scala - message: Detected a tainted SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Avoid using using user input for generating SQL strings. + - javascript + - typescript + message: | + User controlled data in 'unserialize()' or 'deserialize()' function can result in Object Injection or Remote Code Injection. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-502 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://scala-slick.org/doc/3.3.3/sql.html#splicing-literal-values - - https://scala-slick.org/doc/3.2.0/sql-to-slick.html#non-optimal-sql-code - subcategory: - - vuln - technology: - - scala - - slick - - play - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $MODEL.overrideSql(...) - - pattern: sql"..." + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: CRITICAL + shortDescription: Deserialization of Untrusted Data + patterns: + - pattern-either: + - pattern: | + require('serialize-to-js').deserialize(...) - pattern-inside: | - import slick.$DEPS + $MOD = require('serialize-to-js') ... - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern: $REQ - - pattern-either: - - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - patterns: - - pattern: $PARAM - - pattern-either: - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { - ... - } + - pattern-inside: | + import $MOD from 'serialize-to-js' + ... + - pattern: | + $MOD.deserialize(...) severity: ERROR - - id: scala.play.security.tainted-sql-from-http-request.tainted-sql-from-http-request + - id: rules_lgpl_javascript_eval_rule-server-side-template-injection languages: - - scala - message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. + - javascript + message: | + Untrusted user input in templating engine's compile() function can result in Remote Code Execution via server side template injection. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH + cwe: CWE-94 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html - subcategory: - - vuln - technology: - - scala - - play - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR".format(...) - - patterns: - - pattern-inside: | - $SB = new StringBuilder("$SQLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$SQLSTR" - ... - - pattern: $VAR += ... - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b - - patterns: - - pattern: s"..." - - pattern-regex: | - .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - - pattern-not-inside: println(...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern: $REQ - - pattern-either: - - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - patterns: - - pattern: $PARAM - - pattern-either: - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { - ... - } + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code (Code Injection) + patterns: + - pattern-either: + - pattern-inside: | + require('handlebars') + ... + - pattern-inside: | + require('pug') + ... + - pattern-inside: | + require('hamljs') + ... + - pattern-inside: | + require('ejs') + ... + - pattern-inside: | + require('squirrelly') + ... + - pattern-inside: | + require('eta') + ... + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $HB.compile(..., <... $REQ.$FOO ...>, ...) + - pattern: | + $HB.compile(..., <... $REQ.$FOO.$BAR ...>, ...) + - pattern: | + $X = <... $REQ.$FOO ...>; + ... + $HB.compile(..., <... $X ...>, ...) + - pattern: | + $X = <... $REQ.$FOO.$BAR ...>; + ... + $HB.compile(..., <... $X ...>, ...) + - pattern: | + $X = $SOURCE.replace('...', <... $REQ.$FOO ...>, ...) + ... + $HB.compile(..., <... $X ...>, ...) + - pattern: | + $X = $SOURCE.replace('...', <... $REQ.$FOO.$BAR ...>, ...) + ... + $HB.compile(..., <... $X ...>, ...) + - pattern: | + $HB.Compile(..., <... $REQ.$FOO ...>, ...) + - pattern: | + $HB.Compile(..., <... $REQ.$FOO.$BAR ...>, ...) + - pattern: | + $X = <... $REQ.$FOO ...>; + ... + $HB.Compile(..., <... $X ...>, ...) + - pattern: | + $X = <... $REQ.$FOO.$BAR ...>; + ... + $HB.Compile(..., <... $X ...>, ...) + - pattern: | + $X = $SOURCE.replace('...', <... $REQ.$FOO ...>, ...) + ... + $HB.Compile(..., <... $X ...>, ...) + - pattern: | + $X = $SOURCE.replace('...', <... $REQ.$FOO.$BAR ...>, ...) + ... + $HB.Compile(..., <... $X ...>, ...) severity: ERROR - - id: scala.scala-jwt.security.jwt-hardcode.scala-jwt-hardcoded-secret + - id: rules_lgpl_javascript_eval_rule-vm2-code-injection languages: - - scala - message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' + - javascript + message: | + Untrusted user input reaching `vm2` can result in code injection. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-94 owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - pattern-either: - - pattern: | - com.auth0.jwt.algorithms.Algorithm.HMAC256("..."); - - pattern: | - $SECRET = "..."; + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code (Code Injection) + patterns: + - pattern-inside: | + require('vm2') ... - com.auth0.jwt.algorithms.Algorithm.HMAC256($SECRET); - - pattern: | - class $CLASS { - ... - $DECL $SECRET = "..."; - ... - def $FUNC (...): $RETURNTYPE = { + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $VM.run(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: | + $CODE = <... $REQ.$QUERY.$FOO ...>; ... - com.auth0.jwt.algorithms.Algorithm.HMAC256($SECRET); + $VM.run(<... $CODE ...>,...) + - pattern: | + new VM(...).run(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: | + new NodeVM(...).run(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: | + $CODE = <... $REQ.$QUERY.$FOO ...>; ... - } - ... - } - - pattern: | - com.auth0.jwt.algorithms.Algorithm.HMAC384("..."); - - pattern: | - $SECRET = "..."; - ... - com.auth0.jwt.algorithms.Algorithm.HMAC384($SECRET); - - pattern: | - class $CLASS { - ... - $DECL $SECRET = "..."; - ... - def $FUNC (...): $RETURNTYPE = { + new NodeVM(...).run(<... $CODE ...>,...) + - pattern: | + $CODE = <... $REQ.$QUERY.$FOO ...>; ... - com.auth0.jwt.algorithms.Algorithm.HMAC384($SECRET); + new VMScript(<... $CODE ...>,...) + - pattern: | + $VM.run(<... $REQ.$BODY ...>,...) + - pattern: | + $CODE = <... $REQ.$BODY ...>; ... - } - ... - } - - pattern: | - com.auth0.jwt.algorithms.Algorithm.HMAC512("..."); - - pattern: | - $SECRET = "..."; + $VM.run(<... $CODE ...>,...) + - pattern: | + new VM(...).run(<... $REQ.$BODY ...>,...) + - pattern: | + $CODE = <... $REQ.$BODY ...>; + ... + new VM(...).run($CODE,...) + - pattern: | + new NodeVM(...).run(<... $REQ.$BODY ...>,...) + - pattern: | + $CODE = <... $REQ.$BODY ...>; + ... + new NodeVM(...).run(<... $CODE ...>,...) + - pattern: | + $CODE = <... $REQ.$BODY ...>; + ... + new VMScript(<... $CODE ...>,...) + severity: WARNING + - id: rules_lgpl_javascript_eval_rule-vm2-context-injection + languages: + - javascript + message: | + Untrusted user input reaching `vm2` sandbox can result in context injection. + metadata: + category: security + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code (Code Injection) + patterns: + - pattern-inside: | + require('vm2') ... - com.auth0.jwt.algorithms.Algorithm.HMAC512($SECRET); - - pattern: | - class $CLASS { - ... - $DECL $SECRET = "..."; - ... - def $FUNC (...): $RETURNTYPE = { + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + new VM({sandbox: <... $REQ.$QUERY.$FOO ...>},...) + - pattern: | + $CONTEXT = <... $REQ.$QUERY.$FOO ...>; ... - com.auth0.jwt.algorithms.Algorithm.HMAC512($SECRET); + new VM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; ... - } - ... - } + new VM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; + ... + new VM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $VAR = <... $REQ.$QUERY.$FOO ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + new VM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $OPTS = {sandbox: <... $REQ.$QUERY.$FOO ...>}; + ... + new VM($OPTS,...) + - pattern: | + $CONTEXT = <... $REQ.$QUERY.$FOO ...>; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new VM($OPTS,...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new VM($OPTS,...) + - pattern: | + $VAR = <... $REQ.$QUERY.$FOO ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new VM($OPTS,...) + - pattern: | + new NodeVM({sandbox: <... $REQ.$QUERY.$FOO ...>},...) + - pattern: | + $CONTEXT = <... $REQ.$QUERY.$FOO ...>; + ... + new NodeVM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; + ... + new NodeVM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; + ... + new NodeVM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $VAR = <... $REQ.$QUERY.$FOO ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + new NodeVM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $OPTS = {sandbox: <... $REQ.$QUERY.$FOO ...>}; + ... + new NodeVM($OPTS,...) + - pattern: | + $CONTEXT = <... $REQ.$QUERY.$FOO ...>; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new NodeVM($OPTS,...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new NodeVM($OPTS,...) + - pattern: | + $VAR = <... $REQ.$QUERY.$FOO ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new NodeVM($OPTS,...) + - pattern: | + new VM({sandbox: <... $REQ.$BODY ...>},...) + - pattern: | + $CONTEXT = <... $REQ.$BODY ...>; + ... + new VM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = <... {$NAME:$REQ.$BODY} ...>; + ... + new VM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; + ... + new VM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $VAR = <... $REQ.$BODY ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + new VM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $OPTS = {sandbox: <... $REQ.$BODY ...>}; + ... + new VM($OPTS,...) + - pattern: | + $CONTEXT = <... $REQ.$BODY ...>; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new VM($OPTS,...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new VM($OPTS,...) + - pattern: | + $VAR = <... $REQ.$BODY ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new VM($OPTS,...) + - pattern: | + new NodeVM({sandbox: <... $REQ.$BODY ...>},...) + - pattern: | + $CONTEXT = <... $REQ.$BODY ...>; + ... + new NodeVM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = <... {$NAME:$REQ.$BODY} ...>; + ... + new NodeVM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; + ... + new NodeVM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $VAR = <... $REQ.$BODY ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + new NodeVM({sandbox: <... $CONTEXT ...>},...) + - pattern: | + $OPTS = {sandbox: <... $REQ.$BODY ...>}; + ... + new NodeVM($OPTS,...) + - pattern: | + $CONTEXT = <... $REQ.$BODY ...>; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new NodeVM($OPTS,...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new NodeVM($OPTS,...) + - pattern: |- + $VAR = <... $REQ.$BODY ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + $OPTS = {sandbox: <... $CONTEXT ...>}; + ... + new NodeVM($OPTS,...) severity: ERROR - - id: swift.lang.storage.sensitive-storage-userdefaults.swift-user-defaults + - id: rules_lgpl_javascript_eval_rule-vm-code-injection languages: - - swift - message: Potentially sensitive data was observed to be stored in UserDefaults, which is not adequate protection of sensitive information. For data of a sensitive nature, applications should leverage the Keychain. + - javascript + message: | + Untrusted user input reaching `vm` can result in code injection. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW - masvs: - - 'MASVS-STORAGE-1: The app securely stores sensitive data' + cwe: CWE-94 owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html - - https://mas.owasp.org/MASVS/controls/MASVS-STORAGE-1/ - subcategory: - - vuln - technology: - - ios - - macos - options: - symbolic_propagation: true + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code (Code Injection) patterns: + - pattern-inside: | + $VM = require('vm') + ... - pattern-either: - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $VALUE - regex: (?i).*(passcode|password|pass_word|passphrase|pass_code|pass_word|pass_phrase)$ - - focus-metavariable: $VALUE - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $KEY - regex: (?i).*(passcode|password|pass_word|passphrase|pass_code|pass_word|pass_phrase)$ - - focus-metavariable: $KEY - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $VALUE - regex: (?i).*(api_key|apikey)$ - - focus-metavariable: $VALUE - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $KEY - regex: (?i).*(api_key|apikey)$ - - focus-metavariable: $KEY - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $VALUE - regex: (?i).*(secretkey|secret_key|secrettoken|secret_token|clientsecret|client_secret)$ - - focus-metavariable: $VALUE - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $KEY - regex: (?i).*(secretkey|secret_key|secrettoken|secret_token|clientsecret|client_secret)$ - - focus-metavariable: $KEY - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $VALUE - regex: (?i).*(cryptkey|cryptokey|crypto_key|cryptionkey|symmetrickey|privatekey|symmetric_key|private_key)$ - - focus-metavariable: $VALUE - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $KEY - regex: (?i).*(cryptkey|cryptokey|crypto_key|cryptionkey|symmetrickey|privatekey|symmetric_key|private_key)$ - - focus-metavariable: $KEY - severity: WARNING - - id: swift.webview.webview-js-window.swift-webview-config-allows-js-open-windows + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: $VM.runInContext(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $VM.runInContext(<... $REQ.$BODY ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $VM.runInContext($INPUT,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $VM.runInContext($INPUT,...) + - pattern: $VM.runInNewContext(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $VM.runInNewContext(<... $REQ.$BODY ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $VM.runInNewContext($INPUT,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $VM.runInNewContext($INPUT,...) + - pattern: $VM.runInThisContext(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $VM.runInThisContext(<... $REQ.$BODY ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $VM.runInThisContext($INPUT,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $VM.runInThisContext($INPUT,...) + - pattern: $VM.compileFunction(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $VM.compileFunction(<... $REQ.$BODY ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $VM.compileFunction($INPUT,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $VM.compileFunction($INPUT,...) + - pattern: new $VM.Script(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: new $VM.Script(<... $REQ.$BODY ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + new $VM.Script($INPUT,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + new $VM.Script($INPUT,...) + severity: ERROR + - id: rules_lgpl_javascript_eval_rule-vm-compilefunction-injection languages: - - swift - message: Webviews were observed that explictly allow JavaScript in an WKWebview to open windows automatically. Consider disabling this functionality if not required, following the principle of least privelege. + - javascript + message: | + Untrusted user input in `vm.compileFunction()` can result in code injection. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-272: Least Privilege Violation' - impact: LOW - likelihood: LOW - masvs: - - 'MASVS-PLATFORM-2: The app uses WebViews securely' - references: - - https://mas.owasp.org/MASVS/controls/MASVS-PLATFORM-2/ - - https://developer.apple.com/documentation/webkit/wkpreferences/1536573-javascriptcanopenwindowsautomati - subcategory: - - audit - technology: - - ios - - macos + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code (Code Injection) patterns: - - pattern: | - $P = WKPreferences() + - pattern-inside: | + require('vm') ... - pattern-either: - - patterns: - - pattern-inside: | - $P.JavaScriptCanOpenWindowsAutomatically = $FALSE - ... - $P.JavaScriptCanOpenWindowsAutomatically = $TRUE - - pattern-not-inside: | - ... - $P.JavaScriptCanOpenWindowsAutomatically = $TRUE - ... - $P.JavaScriptCanOpenWindowsAutomatically = $FALSE - - pattern: | - $P.JavaScriptCanOpenWindowsAutomatically = true - - metavariable-regex: - metavariable: $TRUE - regex: ^(true)$ - - metavariable-regex: - metavariable: $TRUE - regex: (.*(?!true)) - - patterns: - - pattern: | - $P.JavaScriptCanOpenWindowsAutomatically = true - - pattern-not-inside: | - ... - $P.JavaScriptCanOpenWindowsAutomatically = ... - ... - $P.JavaScriptCanOpenWindowsAutomatically = ... - severity: WARNING - - id: terraform.aws.correctness.subscription-filter-missing-depends.subscription-filter-missing-depends + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $REQ.$QUERY.$FOO ...>},...) + - pattern: | + $CONTEXT = <... $REQ.$QUERY.$FOO ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) + - pattern: | + $VAR = <... $REQ.$QUERY.$FOO ...>; ... $CONTEXT = {$NAME: <... $VAR ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) + - pattern: | + $OPTS = {parsingContext: <... $REQ.$QUERY.$FOO ...>}; + ... + $VM.compileFunction($CODE,$PARAMS,$OPTS,...) + - pattern: | + $CONTEXT = <... $REQ.$QUERY.$FOO ...>; + ... + $OPTS = {parsingContext: <... $CONTEXT ...>}; + ... + $VM.compileFunction($CODE,$PARAMS,$OPTS,...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; + ... + $OPTS = {parsingContext: <... $CONTEXT ...>}; + ... + $VM.compileFunction($CODE,$PARAMS,$OPTS,...) + - pattern: | + $VAR = <... $REQ.$QUERY.$FOO ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + $OPTS = {parsingContext: <... $CONTEXT ...>}; + ... + $VM.compileFunction($CODE,$PARAMS,$OPTS,...) + - pattern: | + $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $REQ.$BODY ...>},...) + - pattern: | + $CONTEXT = <... $REQ.$BODY ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = <... {$NAME:$REQ.$BODY} ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) + - pattern: | + $VAR = <... $REQ.$BODY ...>; ... $CONTEXT = {$NAME: <... $VAR ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) + - pattern: | + $OPTS = {parsingContext: <... $REQ.$BODY ...>}; + ... + $VM.compileFunction($CODE,$PARAMS,$OPTS,...) + - pattern: | + $CONTEXT = <... $REQ.$BODY ...>; + ... + $OPTS = {parsingContext: <... $CONTEXT ...>}; + ... + $VM.compileFunction($CODE,$PARAMS,$OPTS,...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; + ... + $OPTS = {parsingContext: <... $CONTEXT ...>}; + ... + $VM.compileFunction($CODE,$PARAMS,$OPTS,...) + - pattern: | + $VAR = <... $REQ.$BODY ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + $OPTS = {parsingContext: <... $CONTEXT ...>}; + ... + $VM.compileFunction($CODE,$PARAMS,$OPTS,...) + severity: ERROR + - id: rules_lgpl_javascript_eval_rule-vm-runincontext-injection languages: - - hcl - message: The `aws_cloudwatch_log_subscription_filter` resource "$NAME" needs a `depends_on` clause on the `aws_lambda_permission`, otherwise Terraform may try to create these out-of-order and fail. + - javascript + message: | + Untrusted user input in `vm.runInContext()` can result in code injection. metadata: - category: correctness - confidence: MEDIUM - references: - - https://stackoverflow.com/questions/38407660/terraform-configuring-cloudwatch-log-subscription-delivery-to-lambda/38428834#38428834 - technology: - - aws - - terraform - - aws-lambda - - cloudwatch + category: security + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code (Code Injection) patterns: - - pattern: | - resource "aws_cloudwatch_log_subscription_filter" $NAME { - ... - destination_arn = aws_lambda_function.$LAMBDA_NAME.arn - } - - pattern-not-inside: | - resource "aws_cloudwatch_log_subscription_filter" $NAME { - ... - depends_on = [..., aws_lambda_permission.$PERMISSION_NAME, ...] - } - severity: WARNING - - id: terraform.aws.security.aws-cloudfront-insecure-tls.aws-insecure-cloudfront-distribution-tls-version + - pattern-inside: | + require('vm') + ... + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $CONTEXT = <... $REQ.$QUERY.$FOO ...>; + ... + $VM.runInContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; + ... + $VM.runInContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; + ... + $VM.runInContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $VAR = <... $REQ.$QUERY.$FOO ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + $VM.runInContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $CONTEXT = <... $REQ.$BODY ...>; + ... + $VM.runInContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $CONTEXT = <... {$NAME:$REQ.$BODY} ...>; + ... + $VM.runInContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; + ... + $VM.runInContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $VAR = <... $REQ.$BODY ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + $VM.runInContext($CODE,<... $CONTEXT ...>,...) + severity: ERROR + - id: rules_lgpl_javascript_eval_rule-vm-runinnewcontext-injection languages: - - hcl - message: Detected an AWS CloudFront Distribution with an insecure TLS version. TLS versions less than 1.2 are considered insecure because they can be broken. To fix this, set your `minimum_protocol_version` to `"TLSv1.2_2018", "TLSv1.2_2019" or "TLSv1.2_2021"`. + - javascript + message: | + Untrusted user input in `vm.runInNewContext()` can result in code injection. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-94 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - aws + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code (Code Injection) patterns: - - pattern: | - resource "aws_cloudfront_distribution" $ANYTHING { - ... - viewer_certificate { + - pattern-inside: | + require('vm') + ... + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $VM.runInNewContext($CODE,<... $REQ.$QUERY.$FOO ...>,...) + - pattern: | + $CONTEXT = <... $REQ.$QUERY.$FOO ...>; ... - } - ... - } - - pattern-not-inside: | - resource "aws_cloudfront_distribution" $ANYTHING { - ... - viewer_certificate { + $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; ... - minimum_protocol_version = "TLSv1.2_2018" + $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; ... - } - ... - } - - pattern-not-inside: | - resource "aws_cloudfront_distribution" $ANYTHING { - ... - viewer_certificate { + $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $VAR = <... $REQ.$QUERY.$FOO ...>; ... - minimum_protocol_version = "TLSv1.2_2019" + $CONTEXT = {$NAME: <... $VAR ...>}; ... - } - ... - } - - pattern-not-inside: | - resource "aws_cloudfront_distribution" $ANYTHING { - ... - viewer_certificate { + $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $VM.runInNewContext($CODE,<... $REQ.$BODY ...>,...) + - pattern: | + $CONTEXT = <... $REQ.$BODY ...>; ... - minimum_protocol_version = "TLSv1.2_2021" + $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-cloudwatch-log-group-no-retention.aws-cloudwatch-log-group-no-retention + $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $CONTEXT = <... {$NAME:$REQ.$BODY} ...>; + ... + $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) + - pattern: | + $VAR = <... $REQ.$BODY ...>; + ... + $CONTEXT = {$NAME: <... $VAR ...>}; + ... + $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) + severity: ERROR + - id: rules_lgpl_javascript_eval_rule-yaml-deserialize languages: - - hcl - message: The AWS CloudWatch Log Group has no retention. Missing retention in log groups can cause losing important event information. + - javascript + - typescript + message: | + User controlled data in 'yaml.load()' function can result in Remote Code Injection. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-502 owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: CRITICAL + shortDescription: Deserialization of Untrusted Data patterns: + - pattern-either: + - pattern: | + require('js-yaml').load(...) + - pattern-inside: | + $MOD = require('js-yaml') + ... + - pattern-inside: | + import $MOD from 'js-yaml' + ... - pattern: | - resource "aws_cloudwatch_log_group" $ANYTHING { - ... - } + $MOD.load(...) + severity: ERROR + - id: rules_lgpl_javascript_exec_rule-shelljs-os-command-exec + languages: + - javascript + message: | + User controlled data in 'shelljs.exec()' can result in Remote OS Command Execution. + metadata: + category: security + cwe: CWE-78 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + patterns: + - pattern-inside: | + require('shelljs') + ... + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $EXEC.exec(<... $REQ.$QUERY.$VAR ...>, ...) + - pattern: | + $EXEC.exec( <... $REQ.$QUERY ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY.$VAR ...>; + ... + $EXEC.exec(<... $INP ...>, ...) + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + $EXEC.exec(<... $INP ...>, ...) + severity: ERROR + - id: rules_lgpl_javascript_headers_rule-cookie-session-default + languages: + - javascript + message: | + Consider changing the default session cookie name. An attacker can use it to fingerprint the server and target attacks accordingly. + metadata: + category: security + cwe: CWE-522 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: INFO + shortDescription: Insufficiently protected credentials + patterns: + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session') + ... + - pattern-inside: | + $SESSION = require('express-session') + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {name:...} ...>,...) - pattern-not-inside: | - resource "aws_cloudwatch_log_group" $ANYTHING { - ... - retention_in_days = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-codebuild-project-unencrypted.aws-codebuild-project-unencrypted + $OPTS = <... {name:...} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.name = ...; + ... + $SESSION($OPTS,...) + severity: INFO + - id: rules_lgpl_javascript_headers_rule-cookie-session-no-domain languages: - - hcl - message: The AWS CodeBuild Project is unencrypted. The AWS KMS encryption key protects projects in the CodeBuild. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. + - javascript + message: | + 'Default session middleware settings: `domain` not set. It indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.' metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: LOW + cwe: CWE-522 owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: INFO + shortDescription: Insufficiently protected credentials patterns: - - pattern: | - resource "aws_codebuild_project" $ANYTHING { - ... - } + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session') + ... + - pattern-inside: | + $SESSION = require('express-session') + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{domain:...}} ...>,...) - pattern-not-inside: | - resource "aws_codebuild_project" $ANYTHING { - ... - encryption_key = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-config-aggregator-not-all-regions.aws-config-aggregator-not-all-regions + $OPTS = <... {cookie:{domain:...}} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {domain:...} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {domain:...} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.domain = ...; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.domain = ...; + ... + $SESSION($OPTS,...) + severity: INFO + - id: rules_lgpl_javascript_headers_rule-cookie-session-no-httponly languages: - - hcl - message: The AWS configuration aggregator does not aggregate all AWS Config region. This may result in unmonitored configuration in regions that are thought to be unused. Configure the aggregator with all_regions for the source. + - javascript + message: | + 'Session middleware settings: `httpOnly` is explicitly set to false. It ensures that sensitive cookies cannot be accessed by client side JavaScript and helps to protect against cross-site scripting attacks.' metadata: category: security - confidence: HIGH - cwe: - - 'CWE-778: Insufficient Logging' - impact: MEDIUM - likelihood: LOW + cwe: CWE-1004 owasp: - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ - subcategory: - - audit - technology: - - terraform - - aws - pattern-either: - - pattern: | - resource "aws_config_configuration_aggregator" $ANYTHING { - ... - account_aggregation_source { + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: MEDIUM + shortDescription: Sensitive cookie without 'HttpOnly' flag + patterns: + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session') ... - regions = ... + - pattern-inside: | + $SESSION = require('express-session') ... - } - ... - } - - pattern: | - resource "aws_config_configuration_aggregator" $ANYTHING { - ... - organization_aggregation_source { + - pattern-either: + - pattern-inside: $SESSION(<... {cookie:{httpOnly:false}} ...>,...) + - pattern-inside: | + $OPTS = <... {cookie:{httpOnly:false}} ...>; ... - regions = ... + $SESSION($OPTS,...) + - pattern-inside: | + $OPTS = ...; ... - } - ... - } + $COOKIE = <... {httpOnly:false} ...>; + ... + $SESSION($OPTS,...) + - pattern-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {httpOnly:false} ...>; + ... + $SESSION($OPTS,...) + - pattern-inside: | + $OPTS = ...; + ... + $COOKIE.httpOnly = false; + ... + $SESSION($OPTS,...) + - pattern-inside: | + $OPTS = ...; + ... + $OPTS.cookie.httpOnly = false; + ... + $SESSION($OPTS,...) severity: WARNING - - id: terraform.aws.security.aws-db-instance-no-logging.aws-db-instance-no-logging + - id: rules_lgpl_javascript_headers_rule-cookie-session-no-maxage languages: - - hcl - message: Database instance has no logging. Missing logs can cause missing important event information. + - javascript + message: | + 'Session middleware settings: `maxAge` not set. Use it to set expiration date for cookies.' metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: LOW - likelihood: MEDIUM + cwe: CWE-613 owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - vuln - technology: - - aws - - terraform + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: INFO + shortDescription: Insufficient session expiration patterns: - - pattern: | - resource "aws_db_instance" $ANYTHING { - ... - } + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session') + ... + - pattern-inside: | + $SESSION = require('express-session') + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{maxAge:...}} ...>,...) - pattern-not-inside: | - resource "aws_db_instance" $ANYTHING { - ... - enabled_cloudwatch_logs_exports = [$SOMETHING, ...] - ... - } - severity: WARNING - - id: terraform.aws.security.aws-documentdb-auditing-disabled.aws-documentdb-auditing-disabled + $OPTS = <... {cookie:{maxAge:...}} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {maxAge:...} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {maxAge:...} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.maxAge = ...; + ... + $SESSION($OPTS,...) + - pattern-not-inside: |- + $OPTS = ...; + ... + $OPTS.cookie.maxAge = ...; + ... + $SESSION($OPTS,...) + severity: INFO + - id: rules_lgpl_javascript_headers_rule-cookie-session-no-path languages: - - hcl - message: Auditing is not enabled for DocumentDB. To ensure that you are able to accurately audit the usage of your DocumentDB cluster, you should enable auditing and export logs to CloudWatch. + - javascript + message: | + 'Default session middleware settings: `path` not set. It indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request.' metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-778: Insufficient Logging' - impact: LOW - likelihood: LOW + cwe: CWE-522 owasp: - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_cluster#enabled_cloudwatch_logs_exports - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ - subcategory: - - audit - technology: - - terraform - - aws + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: INFO + shortDescription: Insufficiently protected credentials patterns: - - pattern: | - resource "aws_docdb_cluster" $ANYTHING { - ... - } + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session') + ... + - pattern-inside: | + $SESSION = require('express-session') + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{path:...}} ...>,...) - pattern-not-inside: | - resource "aws_docdb_cluster" $ANYTHING { - ... - enabled_cloudwatch_logs_exports = [..., "audit", ...] - ... - } + $OPTS = <... {cookie:{path:...}} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {path:...} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {path:...} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.path = ...; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.path = ...; + ... + $SESSION($OPTS,...) severity: INFO - - id: terraform.aws.security.aws-dynamodb-table-unencrypted.aws-dynamodb-table-unencrypted + - id: rules_lgpl_javascript_headers_rule-cookie-session-no-samesite languages: - - hcl - message: By default, AWS DynamoDB Table is encrypted using AWS-managed keys. However, for added security, it's recommended to configure your own AWS KMS encryption key to protect your data in the DynamoDB table. You can either create a new aws_kms_key resource or use the ARN of an existing key in your AWS account to do so. + - javascript + message: | + 'Default session middleware settings: `sameSite` attribute is not configured to strict or lax. These configurations provides protection against Cross Site Request Forgery attacks.' metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-1275 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: MEDIUM + shortDescription: Sensitive cookie with improper SameSite attribute patterns: - - pattern: | - resource "aws_dynamodb_table" $ANYTHING { - ... - } + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session') + ... + - pattern-inside: | + $SESSION = require('express-session') + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{sameSite:true}} ...>,...) + - pattern-not-inside: $SESSION(<... {cookie:{sameSite:'lax'}} ...>,...) + - pattern-not-inside: $SESSION(<... {cookie:{sameSite:'strict'}} ...>,...) - pattern-not-inside: | - resource "aws_dynamodb_table" $ANYTHING { - ... - server_side_encryption { - enabled = true - kms_key_arn = ... - } - ... - } + $OPTS = <... {cookie:{sameSite:true}} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {sameSite:true} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {sameSite:true} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.sameSite = true; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.sameSite = true; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{sameSite:'strict'}} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {sameSite:'strict'} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {sameSite:'strict'} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.sameSite = 'strict'; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.sameSite = 'strict'; + ... + $SESSION($OPTS,...) severity: WARNING - - id: terraform.aws.security.aws-ebs-snapshot-encrypted-with-cmk.aws-ebs-snapshot-encrypted-with-cmk + - id: rules_lgpl_javascript_headers_rule-cookie-session-no-secure languages: - - hcl - message: Ensure EBS Snapshot is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + - javascript + message: | + 'Default session middleware settings: `secure` not set. It ensures the browser only sends the cookie over HTTPS.' metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-614 owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - aws + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: MEDIUM + shortDescription: Sensitive cookie in HTTPS session without 'Secure' attribute patterns: - - pattern: | - resource "aws_ebs_snapshot_copy" $ANYTHING { - ... - encrypted = true - ... - } + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session') + ... + - pattern-inside: | + $SESSION = require('express-session') + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{secure:true}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{secure:true}} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {secure:true} ...>; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {secure:true} ...>; + ... + $SESSION($OPTS,...) - pattern-not-inside: | - resource "aws_ebs_snapshot_copy" $ANYTHING { - ... - encrypted = true - kms_key_id = ... - ... - } + $OPTS = ...; + ... + $COOKIE.secure = true; + ... + $SESSION($OPTS,...) + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.secure = true; + ... + $SESSION($OPTS,...) severity: WARNING - - id: terraform.aws.security.aws-ebs-unencrypted.aws-ebs-unencrypted + - id: rules_lgpl_javascript_headers_rule-express-cors languages: - - hcl - message: The AWS EBS is unencrypted. The AWS EBS encryption protects data in the EBS. + - javascript + message: | + Access-Control-Allow-Origin response header is set to "*". This will disable CORS Same Origin Policy restrictions. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-346 owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Origin validation error patterns: - - pattern: | - resource "aws_ebs_encryption_by_default" $ANYTHING { - ... - enabled = false - ... - } + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $APP.options('*', cors(...)) + - pattern: | + $RES.set("=~/access-control-allow-origin/i", '*', ...) + - pattern: | + $RES.set(..., { "=~/access-control-allow-origin/i" : '*' }, ...) + - pattern: | + $RES.header("=~/access-control-allow-origin/i", '*', ...) + - pattern: | + $RES.writeHead(..., {"=~/access-control-allow-origin/i": '*' }, ...) severity: WARNING - - id: terraform.aws.security.aws-ebs-volume-unencrypted.aws-ebs-volume-unencrypted + - id: rules_lgpl_javascript_headers_rule-generic-cors languages: - - hcl - message: The AWS EBS volume is unencrypted. The volume, the disk I/O and any derived snapshots could be read if compromised. Volumes should be encrypted to ensure sensitive data is stored securely. + - javascript + message: | + Access-Control-Allow-Origin response header is set to "*". This will disable CORS Same Origin Policy restrictions. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: MEDIUM + cwe: CWE-346 owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume#encrypted - - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html - subcategory: - - audit - technology: - - terraform - - aws + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Origin validation error patterns: - pattern: | - resource "aws_ebs_volume" $ANYTHING { - ... - } - - pattern-not: | - resource "aws_ebs_volume" $ANYTHING { - ... - encrypted = true - ... - } + $APP.options('*', cors(...)) severity: WARNING - - id: terraform.aws.security.aws-ec2-has-public-ip.aws-ec2-has-public-ip + - id: rules_lgpl_javascript_headers_rule-generic-header-injection languages: - - hcl - message: EC2 instances should not have a public IP address attached in order to block public access to the instances. To fix this, set your `associate_public_ip_address` to `"false"`. + - javascript + message: | + Untrusted user input in response header will result in HTTP Header Injection or Response Splitting Attacks. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-284: Improper Access Control' - impact: MEDIUM - likelihood: LOW + cwe: CWE-644 owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - terraform - - aws + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of HTTP headers for scripting syntax patterns: + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - pattern-either: - pattern: | - resource "aws_instance" $ANYTHING { - ... - associate_public_ip_address = true - ... - } + $INP = $REQ.$QUERY; + ... + $RES.set(..., <... $INP ...>, ...) - pattern: | - resource "aws_launch_template" $ANYTHING { - ... - network_interfaces { - ... - associate_public_ip_address = true - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ec2-launch-template-metadata-service-v1-enabled.aws-ec2-launch-template-metadata-service-v1-enabled - languages: - - hcl - message: The EC2 launch template has Instance Metadata Service Version 1 (IMDSv1) enabled. IMDSv2 introduced session authentication tokens which improve security when talking to IMDS. You should either disable IMDS or require the use of IMDSv2. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1390: Weak Authentication' - impact: HIGH - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration#metadata_options - - https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_launch_template" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_launch_template" $ANYTHING { - ... - metadata_options { + $INP = $REQ.$QUERY.$VAR; ... - http_endpoint = "disabled" + $RES.set(..., <... $INP ...>, ...) + - pattern: | + $INP = $REQ.$VAR; ... - } - ... - } - - pattern-not-inside: | - resource "aws_launch_template" $ANYTHING { - ... - metadata_options { + $RES.set(..., { $X: <... $INP ...>}, ...) + - pattern: | + $INP = $REQ.$QUERY.$FOO; ... - http_tokens = "required" + $RES.set(..., { $X: <... $INP ...>}, ...) + - pattern: | + $INP = $REQ.$VAR; ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ecr-mutable-image-tags.aws-ecr-mutable-image-tags + $RES.writeHead(..., { $X: <... $INP ...> }, ...) + - pattern: | + $INP = $REQ.$QUERY.$FOO; + ... + $RES.writeHead(..., { $X: <... $INP ...> }, ...) + - pattern: | + $RES.set(..., <... $REQ.$QUERY ...>, ...) + - pattern: | + $RES.set(..., <... $REQ.$QUERY.$VAR ...>, ...) + - pattern: | + $RES.set(..., { $X: <... $REQ.$VAR ...>}, ...) + - pattern: | + $RES.set(..., { $X: <... $REQ.$QUERY.$FOO ...>}, ...) + - pattern: | + $RES.writeHead(..., { $X: <... $REQ.$VAR ...> }, ...) + - pattern: | + $RES.writeHead(..., { $X: <... $REQ.$QUERY.$FOO ...> }, ...) + severity: ERROR + - id: rules_lgpl_javascript_headers_rule-header-xss-generic languages: - - hcl - message: The ECR repository allows tag mutability. Image tags could be overwritten with compromised images. ECR images should be set to IMMUTABLE to prevent code injection through image mutation. This can be done by setting `image_tag_mutability` to IMMUTABLE. + - javascript + message: | + X-XSS-Protection header is set to 0. This will disable the browser's XSS Filter. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-345: Insufficient Verification of Data Authenticity' - impact: HIGH - likelihood: LOW + cwe: CWE-358 owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository#image_tag_mutability - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/ - subcategory: - - audit - technology: - - terraform - - aws + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Improperly implemented security check for standard patterns: - - pattern: | - resource "aws_ecr_repository" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_ecr_repository" $ANYTHING { - ... - image_tag_mutability = "IMMUTABLE" - ... - } + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $RES.header("=~/x-xss-protection/i", 0, ...) + - pattern: | + $RES.set("=~/x-xss-protection/i", 0, ...) + - pattern: | + $RES.set(..., { "=~/x-xss-protection/i" : 0 }, ...) + - pattern: | + $RES.writeHead(..., {"=~/x-xss-protection/i": 0 }, ...) severity: WARNING - - id: terraform.aws.security.aws-ecr-repository-wildcard-principal.aws-ecr-repository-wildcard-principal + - id: rules_lgpl_javascript_headers_rule-header-xss-lusca languages: - - hcl - message: Detected wildcard access granted in your ECR repository policy principal. This grants access to all users, including anonymous users (public access). Instead, limit principals, actions and resources to what you need according to least privilege. + - javascript + message: | + X-XSS-Protection header is set to 0. This will disable the browser's XSS Filter. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: CWE-358 owasp: - - A05:2021 - Security Misconfiguration - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository_policy - - https://docs.aws.amazon.com/lambda/latest/operatorguide/wildcard-permissions-iam.html - - https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/monitor-amazon-ecr-repositories-for-wildcard-permissions-using-aws-cloudformation-and-aws-config.html - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - vuln - technology: - - aws - - terraform + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Improperly implemented security check for standard patterns: - pattern-inside: | - resource "aws_ecr_repository_policy" $ANYTHING { - ... - } + $X = require('lusca') + ... + - pattern-not: | + $X.use(helmet()) - pattern-either: - - patterns: - - pattern: policy = "$JSONPOLICY" - - metavariable-pattern: - language: json - metavariable: $JSONPOLICY - patterns: - - pattern-not-inside: | - {..., "Effect": "Deny", ...} - - pattern-either: - - pattern: | - {..., "Principal": "*", ...} - - pattern: | - {..., "Principal": [..., "*", ...], ...} - - pattern: | - {..., "Principal": { "AWS": "*" }, ...} - - pattern: | - {..., "Principal": { "AWS": [..., "*", ...] }, ...} - - patterns: - - pattern-inside: policy = jsonencode(...) - - pattern-not-inside: | - {..., Effect = "Deny", ...} - - pattern-either: - - pattern: | - {..., Principal = "*", ...} - - pattern: | - {..., Principal = [..., "*", ...], ...} - - pattern: | - {..., Principal = { AWS = "*" }, ...} - - pattern: | - {..., Principal = { AWS = [..., "*", ...] }, ...} + - pattern: | + $X.xssProtection(false) + - pattern: | + $X({ xssProtection: false}) severity: WARNING - - id: terraform.aws.security.aws-efs-filesystem-encrypted-with-cmk.aws-efs-filesystem-encrypted-with-cmk + - id: rules_lgpl_javascript_headers_rule-helmet-feature-disabled languages: - - hcl - message: Ensure EFS filesystem is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. + - javascript + message: | + One or more Security Response header is explicitly disabled in Helmet. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-358 owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Improperly implemented security check for standard patterns: - - pattern: | - resource "aws_efs_file_system" $ANYTHING { - ... - encrypted = true - ... - } - - pattern-not-inside: | - resource "aws_efs_file_system" $ANYTHING { - ... - encrypted = true - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-elasticsearch-insecure-tls-version.aws-elasticsearch-insecure-tls-version - languages: - - terraform - message: Detected an AWS Elasticsearch domain using an insecure version of TLS. To fix this, set "tls_security_policy" equal to "Policy-Min-TLS-1-2-2019-07". - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform - pattern: | - resource "aws_elasticsearch_domain" $ANYTHING { - ... - domain_endpoint_options { - ... - enforce_https = true - tls_security_policy = "Policy-Min-TLS-1-0-2019-07" - ... - } - ... - } + - pattern-either: + - pattern: | + $HELMET(..., {frameguard: false}, ...) + - pattern: | + $HELMET(..., {contentSecurityPolicy: false}, ...) + - pattern: | + $HELMET(..., {permittedCrossDomainPolicies: false}, ...) + - pattern: | + $HELMET(..., {dnsPrefetchControl: false}, ...) + - pattern: | + $HELMET(..., {expectCt: false}, ...) + - pattern: | + $HELMET(..., {featurePolicy: false}, ...) + - pattern: | + $HELMET(..., {hsts: false}, ...) + - pattern: | + $HELMET(..., {ieNoOpen: false}, ...) + - pattern: | + $HELMET(..., {noSniff: false}, ...) + - pattern: | + $HELMET(..., {hidePoweredBy: false}, ...) + - pattern: | + $HELMET(..., {referrerPolicy: false}, ...) + - pattern: | + $HELMET(..., {xssFilter: false}, ...) severity: WARNING - - id: terraform.aws.security.aws-elasticsearch-nodetonode-encryption.aws-elasticsearch-nodetonode-encryption-not-enabled + - id: rules_lgpl_javascript_headers_rule-host-header-injection languages: - - hcl - message: "Ensure all Elasticsearch has node-to-node encryption enabled.\t" + - javascript + message: | + Using untrusted Host header for generating dynamic URLs can result in web cache and or password reset poisoning. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-348 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - aws + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Use of less trusted source patterns: + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - pattern-either: - pattern: | - resource "aws_elasticsearch_domain" $ANYTHING { - ... - node_to_node_encryption { - ... - enabled = false - ... - } - ... - } + $X = <... "=~/.*http[s]*:///i" + $REQ.host ...>; - pattern: | - resource "aws_elasticsearch_domain" $ANYTHING { - ... - cluster_config { - ... - instance_count = $COUNT - ... - } - } - - pattern-not-inside: | - resource "aws_elasticsearch_domain" $ANYTHING { - ... - cluster_config { + $X = <... "=~/.*http[s]*:///i" + $REQ["host"] ...>; + - pattern: | + $X = <... "=~/.*http[s]*:///i" + $REQ("host") ...>; + - pattern: | + $X = { $Y: <... "=~/.*http[s]*:///i" + $REQ.host ...>}; + - pattern: | + $X = { $Y: <... "=~/.*http[s]*:///i" + $REQ["host"] ...>}; + - pattern: | + $X = { $Y: <... "=~/.*http[s]*:///i" + $REQ("host") ...>}; + - pattern: | + $Z = $REQ.host; ... - instance_count = $COUNT + $X = <... "=~/.*http[s]*:///i" + $Z ...>; + - pattern: | + $Z = $REQ["host"]; ... - } - node_to_node_encryption { + $X = <... "=~/.*http[s]*:///i" + $Z ...>; + - pattern: | + $Z = $REQ("host") ... - enabled = true + $X = <... "=~/.*http[s]*:///i" + $Z ...>; + - pattern: | + $Z = $REQ.host; ... - } - } - - metavariable-comparison: - comparison: $COUNT > 1 - metavariable: $COUNT + $X = { $Y: <... "=~/.*http[s]*:///i" + $REQ.host ...>}; + - pattern: | + $Z = $REQ["host"]; + ... + $X = { $Y: <... "=~/.*http[s]*:///i" + $Z ...>}; + - pattern: | + $Z = $REQ("host") + ... + $X = { $Y: <... "=~/.*http[s]*:///i" + $REQ("host") ...>}; severity: WARNING - - id: terraform.aws.security.aws-glacier-vault-any-principal.aws-glacier-vault-any-principal - languages: - - hcl - message: 'Detected wildcard access granted to Glacier Vault. This means anyone within your AWS account ID can perform actions on Glacier resources. Instead, limit to a specific identity in your account, like this: `arn:aws:iam:::`.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - vuln - technology: - - aws - patterns: - - pattern-inside: | - resource "aws_glacier_vault" $ANYTHING { - ... - } - - pattern: access_policy = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: - - pattern-inside: | - {..., "Effect": "Allow", ...} - - pattern-either: - - pattern: | - "Principal": "*" - - pattern: | - "Principal": {..., "AWS": "*", ...} - - pattern-inside: | - "Principal": {..., "AWS": ..., ...} - - pattern-regex: | - (^\"arn:aws:iam::\*:(.*)\"$) - severity: ERROR - - id: terraform.aws.security.aws-iam-admin-policy-ssoadmin.aws-iam-admin-policy-ssoadmin - languages: - - hcl - message: Detected admin access granted in your policy. This means anyone with this policy can perform administrative actions. Instead, limit actions and resources to what you need according to least privilege. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - vuln - technology: - - aws - patterns: - - pattern-inside: | - resource "aws_ssoadmin_permission_set_inline_policy" $ANYTHING { - ... - } - - pattern: inline_policy = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: - - pattern-not-inside: | - {..., "Effect": "Deny", ...} - - pattern-either: - - pattern: | - {..., "Action": [..., "*", ...], "Resource": [..., "*", ...], ...} - - pattern: | - {..., "Action": "*", "Resource": "*", ...} - - pattern: | - {..., "Action": "*", "Resource": [...], ...} - - pattern: | - {..., "Action": [...], "Resource": "*", ...} - severity: ERROR - - id: terraform.aws.security.aws-iam-admin-policy.aws-iam-admin-policy + - id: rules_lgpl_javascript_jwt_rule-hardcoded-jwt-secret languages: - - hcl - message: Detected admin access granted in your policy. This means anyone with this policy can perform administrative actions. Instead, limit actions and resources to what you need according to least privilege. + - javascript + message: "Hardcoded JWT secret or private key was found. Hardcoding secrets like JWT signing keys poses a significant security risk. \nIf the source code ends up in a public repository or is compromised, the secret is exposed. Attackers could then use the secret to \ngenerate forged tokens and access the system. Store it properly in an environment variable.\n\nHere are some recommended safe ways to access JWT secrets:\n - Use environment variables to store the secret and access it in code instead of hardcoding. This keeps it out of source control.\n - Use a secrets management service to securely store and tightly control access to the secret. Applications can request the secret at runtime.\n - For local development, use a .env file that is gitignored and access the secret from process.env.\n\nsample code snippet of accessing JWT secret from env variables\n```\n const token = jwt.sign(payload, process.env.SECRET, { algorithm: 'HS256' });\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-798 owasp: - - A05:2021 - Security Misconfiguration - references: - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - vuln - technology: - - aws - - terraform + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: HIGH + shortDescription: Use of hard-coded credentials patterns: - - pattern-inside: | - resource "aws_iam_policy" $ANYTHING { - ... - } - - pattern: policy = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: - - pattern-not-inside: | - {..., "Effect": "Deny", ...} + - pattern-either: + - pattern-inside: | + const $JWT = require("jsonwebtoken"); + ... + - pattern-inside: | + const $JOSE = require("jose"); + ... + - pattern-inside: | + import $JWT from "jsonwebtoken" + ... + - pattern-inside: | + import $JOSE from "jose" + ... + - pattern-either: + - pattern: $JWT.sign($PAYLOAD, "...", ...) + - pattern: $JWT.verify($PAYLOAD, "...", ...) + - pattern: new $JOSE.SignJWT(...). ... .sign("...") + - pattern: | + var $TOKEN = new $JOSE.SignJWT(...). ... + ... + $TOKEN. ... .sign("...") + - pattern: $JOSE.jwtVerify( $TKN, "...", ... ) + - patterns: - pattern-either: - - pattern: | - {..., "Action": [..., "*", ...], "Resource": [..., "*", ...], ...} - - pattern: | - {..., "Action": "*", "Resource": "*", ...} - - pattern: | - {..., "Action": "*", "Resource": [...], ...} - - pattern: | - {..., "Action": [...], "Resource": "*", ...} + - patterns: + - pattern-inside: | + var $KEY = $X + ... + - pattern-either: + - pattern: new $JOSE.SignJWT(...). ... .sign($KEY) + - patterns: + - pattern: | + var $TOKEN = new $JOSE.SignJWT(...). ... + ... + $TOKEN. ... .sign($KEY) + - pattern: $TOKEN. ... .sign($KEY) + - pattern: $JOSE.jwtVerify( $TKN, $KEY, ... ) + - pattern: new $JOSE.SignJWT(...). ... .sign($X) + - patterns: + - pattern: | + var $TOKEN = new $JOSE.SignJWT(...). ... + ... + $TOKEN. ... .sign($X) + - pattern: $TOKEN. ... .sign($X) + - pattern: $JOSE.jwtVerify( $TKN, $X, ... ) + - metavariable-pattern: + metavariable: $X + pattern-either: + - pattern: new TextEncoder().encode( "...",... ) + - pattern: Uint8Array.from("...", ...) severity: ERROR - - id: terraform.aws.security.aws-insecure-api-gateway-tls-version.aws-insecure-api-gateway-tls-version + - id: rules_lgpl_javascript_jwt_rule-jwt-exposed-credentials languages: - - terraform - message: Detected AWS API Gateway to be using an insecure version of TLS. To fix this issue make sure to set "security_policy" equal to "TLS_1_2". + - javascript + message: "The application is storing a password in the JWT token payload. Storing \npasswords in JWT token payloads is an insecure practice that can lead to \ncompromised credentials. \n\nThe password transmitted in the JWT payload is not encrypted and therefore \nvisible to anyone who intercepts the token. It is recommended to avoid storing \nsensitive information like passwords in JWTs. Instead, reference user identifiers \nthat map to credentials stored securely on the server.This helps to mitigate the \nrisk of exposing passwords through JWT tokens that could be intercepted or leaked.\n\nSecure code example of secure JWT signing:\n```\nrouter.route(\"/jsonwebtoken/1\").get((req, res) => {\n // any payload without passwords or any other sensitive data will be secure\n const payload = { user_id: 123, username: 'john_doe' };\n const token = jwt.sign(payload, secretKey, { algorithm: 'HS256' });\n console.log('Generated Token:', token);\n res.send({ token })\n})\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-522 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: HIGH + shortDescription: Insufficiently protected credentials patterns: - pattern-either: - - pattern: | - resource "aws_api_gateway_domain_name" $ANYTHING { + - pattern-inside: | + const $JWT = require("jsonwebtoken"); + ... + - pattern-inside: | + const $JOSE = require("jose"); + ... + - pattern-inside: | + import $JWT from "jsonwebtoken" + ... + - pattern-inside: | + import $JOSE from "jose" + ... + - pattern-either: + - pattern: '$JWT.sign(<... {$PASSWORD: $VALUE} ...>, ...)' + - patterns: + - pattern: | + $OBJ = <... {$PASSWORD: $VALUE} ...> ... - security_policy = "..." + $TOKEN = $JWT.sign(<... $OBJ ...>, ...) + - pattern: $TOKEN = $JWT.sign(<... $OBJ ...>, ...) + - patterns: + - pattern: | + $OBJ. ... .$PASSWORD = ... ... - } - - pattern: | - resource "aws_apigatewayv2_domain_name" $ANYTHING { + $TOKEN = $JWT.sign(<... $OBJ ...>, ...) + - pattern: $TOKEN = $JWT.sign(<... $OBJ ...>, ...) + - pattern: 'new $JOSE.SignJWT(<... {$PASSWORD: $VALUE} ...>)' + - patterns: + - pattern: | + $OBJ = <... {$PASSWORD: $VALUE} ...> ... - domain_name_configuration {...} + new $JOSE.SignJWT(<... $OBJ ...>) + - pattern: new $JOSE.SignJWT(<... $OBJ ...>) + - patterns: + - pattern: | + $OBJ. ... .$PASSWORD = ... ... - } - - pattern-not: | - resource "aws_api_gateway_domain_name" $ANYTHING { + new $JOSE.SignJWT(<... $OBJ ...>) + - pattern: new $JOSE.SignJWT(<... $OBJ ...>) + - metavariable-regex: + metavariable: $PASSWORD + regex: (?i)\b(?:.*password.*)\b + severity: ERROR + - id: rules_lgpl_javascript_jwt_rule-jwt-exposed-data + languages: + - javascript + message: | + The object is passed strictly to jose.JWT.sign(...). Make sure that sensitive information is not exposed through JWT token payload. + metadata: + category: security + cwe: CWE-522 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: HIGH + shortDescription: Insufficiently protected credentials + patterns: + - pattern-inside: | + require('jose') + ... + - pattern-either: + - patterns: + - pattern-inside: function (...,$INPUT,...) {...} + - pattern-either: + - pattern: $JOSE.JWT.sign($INPUT,...) + - pattern: $JWT.sign($INPUT,...) + - patterns: + - pattern-inside: function $F(...,$INPUT,...) {...} + - pattern-either: + - pattern: $JOSE.JWT.sign($INPUT,...) + - pattern: $JWT.sign($INPUT,...) + severity: WARNING + - id: rules_lgpl_javascript_jwt_rule-jwt-express-hardcoded + languages: + - javascript + message: "Hardcoded JWT secret or private key was found. Hardcoding secrets like JWT signing keys poses a significant security risk. \nIf the source code ends up in a public repository or is compromised, the secret is exposed. Attackers could then use the secret to \ngenerate forged tokens and access the system. Store it properly in an environment variable.\n\nHere are some recommended safe ways to access JWT secrets:\n - Use environment variables to store the secret and access it in code instead of hardcoding. This keeps it out of source control.\n - Use a secrets management service to securely store and tightly control access to the secret. Applications can request the secret at runtime.\n - For local development, use a .env file that is gitignored and access the secret from process.env.\n\nsample code snippet of accessing JWT secret from env variables\n```\nrouter.route(\"/auth-route-1\").get(\n jwt({ secret: process.env.secret, algorithms: ['HS256'] }),\n (req, res) => {\n res.send('Token is valid');\n }\n);\n```\n" + metadata: + category: security + cwe: CWE-522 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: CRITICAL + shortDescription: Insufficiently protected credentials + patterns: + - pattern-either: + - pattern-inside: | + import { ..., $JWT,... } from 'express-jwt'; + ... + - pattern-inside: | + var {..., expressjwt: $JWT,... } = require('express-jwt'); + ... + - pattern-either: + - pattern: $JWT(<...{...,secret:"...",...}...>) + - patterns: + - pattern-inside: | + $OPTS = <... {secret: "..."} ...>; ... - security_policy = "TLS_1_2" + - pattern: $JWT(<... $OPTS ...>,...) + - patterns: + - pattern-inside: | + $OPTS = <... {secret: "..."} ...>; ... - } - - pattern-not: | - resource "aws_apigatewayv2_domain_name" $ANYTHING { + $OPTS2 = <... $OPTS ...>; ... - domain_name_configuration { - ... - security_policy = "TLS_1_2" - ... - } - } - severity: WARNING - - id: terraform.aws.security.aws-insecure-redshift-ssl-configuration.aws-insecure-redshift-ssl-configuration + - pattern: $JWT(<... $OPTS2 ...>,...) + severity: ERROR + - id: rules_lgpl_javascript_jwt_rule-jwt-not-revoked languages: - - hcl - message: Detected an AWS Redshift configuration with a SSL disabled. To fix this, set your `require_ssl` to `"true"`. + - javascript + message: | + No token revoking configured for `express-jwt`. A leaked token could still be used and unable to be revoked. Consider using function as the `isRevoked` option. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-522 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - aws + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: HIGH + shortDescription: Insufficiently protected credentials patterns: - - pattern: | - resource "aws_redshift_parameter_group" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_redshift_parameter_group" $ANYTHING { - ... - parameter { - name = "require_ssl" - value = "true" - } - ... - } - - pattern-not-inside: | - resource "aws_redshift_parameter_group" $ANYTHING { - ... - parameter { - name = "require_ssl" - value = true - } - ... - } + - pattern-inside: | + $JWT = require('express-jwt') + ... + - pattern: $JWT(...) + - pattern-not-inside: $JWT(<... {isRevoked:...} ...>,...) + - pattern-not-inside: |- + $OPTS = <... {isRevoked:...} ...>; + ... + $JWT($OPTS,...) severity: WARNING - - id: terraform.aws.security.aws-kinesis-stream-unencrypted.aws-kinesis-stream-unencrypted + - id: rules_lgpl_javascript_jwt_rule-node-jwt-none-algorithm languages: - - hcl - message: The AWS Kinesis stream does not encrypt data at rest. The data could be read if the Kinesis stream storage layer is compromised. Enable Kinesis stream server-side encryption. + - javascript + message: "Use of `{algorithm:'none'}` detected with `jsonwebtoken`. \nUsing none as the algorithm for jsonwebtoken can directly impact the integrity of the information transfer through the JWT token.\nConsider using a secure algorithm to sign your JWT token such as HMAC or RSA.\nSome safe usage examples:\n```\nlet token = jwt.sign({user:\"user1\"}, 'secret', {algorithm: 'HS256'}); \n```\nUsing a secure algorithm can protect the integrity of the token information. \nAvoid using none as the algorithm when signing jwt tokens since it can violate the integrity of the JWT information.\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW + cwe: CWE-327 owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kinesis_stream#encryption_type - - https://docs.aws.amazon.com/streams/latest/dev/server-side-encryption.html - rule-origin-note: published from /src/aws-kinesis-stream-unencrypted.yml in None - subcategory: - - audit - technology: - - terraform - - aws - patterns: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: CRITICAL + shortDescription: Use of a broken or risky cryptographic algorithm + mode: taint + pattern-sinks: + - pattern: $JWT.verify($P, $X, {...,algorithms:[...,'none',...],...},...) + - pattern: $JWT.sign($P, $X, {...,algorithm:'none',...},...) + pattern-sources: + - pattern: $JWT = require("jsonwebtoken") + - pattern: import $JWT from "jsonwebtoken" + severity: ERROR + - id: rules_lgpl_javascript_redirect_rule-express-open-redirect + languages: + - javascript + message: "Passing untrusted user input in `redirect()` can result in an open redirect\nvulnerability. This could be abused by malicious actors to trick users into \nbeing redirected to websites under their control to capture authentication\ninformation. \nTo prevent open redirect vulnerabilities:\n\n- Always validate and sanitize user inputs, especially URL parameters\n or query strings that may influence the flow of the application.\n- Use allowlists (lists of permitted URLs) to validate redirect targets \n against known, trusted URLs before performing the redirect.\n- Avoid directly using user input for redirecting. If unavoidable, ensure\n strict validation against an allowlist.\n\nFollowing is an example of secure validation against allowlist to prevent the vulnerability:\n ```\n // Define a list of explicitly allowed URLs for redirection\n const allowedUrls = [\n 'https://www.example.com/page1',\n 'https://www.example.com/page2',\n 'https://secure.example.com/page3'\n ];\n\n app.get('/redirect/:url', (req, res) => {\n const url = decodeURIComponent(req.params.url);\n const isAllowed = allowedUrls.includes(url);\n if (isAllowed) {\n // If the URL is allowed, proceed with the redirect\n res.redirect(url);\n } else {\n res.status(400).send('Invalid redirect URL');\n }\n });\n ```\n" + metadata: + category: security + cwe: CWE-601 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: URL redirection to untrusted site 'open redirect' + mode: taint + pattern-sanitizers: + - pattern-either: + - patterns: + - pattern-either: + - pattern: "if($VALIDATION){\n ...\n $RES.redirect(...)\n ...\n} \n" + - pattern: | + $A = $VALIDATION + ... + if($A){ + ... + $RES.redirect(...) + ... + } + - metavariable-pattern: + metavariable: $VALIDATION + pattern-either: + - pattern: "$AL.includes(...) \n" + - pattern: | + $AL.indexOf(...) !== -1 + - pattern: | + $AL.find(...) !== undefined + - pattern: | + $ALS.has(...) + - patterns: + - pattern: | + $RES.redirect("$DOM" + ...) + - metavariable-regex: + metavariable: $DOM + regex: (http(s)?:\/\/.*\/) + pattern-sinks: - pattern: | - resource "aws_kinesis_stream" $ANYTHING { - ... - } - - pattern-not: | - resource "aws_kinesis_stream" $ANYTHING { - ... - encryption_type = "KMS" - ... - } - severity: WARNING - - id: terraform.aws.security.aws-kms-key-wildcard-principal.aws-kms-key-wildcard-principal + $RES.redirect(...) + pattern-sources: + - patterns: + - pattern-inside: | + function ($REQ, $RES, ...) {...} + - focus-metavariable: $REQ + severity: ERROR + - id: rules_lgpl_javascript_redirect_rule-express-open-redirect2 languages: - - hcl - message: Detected wildcard access granted in your KMS key. This means anyone with this policy can perform administrative actions over the keys. Instead, limit principals, actions and resources to what you need according to least privilege. + - javascript + message: "Passing untrusted user input in `redirect()` can result in an open redirect\nvulnerability. This could be abused by malicious actors to trick users into \nbeing redirected to websites under their control to capture authentication\ninformation. \nTo prevent open redirect vulnerabilities:\n\n- Always validate and sanitize user inputs, especially URL parameters\n or query strings that may influence the flow of the application.\n- Use allowlists (lists of permitted URLs) to validate redirect targets \n against known, trusted URLs before performing the redirect.\n- Avoid directly using user input for redirecting. If unavoidable, ensure\n strict validation against an allowlist.\n\nFollowing is an example of secure validation against allowlist to prevent the vulnerability:\n ```\n // Define a list of explicitly allowed URLs for redirection\n const allowedUrls = [\n 'https://www.example.com/page1',\n 'https://www.example.com/page2',\n 'https://secure.example.com/page3'\n ];\n\n app.get('/redirect/:url', (req, res) => {\n const url = decodeURIComponent(req.params.url);\n const isAllowed = allowedUrls.includes(url);\n if (isAllowed) {\n // If the URL is allowed, proceed with the redirect\n res.location(url).status(302).end();\n } else {\n res.status(400).send('Invalid redirect URL');\n }\n });\n ```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-601 owasp: - - A05:2021 - Security Misconfiguration - references: - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern-inside: | - resource "aws_kms_key" $ANYTHING { - ... - } - - pattern: policy = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: - - pattern-not-inside: | - {..., "Effect": "Deny", ...} + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: URL redirection to untrusted site 'open redirect' + mode: taint + pattern-sanitizers: + - pattern-either: + - patterns: - pattern-either: + - pattern: "if($VALIDATION){\n ...\n} \n" - pattern: | - {..., "Principal": "*", "Action": "kms:*", "Resource": "*", ...} + $A = $VALIDATION + ... + if($A){ + ... + } + - metavariable-pattern: + metavariable: $VALIDATION + pattern-either: + - pattern: "$AL.includes(...) \n" + - pattern: | + $AL.indexOf(...) !== -1 + - pattern: | + $AL.find(...) !== undefined + - pattern: | + $ALS.has(...) + pattern-sinks: + - pattern-either: + - patterns: + - pattern-not: | + $RES.$METHOD("=~/location/i", "=~/http(s)?:\/\/.*\//" + ...) + - pattern-not-inside: | + $VAR = "=~/http(s)?:\/\/.*\//" + ...; + ... + - pattern: | + $RES.$METHOD("=~/location/i", $VAR) + - metavariable-regex: + metavariable: $METHOD + regex: (header|set|append|setHeader) + - patterns: + - pattern-not-inside: | + $V = "=~/http(s)?:\/\/.*\//" + ...; + ... + - pattern-not: + patterns: + - pattern: "$RES.writeHead(..., { \n ..., \n location: $V,\n ...\n})\n" + - metavariable-pattern: + metavariable: $V + patterns: + - pattern: | + "=~/http(s)?:\/\/.*\//" + ... + - pattern: "$RES.writeHead(..., { \n ..., \n location: $V,\n ...\n })\n" + - focus-metavariable: $V + - patterns: + - pattern-not: | + $RES.location("=~/http(s)?:\/\/.*\//" + ...) + - pattern-not-inside: | + $VAR = "=~/http(s)?:\/\/.*\//" + ...; + ... + - pattern: | + $RES.location($VAR) + pattern-sources: + - patterns: + - pattern-inside: | + function ($REQ, $RES, ...) {...} + - focus-metavariable: $REQ + severity: ERROR + - id: rules_lgpl_javascript_ssrf_rule-node-ssrf + languages: + - javascript + message: "This application allows user-controlled URLs to be passed directly to HTTP client libraries. \nThis can result in Server-Side Request Forgery (SSRF).\nSSRF refers to an attack where the attacker can abuse functionality on \nthe server to force it to make requests to other internal systems within your \ninfrastructure that are not directly exposed to the internet. \nThis allows the attacker to access internal resources they do not have direct access to.\n\nSome risks of SSRF are:\n\n- Access and manipulation of internal databases, APIs, or administrative panels\n- Ability to scan internal network architecture and services\n- Can be used to pivot attacks into the internal network\n- Circumvent network segregation and firewall rules\n\nTo avoid this, try using hardcoded HTTP request calls or a whitelisting object to \ncheck whether the user input is trying to access allowed resources or not.\n\nHere is an example:\n```\nvar whitelist = [\n \"https://example.com\", \n \"https://example.com/sample\"\n]\n\napp.get('/ssrf/node-ssrf/axios/safe/3', function (req, res) {\n if(whitelist.includes(req.query.url)){\n axios.get(url, {})\n .then(function (response) {\n console.log(response);\n })\n .catch(function (response) {\n console.log(response); \n })\n }\n});\n``` \nFor more information on SSRF see OWASP:\nhttps://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html\n" + metadata: + category: security + cwe: CWE-918 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: HIGH + shortDescription: Server-side request forgery (SSRF) + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: "if($VALIDATION){\n...\n} \n" + - pattern: | + $A = $VALIDATION + ... + if($A){ + ... + } + - metavariable-pattern: + metavariable: $VALIDATION + pattern-either: + - pattern: "$AL.includes(...) \n" - pattern: | - {..., "Principal": [..., "*", ...], "Action": "kms:*", "Resource": "*", ...} + $AL.indexOf(...) !== -1 - pattern: | - {..., "Principal": { "AWS": "*" }, "Action": "kms:*", "Resource": "*", ...} + $AL.find(...) !== undefined - pattern: | - {..., "Principal": { "AWS": [..., "*", ...] }, "Action": "kms:*", "Resource": "*", ...} + $ALS.has(...) + pattern-sinks: + - patterns: + - focus-metavariable: $REQ + - pattern-either: + - pattern-inside: | + $NEEDLE = require('needle'); + ... + - pattern-inside: | + import $NEEDLE from 'needle' + ... + - pattern-either: + - pattern: $NEEDLE('$VERB', $REQ, ...) + - pattern: $NEEDLE.$VERB($REQ, ...) + - metavariable-regex: + metavariable: $VERB + regex: ^(get|put|post|patch|delete|head)$ + - patterns: + - focus-metavariable: $REQ + - pattern-either: + - pattern-inside: | + $AXIOS = require('axios'); + ... + - pattern-inside: | + import $AXIOS from 'axios' + ... + - pattern-either: + - patterns: + - metavariable-regex: + metavariable: $URL + regex: ^(url|baseURL)$ + - pattern-either: + - pattern: | + $AXIOS({ ..., $URL: $REQ, ...}) + - pattern: | + $AXIOS.create({ ..., $URL: $REQ, ...}) + - patterns: + - pattern: $AXIOS.$VERB($REQ, ...) + - metavariable-regex: + metavariable: $VERB + regex: ^(get|put|post|patch|delete|head)$ + - patterns: + - pattern: axios($REQ) + - pattern-not-inside: axios({...}) + - pattern: | + axios.defaults.baseURL = $REQ + - patterns: + - focus-metavariable: $URL + - pattern-either: + - pattern-inside: | + {..., request, ... } = require('urllib'); + ... + - pattern-inside: | + import {..., request, ... } from 'urllib' + ... + - pattern: request($URL, ...) + - patterns: + - focus-metavariable: $URL + - pattern-either: + - pattern-inside: | + {..., HttpClient, ... } = require('urllib'); + ... + - pattern-inside: | + import {..., HttpClient, ... } from 'urllib' + ... + - pattern: | + $HTTPCLIENT = new HttpClient({ + allowH2: true, + }); + ... + $HTTPCLIENT.request($URL, ...) + - patterns: + - focus-metavariable: $URL + - pattern-either: + - pattern-inside: | + $URLLIIB = require('urllib'); + ... + - pattern-inside: | + import $URLLIIB from 'urllib' + ... + - pattern: $URLLIIB.request($URL, ...) + - patterns: + - pattern-either: + - pattern-inside: | + $SA = require('superagent'); + ... + - pattern-inside: | + import $SA from 'superagent' + ... + - patterns: + - pattern: $SA.$VERB(...) + - metavariable-regex: + metavariable: $VERB + regex: ^(get|put|post|patch|delete|head)$ + - patterns: + - pattern-either: + - patterns: + - pattern: fetch($REQ,...) + - focus-metavariable: $REQ + - pattern-not: fetch(new Request(...)) + - patterns: + - pattern: fetch(new Request($REQ,...)) + - focus-metavariable: $REQ + - pattern-not-inside: | + $REQUEST_OBJ = new Request(...) + ... + fetch($REQUEST_OBJ) + - patterns: + - pattern: new Request($REQ,...) + - focus-metavariable: $REQ + - pattern-inside: | + $REQUEST_OBJ = new Request($REQ,...) + ... + fetch($REQUEST_OBJ) + - patterns: + - focus-metavariable: $REQ + - pattern-either: + - pattern-inside: | + $HTTP = require('$PKG'); + ... + - pattern-inside: | + import $HTTP from $PKG + ... + - metavariable-regex: + metavariable: $PKG + regex: ^(http|https)$ + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|request)$ + - pattern-either: + - patterns: + - pattern: $HTTP.$METHOD($REQ, ...) + - pattern-not-inside: | + $HTTP.$METHOD({...}, ...) + - pattern-not-inside: | + $OPTS = {...} + ... + $HTTP.$METHOD($OPTS, ...) + - pattern: | + $HTTP.$METHOD({..., hostname: $REQ}, ...) + - pattern: | + $OPTS = {..., hostname: $REQ, ...} + ... + $HTTP.$METHOD($OPTS, ...) + - patterns: + - focus-metavariable: $REQ + - pattern-either: + - pattern-inside: | + { ..., io, ... } = require('socket.io-client'); + ... + - pattern-inside: | + import { ..., io, ... } from 'socket.io-client' + ... + - pattern: io($REQ, ...) + - patterns: + - focus-metavariable: $HOST + - pattern-either: + - pattern-inside: | + $NET = require('net'); + ... + - pattern-inside: | + import $NET from 'net' + ... + - metavariable-regex: + metavariable: $METHOD + regex: ^(connect|createConnection)$ + - pattern-either: + - pattern: $NET.$METHOD($PORT, $HOST, ...) + - pattern: | + $NET.$METHOD({..., host: $HOST, ...}, ...) + - pattern: | + $OPTS = {..., host: $HOST, ...} + ... + $NET.$METHOD($OPTS, ...) + - pattern: | + $CLIENT = new $NET.Socket() + ... + $CLIENT.$METHOD($PORT, $HOST, ...) + - patterns: + - pattern-either: + - pattern-inside: | + $BENT = require('bent'); + ... + - pattern-inside: | + import $BENT from 'bent'; + ... + - pattern: $BENT(...) + - patterns: + - focus-metavariable: $REQ + - pattern-either: + - pattern-inside: | + $BENT = require('bent'); + ... + $MTD = $BENT(...) + - pattern-inside: | + import $BENT from 'bent'; + ... + $MTD = $BENT(...) + - pattern: $MTD($REQ, ...) + - patterns: + - pattern-either: + - pattern-inside: | + $BENT = require('bent'); + ... + $GETBENT = $BENT('$PKG') + ... + - pattern-inside: | + import $BENT from 'bent'; + ... + $GETBENT = $BENT('$PKG') + ... + - pattern: $GETBENT(...) + - metavariable-regex: + metavariable: $PKG + regex: ^(json|buffer)$ + - patterns: + - focus-metavariable: $REQ + - pattern-either: + - pattern-inside: | + import $GOT from 'got'; + ... + - pattern: $GOT.$VERB($REQ, ...) + - metavariable-regex: + metavariable: $VERB + regex: ^(get|put|post|patch|delete|head)$ + - patterns: + - focus-metavariable: $URL + - pattern-either: + - pattern-inside: | + $REQUEST = require('request'); + ... + - pattern-inside: | + import $REQUEST from 'request'; + ... + - pattern: $REQUEST($URL, ...) + pattern-sources: + - patterns: + - focus-metavariable: $REQ + - pattern: function ($REQ, $RES, ...) {...} + - patterns: + - focus-metavariable: $REQ + - pattern: function $FUNC($REQ, $RES, ...) {...} severity: ERROR - - id: terraform.aws.security.aws-kms-no-rotation.aws-kms-no-rotation + - id: rules_lgpl_javascript_ssrf_rule-phantom-ssrf languages: - - hcl - message: The AWS KMS has no rotation. Missing rotation can cause leaked key to be used by attackers. To fix this, set a `enable_key_rotation`. + - javascript + message: | + 'If unverified user data can reach the `phantom` methods it can result in Server-Side Request Forgery vulnerabilities. + + ' metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-918 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Server-side request forgery (SSRF) patterns: + - pattern-inside: | + require('phantom') + ... + - pattern-either: + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - pattern-either: + - pattern: $PAGE.open(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.setContent(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.open(<... $REQ.$BODY ...>,...) + - pattern: $PAGE.setContent(<... $REQ.$BODY ...>,...) + - pattern: $PAGE.openUrl(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.openUrl(<... $REQ.$BODY ...>,...) + - pattern: $PAGE.evaluateJavaScript(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.evaluateJavaScript(<... $REQ.$BODY ...>,...) + - pattern: $PAGE.property("content",<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.property("content",<... $REQ.$BODY ...>,...) - pattern: | - resource "aws_kms_key" $ANYTHING { - ... - enable_key_rotation = false - ... - } + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.open(<... $INPUT ...>,...) - pattern: | - resource "aws_kms_key" $ANYTHING { - ... - customer_master_key_spec = "SYMMETRIC_DEFAULT" - enable_key_rotation = false - ... - } + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.open(<... $INPUT ...>,...) - pattern: | - resource "aws_kms_key" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_kms_key" $ANYTHING { - ... - enable_key_rotation = true - ... - } - - pattern-not-inside: | - resource "aws_kms_key" $ANYTHING { - ... - customer_master_key_spec = "RSA_2096" - ... - } - severity: WARNING - - id: terraform.aws.security.aws-lambda-environment-credentials.aws-lambda-environment-credentials + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.setContent(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.setContent(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.openUrl(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.openUrl(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluateJavaScript(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluateJavaScript(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.property("content",<... $INPUT ...>,...) + - pattern: |- + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.property("content",<... $INPUT ...>,...) + severity: ERROR + - id: rules_lgpl_javascript_ssrf_rule-playwright-ssrf languages: - - hcl - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + message: | + If unverified user data can reach the `puppeteer` methods it can result in Server-Side Request Forgery vulnerabilities. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: HIGH - likelihood: LOW + cwe: CWE-918 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - subcategory: - - vuln - technology: - - aws - - terraform - - secrets + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Server-side request forgery (SSRF) patterns: - pattern-inside: | - resource "$ANYTING" $ANYTHING { - ... - environment { - variables = { - ... - } - } - ... - } + require('playwright') + ... - pattern-either: - - pattern-inside: | - AWS_ACCESS_KEY_ID = "$Y" - - pattern-regex: | - (?, ...) + - pattern: $PAGE.goto(<... $REQ.$BODY ...>, ...) + - pattern: $PAGE.setContent(<... $REQ.$QUERY.$FOO ...>, ...) + - pattern: $PAGE.setContent(<... $REQ.$BODY ...>, ...) + - pattern: $PAGE.evaluate(<... $REQ.$QUERY.$FOO ...>, ...) + - pattern: $PAGE.evaluate(<... $REQ.$BODY ...>, ...) + - pattern: $PAGE.evaluate($CODE,..., <... $REQ.$QUERY.$FOO ...>, ...) + - pattern: $PAGE.evaluate($CODE,..., <... $REQ.$BODY ...>, ...) + - pattern: $PAGE.evaluateHandle(<... $REQ.$QUERY.$FOO ...>, ...) + - pattern: $PAGE.evaluateHandle(<... $REQ.$BODY ...>, ...) + - pattern: $PAGE.evaluateHandle($CODE,..., <... $REQ.$QUERY.$FOO ...>, ...) + - pattern: $PAGE.evaluateHandle($CODE,..., <... $REQ.$BODY ...>, ...) + - pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY ...>, ...) + - pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY.$FOO ...>, ...) + - pattern: $CONTEXT.addInitScript(<... $REQ.$BODY ...>,...) + - pattern: $CONTEXT.addInitScript(<... $REQ.$BODY.$FOO ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; ... - mode = "Active" + $PAGE.goto(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; ... - } - ... - } - severity: INFO - - id: terraform.aws.security.aws-provider-static-credentials.aws-provider-static-credentials + $PAGE.goto(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.setContent(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.setContent(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluate($CODE,..., <... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluate($CODE,..., <... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluate(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluate(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluateHandle(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluateHandle(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluateHandle($CODE,..., <... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluateHandle($CODE,..., <... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluateOnNewDocument(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluateOnNewDocument(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $CONTEXT.addInitScript($INPUT,...) + severity: ERROR + - id: rules_lgpl_javascript_ssrf_rule-puppeteer-ssrf languages: - - hcl - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + message: | + If unverified user data can reach the `puppeteer` methods it can result in Server-Side Request Forgery vulnerabilities. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-918 owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - subcategory: - - vuln - technology: - - secrets - - aws - - terraform + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Server-side request forgery (SSRF) patterns: - pattern-inside: | - provider "aws" { + require('puppeteer') ... - secret_key = "$SECRET" - } - - focus-metavariable: $SECRET - severity: WARNING - - id: terraform.aws.security.aws-rds-backup-no-retention.aws-rds-backup-no-retention - languages: - - hcl - message: The AWS RDS has no retention. Missing retention can cause losing important event information. To fix this, set a `backup_retention_period`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - pattern-either: + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: $PAGE.goto(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.goto(<... $REQ.$BODY ...>,...) + - pattern: $PAGE.setContent(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.setContent(<... $REQ.$BODY ...>,...) + - pattern: $PAGE.evaluate(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.evaluate(<... $REQ.$BODY ...>,...) + - pattern: $PAGE.evaluateHandle(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.evaluateHandle(<... $REQ.$BODY ...>,...) + - pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY ...>,...) + - pattern: $PAGE.evaluate($CODE,<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.evaluate($CODE,<... $REQ.$BODY ...>,...) + - pattern: $PAGE.evaluateHandle($CODE,<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.evaluateHandle($CODE,<... $REQ.$BODY ...>,...) + - pattern: $PAGE.evaluateOnNewDocument($CODE,<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PAGE.evaluateOnNewDocument($CODE,<... $REQ.$BODY ...>,...) - pattern: | - resource "aws_rds_cluster" $ANYTHING { - ... - backup_retention_period = 0 - ... - } + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.goto(<... $INPUT ...>,...) - pattern: | - resource "aws_db_instance" $ANYTHING { - ... - backup_retention_period = 0 - ... - } - severity: WARNING - - id: terraform.aws.security.aws-sqs-queue-policy-wildcard-principal.aws-sqs-queue-policy-wildcard-principal + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.goto(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.setContent(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.setContent(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluate(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluate(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluateHandle(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluateHandle(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluateOnNewDocument(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluateOnNewDocument(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluate($CODE,<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluate($CODE,<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluateHandle($CODE,<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluateHandle($CODE,<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PAGE.evaluateOnNewDocument($CODE,<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PAGE.evaluateOnNewDocument($CODE,<... $INPUT ...>,...) + severity: ERROR + - id: rules_lgpl_javascript_ssrf_rule-wkhtmltoimage-ssrf languages: - - hcl - message: Wildcard used in your SQS queue policy principal. This grants access to all users, including anonymous users (public access). Unless you explicitly require anyone on the internet to be able to read or write to your queue, limit principals, actions and resources to what you need according to least privilege. + - javascript + message: "This rule detects instances where user-controlled URLs are passed directly\nto the `generate` function of `wkhtmltoimage` library. This practice can\nlead to Server Side Request Forgery (SSRF) vulnerabilities, where an\nattacker can induce the server to make requests to arbitrary URLs. This\ncan potentially expose internal services within the network or lead to\ninformation disclosure.\n\nTo mitigate this vulnerability, ensure that URLs are safe and intended for \npublic access. Implementing allowlists for acceptable domains or schemes can \nsignificantly reduce the risk of SSRF. Additionally, consider using server-side \nproxy services that restrict the outgoing requests to trusted domains and \nresources.\n\nSecure Code Example:\n```\nconst wkhtmltoimage = require('wkhtmltoimage');\n\n// Define an allowlist of domains\nconst allowedDomains = ['example.com', 'trusted-source.com'];\n\napp.post('/generate-image', (req, res) => {\n const userInputUrl = req.body.url; \n const parsedUrl = new URL(userInputUrl);\n\n // Check if the domain is in the allowlist\n if (allowedDomains.includes(parsedUrl.hostname)) {\n wkhtmltoimage.generate(userInputUrl, { output: 'output.jpg' }, \n function (err, stream) {\n if (err) {\n return res.status(500).send('Error generating image');\n }\n // Send a success response or the image itself\n res.status(200).send('Image generated successfully');\n });\n } else {\n res.status(400).send('URL is not allowed due to security policies.');\n }\n});\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-918 owasp: - - A05:2021 - Security Misconfiguration - references: - - https://cwe.mitre.org/data/definitions/732.html - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_policy - - https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-security-best-practices.html - rule-origin-note: published from /src/aws-sqs-queue-policy-wildcard-principal.yml in None - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern-either: + - A1:2017-Injection + - A10:2021-Server-Side Request Forgery + security-severity: MEDIUM + shortDescription: Server-side request forgery (SSRF) + mode: taint + pattern-sanitizers: + - patterns: - pattern-inside: | - resource "aws_sqs_queue_policy" $ANYTHING { + if($ALLOWED.includes($URL)){ ... } - - pattern-inside: | - resource "aws_sqs_queue" $ANYTHING { + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $W = require('wkhtmltoimage') + ... + - pattern-inside: | + import $W from 'wkhtmltoimage' + ... + - pattern: | + $W.generate(...) + pattern-sources: + - patterns: + - pattern: | + function($REQ, $RES, ...){ ... } - - pattern-either: - - patterns: - - pattern: policy = "$JSONPOLICY" - - metavariable-pattern: - language: json - metavariable: $JSONPOLICY - patterns: - - pattern-not-inside: | - {..., "Effect": "Deny", ...} - - pattern-either: - - pattern: | - {..., "Principal": "*", ...} - - pattern: | - {..., "Principal": [..., "*", ...], ...} - - pattern: | - {..., "Principal": { "AWS": "*" }, ...} - - pattern: | - {..., "Principal": { "AWS": [..., "*", ...] }, ...} - - patterns: - - pattern-inside: policy = jsonencode(...) - - pattern-not-inside: | - {..., Effect = "Deny", ...} - - pattern-either: - - pattern: | - {..., Principal = "*", ...} - - pattern: | - {..., Principal = [..., "*", ...], ...} - - pattern: | - {..., Principal = { AWS = "*" }, ...} - - pattern: | - {..., Principal = { AWS = [..., "*", ...] }, ...} - severity: ERROR - - id: terraform.aws.security.aws-subnet-has-public-ip-address.aws-subnet-has-public-ip-address + - focus-metavariable: $REQ + severity: WARNING + - id: rules_lgpl_javascript_ssrf_rule-wkhtmltopdf-ssrf languages: - - hcl - message: Resources in the AWS subnet are assigned a public IP address. Resources should not be exposed on the public internet, but should have access limited to consumers required for the function of your application. Set `map_public_ip_on_launch` to false so that resources are not publicly-accessible. + - javascript + message: | + User controlled URL reached to `wkhtmltopdf` can result in Server Side Request Forgery (SSRF). metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-284: Improper Access Control' - impact: MEDIUM - likelihood: LOW + cwe: CWE-918 owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet#map_public_ip_on_launch - - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-public-addresses - subcategory: - - audit - technology: - - terraform - - aws + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Server-side request forgery (SSRF) patterns: + - pattern-inside: | + require('wkhtmltopdf') + ... + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - pattern-either: - pattern: | - resource "aws_subnet" $ANYTHING { - ... - map_public_ip_on_launch = true - ... - } + $INP = <... $REQ.$VAR ...>; + ... + wkhtmltopdf(<... $INP ...>, ...) - pattern: | - resource "aws_default_subnet" $ANYTHING { - ... - } - - pattern-not: | - resource "aws_default_subnet" $ANYTHING { - ... - map_public_ip_on_launch = false - ... - } - severity: WARNING - - id: terraform.aws.security.insecure-load-balancer-tls-version.insecure-load-balancer-tls-version + $INP = <... $REQ.$VAR.$FOO ...>; + ... + wkhtmltopdf(<... $INP ...>, ...) + - pattern: | + wkhtmltopdf(<... $REQ.$VAR ...>, ...) + - pattern: | + wkhtmltopdf(<... $REQ.$VAR.$FOO ...>, ...) + severity: ERROR + - id: rules_lgpl_javascript_traversal_rule-admzip-path-overwrite languages: - - hcl - message: Detected an AWS load balancer with an insecure TLS version. TLS versions less than 1.2 are considered insecure because they can be broken. To fix this, set your `ssl_policy` to `"ELBSecurityPolicy-TLS13-1-2-2021-06"`, or include a default action to redirect to HTTPS. + - javascript + message: | + Insecure ZIP archive extraction using adm-zip can result in arbitrary path over write and can result in code injection. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-22 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.ietf.org/rfc/rfc5246.txt - subcategory: - - vuln - technology: - - terraform - - aws + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') patterns: - - pattern-either: - - patterns: - - pattern: ssl_policy = $ANYTHING - - pattern-not-regex: ELBSecurityPolicy-TLS13-1-[23]-[0-9-]+ - - pattern-not-regex: ELBSecurityPolicy-FS-1-2-[(Res)0-9-]+ - - patterns: - - pattern: protocol = "HTTP" - - pattern-not-inside: | - resource $ANYTHING $NAME { - ... - default_action { - ... - redirect { - ... - protocol = "HTTPS" - ... - } - ... - } - ... - } - pattern-inside: | - resource $RESOURCE $X { - ... - } - - metavariable-pattern: - metavariable: $RESOURCE - patterns: - - pattern-either: - - pattern: | - "aws_lb_listener" - - pattern: | - "aws_alb_listener" + $X = require('adm-zip') + ... + - pattern-not: | + if ($FILENAME.indexOf('..')) + - pattern-not: | + $FS.createWriteStream($PATH.join(..., $PATH.basename($FILENAME, ...))) + - pattern-not: | + $FS.writeFile($PATH.join(..., $PATH.basename($FILENAME, ...))) + - pattern-not: | + $FS.writeFileSync($PATH.join(..., $PATH.basename($FILENAME, ...))) + - pattern-either: + - pattern: $ZIPENTZ.forEach(function $FUNC($ENTRY, ...) { $FS.createWriteStream(...) }, ...) + - pattern: $ZIPENTZ.forEach(function $FUNC($ENTRY, ...) { $FS.writeFile(...) }, ...) + - pattern: $ZIPENTZ.forEach(function $FUNC($ENTRY, ...) { $FS.writeFileSync(...) }, ...) severity: WARNING - - id: terraform.aws.security.unrestricted-github-oidc-policy.unrestricted-github-oidc-policy + - id: rules_lgpl_javascript_traversal_rule-express-lfr languages: - - hcl - match: - all: - - inside: | - data "aws_iam_policy_document" $POLICY { - ... - } - - | - statement { - ... - principals { - ... - type = "Federated" - identifiers = [..., $IDENTIFIER, ...] - } - } - - not: | - statement { - ... - condition { - ... - variable = "token.actions.githubusercontent.com:sub" - } - } - where: - - metavariable: $IDENTIFIER - regex: .*oidc-provider/token\.actions\.githubusercontent\.com - message: '`$POLICY` is missing a `condition` block which scopes users of this policy to specific GitHub repositories. Without this, `$POLICY` is open to all users on GitHub. Add a `condition` block on the variable `token.actions.githubusercontent.com:sub` which scopes it to prevent this.' + - javascript + message: "This application is using untrusted user input in express render() function.\nRendering templates with untrusted user input enables arbitrary file read \nvulnerabilities when using templating engines like Handlebars (hbs). \n\nAn attacker can craft malicious input that traverses the filesystem and exposes sensitive files. \nConsider sanitizing and validating all user input before passing it to render() to prevent arbitrary file reads. \n\nSample safe use of express.render function\n```\napp.get(\"/traversal/2\", async (req, res) => {\n var indexPath = \"index\";\n res.render(indexPath, { title: \"Index Page\" })\n});\n```\n\nFor more details see: \nhttps://owasp.org/www-community/attacks/Path_Traversal\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-284: Improper Access Control' - impact: HIGH - likelihood: MEDIUM + cwe: CWE-23 owasp: - - A05:2017 - Sensitive Data Exposure - - A01:2021 - Broken Access Control - references: - - https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services#configuring-the-role-and-trust-policy - - https://dagrz.com/writing/aws-security/hacking-github-aws-oidc/ - subcategory: - - audit - technology: - - terraform - - aws + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Relative path traversal + mode: taint + pattern-sinks: + - pattern: $RES.render(..., $VAR) + pattern-sources: + - patterns: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern: $REQ.$FUNC. ... + - metavariable-regex: + metavariable: $FUNC + regex: ^(body|params|query|cookies|hostname|subdomains|ip|ips|originalUrl|path)$ severity: WARNING - - id: terraform.aws.security.wildcard-assume-role.wildcard-assume-role + - id: rules_lgpl_javascript_traversal_rule-express-lfr-warning languages: - - hcl - message: 'Detected wildcard access granted to sts:AssumeRole. This means anyone with your AWS account ID and the name of the role can assume the role. Instead, limit to a specific identity in your account, like this: `arn:aws:iam:::root`.' + - javascript + message: | + Untrusted user input in express render() function can result in arbitrary file read if hbs templating is used. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-23 owasp: - - A06:2017 - Security Misconfiguration - - A05:2021 - Security Misconfiguration - references: - - https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/ - subcategory: - - vuln - technology: - - aws + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Relative path traversal patterns: + - pattern-not-inside: | + require('hbs') + ... - pattern-inside: | - resource "aws_iam_role" $NAME { - ... - } - - pattern: assume_role_policy = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: + require('express') + ... + - pattern-either: + - pattern: | + $INP = <... $REQ.$QUERY ...>; + ... + $RES.render($VIEW, <... $INP ...>) + - pattern: | + $INP = <... $REQ.$QUERY.$FOO ...>; + ... + $RES.render($VIEW, <... $INP ...>) + - pattern: $RES.render($VIEW, <... $REQ.$QUERY.$FOO ...>) + - pattern: $RES.render($VIEW, <... $REQ.$BODY ...>) + severity: WARNING + - id: rules_lgpl_javascript_traversal_rule-generic-path-traversal + languages: + - javascript + message: "This application is using untrusted user input with the readFile() and\nreadFileSync() functions. \nThis can lead to directory traversal attacks, as reading files with untrusted input enables arbitrary file access.\nAn attacker could craft malicious input that traverses the file system and exposes sensitive files. \nPlease consider sanitizing and validating all user input before passing it to readFile() or readFileSync() to prevent unwanted file reads.\nHere is an example of a safer usage in readFileAsync():\n```\napp.get('/foo', function (req, res) {\n var fileName = config.dirName + '/' + data;\n fs.readFileAsync(\"fileName\")\n .then(function (data) {\n res.download(fileName, downloadFileName);\n })\n })\n```\nFor more details see: \nhttps://owasp.org/www-community/attacks/Path_Traversal\n" + metadata: + category: security + cwe: CWE-23 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Relative path traversal + mode: taint + pattern-sinks: + - patterns: + - pattern-either: - pattern-inside: | - {..., "Effect": "Allow", ..., "Action": "sts:AssumeRole", ...} - - pattern: | - "Principal": {..., "AWS": "*", ...} - severity: ERROR - - id: terraform.azure.security.appservice.appservice-authentication-enabled.appservice-authentication-enabled + $FS = require('fs') + ... + - pattern-inside: | + import $FS from 'fs' + ... + - pattern-either: + - pattern: $FS.createReadStream(...) + - patterns: + - pattern: $FS.readFile($REQ, ...) + - focus-metavariable: $REQ + - patterns: + - pattern: $FS.readFileSync($REQ,...) + - focus-metavariable: $REQ + - patterns: + - pattern: $FS.readFileAsync($REQ,...) + - focus-metavariable: $REQ + pattern-sources: + - patterns: + - focus-metavariable: $REQ + - pattern: function ($REQ, $RES, ...) {...} + severity: WARNING + - id: rules_lgpl_javascript_traversal_rule-join-resolve-path-traversal languages: - - hcl - message: Enabling authentication ensures that all communications in the application are authenticated. The `auth_settings` block needs to be filled out with the appropriate auth backend settings + - javascript + message: | + 'Path constructed with user input can result in Path Traversal. Ensure that user input does not reach `join()` or `resolve()`. ' metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-287: Improper Authentication' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-22 owasp: - - A02:2017 - Broken Authentication - - A07:2021 - Identification and Authentication Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#auth_settings - subcategory: - - vuln - technology: - - terraform - - azure + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { + - pattern-inside: | + require('path') ... - auth_settings { + - pattern-either: + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: $PATH.join(...,<... $REQ.$BODY ...>,...) + - pattern: $PATH.join(...,<... $REQ.$QUERY.$FOO ...>,...) + - pattern: | + $VAR = <... $REQ.$BODY ...>; ... - enabled = true + $PATH.join(...,<... $VAR ...>,...) + - pattern: | + $VAR = <... $REQ.$QUERY.$FOO ...>; ... - } + $PATH.join(...,<... $VAR ...>,...) + - pattern: $PATH.resolve(...,<... $REQ.$BODY ...>,...) + - pattern: $PATH.resolve(...,<... $REQ.$QUERY.$FOO ...>,...) + - pattern: | + $VAR = <... $REQ.$BODY ...>; + ... + $PATH.resolve(...,<... $VAR ...>,...) + - pattern: |- + $VAR = <... $REQ.$QUERY.$FOO ...>; + ... + $PATH.resolve(...,<... $VAR ...>,...) + severity: WARNING + - id: rules_lgpl_javascript_traversal_rule-tar-path-overwrite + languages: + - javascript + message: | + Insecure TAR archive extraction can result in arbitrary path over write and can result in code injection. + metadata: + category: security + cwe: CWE-22 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + patterns: + - pattern-inside: | + $X = require('tar-stream') ... - } + - pattern-not-inside: | + $Y.pipe($UNZIP.Parse(...)).on('entry', function $FUNC(...) { + ... + }, ...) + - pattern-inside: | + $EXTRACT.on('entry', function $FUNC(...) { + ... + }, ...) + - pattern-not: | + if ($FILENAME.indexOf('..')) + - pattern-not: | + $FS.createWriteStream($PATH.join(..., $PATH.basename($FILENAME, ...))) + - pattern-not: | + $FS.writeFile($PATH.join(..., $PATH.basename($FILENAME, ...))) + - pattern-not: | + $FS.writeFileSync($PATH.join(..., $PATH.basename($FILENAME, ...))) + - pattern-either: + - pattern: | + $FS.createWriteStream($FIL, ...) + - pattern: | + $FS.writeFile($FIL, ...) + - pattern: | + $FS.writeFileSync($FIL, ...) + severity: WARNING + - id: rules_lgpl_javascript_traversal_rule-zip-path-overwrite + languages: + - javascript + message: "This application is extracting ZIP archives without sanitizing paths or writing files to a dedicated extraction directory. \nThis allows attackers to overwrite sensitive files or inject malicious code by manipulating TAR archive contents.\n\nTo fix, sanitize all paths from ZIP archives before writing extracted files using path.basename and path.join.\n\nExample of extracting tar files safely:\n```\napp.get(\"/extract\", async (req, res) => {\n fs.createReadStream(zipPath)\n .pipe(unzipper.Parse())\n .on('entry', entry => {\n const directory = 'assets/tar/extracted/';\n const filename = entry.path;\n entry.pipe(fs.createWriteStream(path.join(directory, filename)));\n });\n});\n```\n\nWrite extracted files only to a dedicated extraction directory, not the global filesystem. Limit extracts to allowed file type.\n\nSee OWASP Path Traversal (https://owasp.org/www-community/attacks/Path_Traversal) and Unrestricted Upload of File with \nDangerous Type (https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload) for more details.\n" + metadata: + category: security + cwe: CWE-22 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + patterns: - pattern-either: - pattern-inside: | - resource "azurerm_app_service" "..." { + import $X from 'unzipper' ... - } - pattern-inside: | - resource "azurerm_app_service" "..." { + $X = require('unzipper') ... - auth_settings { - ... - enabled = false - ... - } + - pattern-inside: | + $Y.pipe($X.Parse(...)).on('entry', function $FUNC(...) { ... - } - severity: ERROR - - id: terraform.azure.security.appservice.appservice-enable-http2.appservice-enable-http2 + }, ...) + - pattern-not-inside: "if (<... $FILENAME.indexOf(...) ...>){ \n...\n}\n" + - pattern-not-inside: | + $BASE = $PATH.basename($FILENAME, ...) + ... + $JOIN = $PATH.join(..., $BASE) + ... + - pattern-not: | + $FS.$MTD($PATH.join(..., $PATH.basename($FILENAME, ...))) + - pattern: | + $FS.$MTD($FIL, ...) + - metavariable-regex: + metavariable: $MTD + regex: ^(writeFileSync|writeFile|createWriteStream)$ + severity: WARNING + - id: rules_lgpl_javascript_xml_rule-node-entity-expansion languages: - - hcl - message: Use the latest version of HTTP to ensure you are benefiting from security fixes. Add `http2_enabled = true` to your appservice resource block + - javascript + message: | + User controlled data in XML Parsers can result in XML Internal Entity Processing vulnerabilities like in DoS. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-444: Inconsistent Interpretation of HTTP Requests (''HTTP Request/Response Smuggling'')' - impact: MEDIUM - likelihood: LOW + cwe: CWE-776 owasp: - - A04:2021 - Insecure Design - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#http2_enabled - subcategory: - - vuln - technology: - - terraform - - azure + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration + security-severity: CRITICAL + shortDescription: Improper restriction of recursive entity references in DTDs (XML Entity Expansion) patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - site_config { - ... - http2_enabled = true - ... - } - ... - } - pattern-either: - - pattern-inside: | - resource "azurerm_app_service" "..." { + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $PARSER = new expat.Parser() ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { + $PARSER.write(..., <... $REQ.$QUERY ...>, ...) + - pattern: | + $PARSER = new expat.Parser() ... - site_config { + $PARSER.write(..., <... $REQ.$QUERY.$FOO ...>, ...) + - pattern: | + $PARSER = new expat.Parser() + ... + $PARSER.write(..., <... $REQ.$QUERY.$FOO.$FILE ...>, ...) + severity: ERROR + - id: rules_lgpl_javascript_xml_rule-node-xpath-injection + languages: + - javascript + message: "Passing untrusted user input in `xpath.parse()` can result in XPATH injection\nvulnerability. This could be abused by malicious actors to execute expressions on\non XML files to capture unauthorized information.\nTo prevent XPATH injection vulnerabilities:\n\n- Always validate and sanitize user inputs, especially parameters\nor query strings that may influence the flow of the application.\n- Avoid directly using user input for parsing. If unavoidable, ensure\nstrict validation against an allowlist. \n- Use allowlists (lists of permitted expressions) to validate user input \nagainst known, trusted expressions before performing the parse.\n\n\nFollowing is an example of secure validation against allowlist to prevent the vulnerability:\n```\n// Define a list of explicitly allowed expressions for parsing\nconst allowedExpr = [\n 'expression1',\n 'expression2',\n 'expression3'\n];\n\napp.get('/xml/xpath/1', (req, res) => {\n var expression = req.params.exp;\n var isAllowed = allowedExpr.includes(expression);\n let xml_string = fs.readFileSync(\"books.xml\", \"utf8\");\n var doc = new dom().parseFromString(xml_string, 'text/xml');\n if (isAllowed) {\n // If the expression is allowed, proceed with the parsing\n var evaluator = xpath.parse(\"//\"+expression);\n var nodes = evaluator.select({ node: doc }); \n res.send(nodes[0].firstChild.data);\n } else {\n res.status(400).send('Invalid expression');\n }\n});\n```\n" + metadata: + category: security + cwe: CWE-643 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of data within XPath expressions (XPath Injection) + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: "if($VALIDATION){\n...\n$XPATH.parse($REQ, ...) \n...\n} \n" + - pattern: "$A = $VALIDATION\n...\nif($A){\n...\n$XPATH.parse($REQ, ...) \n...\n}\n" + - metavariable-pattern: + metavariable: $VALIDATION + pattern-either: + - pattern: "$AL.includes(...) \n" + - pattern: | + $AL.indexOf(...) !== -1 + - pattern: | + $AL.find(...) !== undefined + - pattern: | + $ALS.has(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $XPATH = require('xpath') ... - http2_enabled = false + - pattern-inside: | + import { $XPATH } from 'xpath' ... - } - ... - } - severity: INFO - - id: terraform.azure.security.appservice.appservice-enable-https-only.appservice-enable-https-only + - pattern-inside: | + import { $K as $XPATH } from 'xpath' + ... + - pattern: "$XPATH.parse($REQ, ...) \n" + - focus-metavariable: $REQ + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + function ($REQ, $RES, ...) {...} + - pattern: | + function $FUNC($REQ, $RES, ...) {...} + - focus-metavariable: $REQ + severity: ERROR + - id: rules_lgpl_javascript_xml_rule-node-xxe languages: - - hcl - message: By default, clients can connect to App Service by using both HTTP or HTTPS. HTTP should be disabled enabling the HTTPS Only setting. + - javascript + message: | + User controlled data in XML parsers can result in XML External or Internal Entity (XXE) Processing vulnerabilities metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-611 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#https_only - - https://docs.microsoft.com/en-us/azure/app-service/configure-ssl-bindings#enforce-https - subcategory: - - vuln - technology: - - terraform - - azure + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration + security-severity: CRITICAL + shortDescription: Improper restriction of XML external entity reference patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - https_only = true - ... - } - pattern-either: - - pattern-inside: | - resource "azurerm_app_service" "..." { + - pattern-inside: function ($REQ, $RES, ...) {...} + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + - pattern-either: + - pattern: | + $LIBXML.parseXmlString(..., <... $REQ.$QUERY.$VAR.$FILE ...>, ...) + - pattern: | + $LIBXML.parseXmlString(..., <... $REQ.$QUERY.$VAR ...>, ...) + - pattern: | + $LIBXML.parseXmlString(..., <... $REQ.$QUERY ...>, ...) + - pattern: | + $FOO = <... $REQ.$QUERY.$VAR.$FILE ...>; ... $LIBXML.parseXmlString(..., <... $FOO ...>, ...) + - pattern: | + $FOO = <... $REQ.$QUERY.$VAR ...>; ... $LIBXML.parseXmlString(..., <... $FOO ...>, ...) + - pattern: | + $FOO = <... $REQ.$QUERY ...>; ... $LIBXML.parseXmlString(..., <... $FOO ...>, ...) + - pattern: | + $LIBXML.parseXml(..., <... $REQ.$QUERY.$VAR.$FILE ...>, ...) + - pattern: | + $LIBXML.parseXml(..., <... $REQ.$QUERY.$VAR ...>, ...) + - pattern: | + $LIBXML.parseXml(..., <... $REQ.$QUERY ...>, ...) + - pattern: | + $FOO = <... $REQ.$QUERY.$VAR.$FILE ...>; ... $LIBXML.parseXml(..., <... $FOO ...>, ...) + - pattern: | + $FOO = <... $REQ.$QUERY.$VAR ...>; ... $LIBXML.parseXml(..., <... $FOO ...>, ...) + - pattern: | + $FOO = <... $REQ.$QUERY ...>; ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { + $LIBXML.parseXml(..., <... $FOO ...>, ...) + - pattern: | + $PARSER = new libxmljs.SaxParser() ... - https_only = false + $PARSER.parseString(..., <... $REQ.$QUERY ...>, ...) + - pattern: | + $PARSER = new libxmljs.SaxParser() ... - } + $PARSER.parseString(..., <... $REQ.$QUERY.$BAR ...>, ...) + - pattern: | + $PARSER = new libxmljs.SaxParser() + ... + $PARSER.parseString(..., <... $REQ.$QUERY.$BAR.$FILE ...>, ...) + - pattern: | + $PARSER = new libxmljs.SaxPushParser() + ... + $PARSER.push(..., <... $REQ.$QUERY ...>, ...) + - pattern: | + $PARSER = new libxmljs.SaxPushParser() + ... + $PARSER.push(..., <... $REQ.$QUERY.$FOO ...> , ...) + - pattern: | + $PARSER = new libxmljs.SaxPushParser() + ... + $PARSER.push(..., <... $REQ.$QUERY.$FOO.$FILE ...> , ...) + - pattern: | + $PARSER = new libxmljs.SaxParser() + ... + $FOO = <... $REQ.$QUERY ...>; + ... + $PARSER.parseString(..., <... $FOO ...>, ...) + - pattern: | + $PARSER = new libxmljs.SaxParser() + ... + $FOO = <... $REQ.$QUERY.$BAR ...>; + ... + $PARSER.parseString(..., <... $FOO ...>, ...) + - pattern: | + $PARSER = new libxmljs.SaxParser() + ... + $FOO = <... $REQ.$QUERY.$BAR.$FILE ...>; + ... + $PARSER.parseString(..., <... $FOO ...>, ...) + - pattern: | + $PARSER = new libxmljs.SaxPushParser() + ... + $FOO = <... $REQ.$QUERY ...>; + ... + $PARSER.push(..., <... $FOO ...>, ...) + - pattern: | + $PARSER = new libxmljs.SaxPushParser() + ... + $FOO = <... $REQ.$QUERY.$BAR ...>; + ... + $PARSER.push(..., <... $FOO ...> , ...) + - pattern: | + $PARSER = new libxmljs.SaxPushParser() + ... + $FOO = <... $REQ.$QUERY.$BAR.$FILE ...>; + ... + $PARSER.push(..., <... $FOO ...> , ...) severity: ERROR - - id: terraform.azure.security.appservice.appservice-require-client-cert.appservice-require-client-cert + - id: rules_lgpl_javascript_xml_rule-xxe-expat languages: - - hcl - message: Detected an AppService that was not configured to use a client certificate. Add `client_cert_enabled = true` in your resource block. + - javascript + message: | + Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-611 owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#client_cert_enabled - subcategory: - - vuln - technology: - - terraform - - azure + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration + security-severity: CRITICAL + shortDescription: Improper restriction of XML external entity reference patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - client_cert_enabled = true + - pattern-inside: | + require('node-expat') ... - } + - pattern-either: + - pattern-inside: function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} + - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - pattern-either: - pattern-inside: | - resource "azurerm_app_service" "..." { + $PARSER = new $EXPAT.Parser(...) ... - } - pattern-inside: | - resource "azurerm_app_service" "..." { + $PARSER = new Parser(...) ... - client_cert_enabled = false + - pattern-either: + - pattern: $PARSER.parse(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PARSER.parse(<... $REQ.$BODY ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; ... - } - severity: INFO - - id: terraform.azure.security.appservice.appservice-use-secure-tls-policy.appservice-use-secure-tls-policy + $PARSER.parse(<... $INPUT ...>,...) + - pattern: | + $INPUT = <... $REQ.$BODY ...>; + ... + $PARSER.parse(<... $INPUT ...>,...) + - pattern: $PARSER.write(<... $REQ.$QUERY.$FOO ...>,...) + - pattern: $PARSER.write(<... $REQ.$BODY ...>,...) + - pattern: | + $INPUT = <... $REQ.$QUERY.$FOO ...>; + ... + $PARSER.write(<... $INPUT ...>,...) + - pattern: |- + $INPUT = <... $REQ.$BODY ...>; + ... + $PARSER.write(<... $INPUT ...>,...) + severity: ERROR + - id: rules_lgpl_javascript_xss_rule-express-xss languages: - - hcl - message: Detected an AppService that was not configured to use TLS 1.2. Add `site_config.min_tls_version = "1.2"` in your resource block. + - javascript + message: "This application accepts user input directly from the client side without validation. \nThis could lead to Cross Site Scripting (XSS) if the input contains malicious script code and \nthe application server does not properly escape or sanitize the output. \nConsider encoding input data before sending it to the client side. \n\n```\n// safe method of sending user input data\nrouter.get('/safe/1', (req, res) => {\n var name = encodeURI(req.query.name); \n res.send(name);\n})\n```\n\nXSS is an attack that exploits a web application or system to treat user input as markup or script code. \nIt is important to encode the data depending on the specific context in which it is used. \n" metadata: category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-79 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#min_tls_version - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: min_tls_version = $ANYTHING - - pattern-inside: | - resource "azurerm_app_service" "$NAME" { - ... - } - - pattern-not-inside: min_tls_version = "1.2" - severity: ERROR - - id: terraform.azure.security.appservice.azure-appservice-detailed-errormessages-enabled.azure-appservice-detailed-errormessages-enabled + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + mode: taint + options: + taint_unify_mvars: true + pattern-propagators: + - from: $IN + pattern: $ARR.push($IN) + to: $ARR + pattern-sanitizers: + - pattern: encodeURI(...) + - pattern: encodeURIComponent(...) + pattern-sinks: + - patterns: + - focus-metavariable: $INPUT + - pattern-either: + - pattern: $RES. ... .send($INPUT) + - pattern: $RES. ... .write($INPUT) + pattern-sources: + - patterns: + - patterns: + - metavariable-regex: + metavariable: $LIB + regex: (?Handlebars safe string\" + Handlebars.escapeExpression(req.query.message))\n res.send(returnObj.string)\n```\n" + metadata: + category: security + cwe: CWE-79 + owasp: + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation (Cross-site Scripting) + mode: taint + pattern-sanitizers: + - pattern-either: + - patterns: + - pattern-inside: | + $HB = require('handlebars') + ... + - pattern: $HB.escapeExpression(...) + - patterns: + - pattern-inside: | + import $HB from "handlebars"; + ... + - pattern: $HB.escapeExpression(...) + pattern-sinks: + - pattern-either: + - patterns: + - pattern-inside: | + $HB = require('handlebars') + ... + - pattern: new $HB.SafeString(...) + - patterns: + - pattern-inside: | + import $HB from "handlebars"; + ... + - pattern: new $HB.SafeString(...) + pattern-sources: + - patterns: + - focus-metavariable: $REQ + - pattern: function ($REQ, $RES, ...) {...} + severity: WARNING + - id: rules_lgpl_javascript_xss_rule-squirrelly-autoescape languages: - - hcl - message: Ensure that App service enables detailed error messages + - javascript + message: "This application is rendering HTML with vulnerable \nconfigurations by setting Sqrl.autoEscaping(false) in squirrelly.\n\nThis could lead to Cross Site Scripting (XSS) if the input is malicious \nscript code and the application server is not properly validating the output.\n\n```\n// safe use of squirrelly render\nvar myTemplate = \"

    My Message is: {{message}}

    \"\nSqrl.Render(myTemplate, {message: req.query.message})\n```\n\nXSS is an attack that exploits a web application or system to treat user input as markup or script code. \nIt is important to encode the data depending on the specific context it is used in.\n\nBy default, squirrelly autoEscaping(true) escapes input values to prevent XSS attacks. \nConsider using squirrelly with default autoEscaping settings.\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-778: Insufficient Logging' - impact: LOW - likelihood: LOW + cwe: CWE-79 owasp: - - A10:2017 - Insufficient Logging & Monitoring - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - logs { - ... - detailed_error_messages_enabled = true - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + pattern-either: + - patterns: + - pattern-inside: | + $SQLY = require('squirrelly') + ... + - pattern: $SQLY.autoEscaping(false) + - patterns: + - pattern-inside: | + import $SQLY from 'squirrelly'; + ... + - pattern: $SQLY.autoEscaping(false) severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-https-only.azure-appservice-https-only + - id: rules_lgpl_javascript_xss_rule-xss-disable-mustache-escape languages: - - hcl - message: Ensure web app redirects all HTTP traffic to HTTPS in Azure App Service Slot + - javascript + message: | + Markup escaping disabled. This can be used with some template engines to escape disabling of HTML entities, which can lead to XSS attacks. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: LOW + cwe: CWE-116 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - https_only = true - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper encoding or escaping of output + pattern: $OBJ.escapeMarkup = false severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-min-tls-version.azure-appservice-min-tls-version + - id: rules_lgpl_javascript_xss_rule-xss-serialize-javascript languages: - - hcl - message: Ensure web app is using the latest version of TLS encryption + - javascript + message: "This application is serializing Javascript objects with vulnerable \nconfigurations by setting `{unsafe: true}` in serialize-javascript. \n\nThis could lead to Cross Site Scripting (XSS) if the input was malicious \nscript code and the application server is not properly validating the output.\n\n```\n// safe use of serialize-javascript\nconst jsObj = serialize({\n foo: htmlResponse\n }\n);\n```\n\nXSS is an attack which exploits a web application or system to treat user input as markup or script code. \nIt is important to encode the data depending on the specific context it is used in. \n\nBy default, serialize-javascript encodes input values to prevent XSS attacks. \nConsider using serialize-javascript with default settings or set `{unsafe: false}` to encode\ninput data.\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-80 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern-either: - - pattern: | - "1.0" - - pattern: | - "1.1" - - pattern-inside: min_tls_version = ... - - pattern-inside: | - $RESOURCE "azurerm_app_service" "..." { - ... - } + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper neutralization of script-related HTML tags in a web page (basic XSS) + pattern-either: + - patterns: + - pattern-inside: | + $S = require('serialize-javascript') + ... + - pattern: '$S(..., {...,unsafe: true,...})' + - patterns: + - pattern-inside: | + import serialize from "serialize-javascript"; + ... + - pattern: 'serialize(..., {...,unsafe: true,...})' severity: WARNING - - id: terraform.azure.security.azure-key-no-expiration-date.azure-key-no-expiration-date + - id: kotlin_cookie_rule-CookieHTTPOnly languages: - - hcl - message: Ensure that the expiration date is set on all keys + - kotlin + message: | + A new cookie is created without the HttpOnly flag set. The HttpOnly flag is a directive to the + browser to make sure that the cookie can not be red by malicious script. When a user is the + target of a "Cross-Site Scripting", the attacker would benefit greatly from getting the session + id for example. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW + cwe: CWE-1004 owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Sensitive cookie without 'HttpOnly' flag technology: - - terraform - - azure + - kotlin patterns: - - pattern: resource + - pattern: | + $C = $X.servlet.http.Cookie(..., ...) + ...; + ($RESP: $X.servlet.http.HttpServletResponse).addCookie($C) - pattern-not-inside: | - resource "azurerm_key_vault_key" "..." { + $C = $X.servlet.http.Cookie(..., ...) ... - expiration_date = "..." - ... - } - - pattern-inside: | - resource "azurerm_key_vault_key" "..." { - ... - } + $C.setHttpOnly(true) + ...; + ($RESP: $X.servlet.http.HttpServletResponse).addCookie($C) severity: WARNING - - id: terraform.azure.security.azure-mssql-service-mintls-version.azure-mssql-service-mintls-version + - id: kotlin_cookie_rule-CookieInsecure languages: - - hcl - message: Ensure MSSQL is using the latest version of TLS encryption + - kotlin + message: | + "A new cookie is created without the Secure flag set. The Secure flag is a + directive to the browser to make sure that the cookie is not sent for insecure communication + (http://)" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-614 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Sensitive cookie in HTTPS session without 'Secure' attribute technology: - - terraform - - azure + - kotlin patterns: - - pattern-either: - - pattern: | - "1.0" - - pattern: | - "1.1" - - pattern-inside: minimum_tls_version = ... - - pattern-inside: | - $RESOURCE "azurerm_mssql_server" "..." { + - pattern: | + $C = $X.servlet.http.Cookie(..., ...) + ...; + ($RESP: $X.servlet.http.HttpServletResponse).addCookie($C) + - pattern-not-inside: | + $C = $X.servlet.http.Cookie(..., ...) ... - } + $C.setSecure(true) + ...; + ($RESP: $X.servlet.http.HttpServletResponse).addCookie($C) severity: WARNING - - id: terraform.azure.security.azure-mysql-encryption-enabled.azure-mysql-encryption-enabled + - id: kotlin_cookie_rule-HttpResponseSplitting languages: - - hcl - message: Ensure that MySQL server enables infrastructure encryption + - kotlin + message: | + When an HTTP request contains unexpected CR and LF characters, the server may respond with an + output stream that is interpreted as two different HTTP responses (instead of one). An attacker + can control the second response and mount attacks such as cross-site scripting and cache + poisoning attacks. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: LOW + cwe: CWE-113 owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mysql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mysql_server" "..." { - ... - infrastructure_encryption_enabled = true - ... - } + - kotlin + mode: taint + pattern-sanitizers: + - patterns: + - metavariable-pattern: + metavariable: $S0 + pattern-either: + - pattern: '...' + - pattern: '""' + - metavariable-pattern: + metavariable: $PATTERN + patterns: + - pattern: '...' + - pattern-regex: .*\[\]?(?=[^]]*\\r)(?=[^]]*\\n)[^]]*\]\+ + - pattern-inside: | + $STR.replace($PATTERN, $S0) + ... + - pattern: org.apache.commons.text.StringEscapeUtils.escapeJava(...) + pattern-sinks: + - pattern: javax.servlet.http.Cookie("$KEY", ...) + - patterns: + - pattern-inside: | + $C = javax.servlet.http.Cookie("$KEY", ...) + ... + - pattern: $C.setValue(...) + pattern-sources: + - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameter(...)' + - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameterNames()' + - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameterValues(...)' + - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameterMap()' + - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getHeader(...)' + - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getPathInfo()' severity: WARNING - - id: terraform.azure.security.azure-mysql-mintls-version.azure-mysql-mintls-version + - id: kotlin_cookie_rule-RequestParamToHeader languages: - - hcl - message: Ensure MySQL is using the latest version of TLS encryption + - kotlin + message: | + This code directly writes an HTTP parameter to an HTTP header, which allows for a HTTP + response splitting vulnerability. See http://en.wikipedia.org/wiki/HTTP_response_splitting for + more information. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-113 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') technology: - - terraform - - azure - patterns: - - pattern-either: - - pattern: | - "TLS1_0" - - pattern: | - "TLS1_1" - - pattern-inside: ssl_minimal_tls_version_enforced = ... - - pattern-inside: | - $RESOURCE "azurerm_mysql_server" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.keyvault.keyvault-ensure-key-expires.keyvault-ensure-key-expires + - kotlin + mode: taint + pattern-sanitizers: + - patterns: + - metavariable-pattern: + metavariable: $S0 + pattern-either: + - pattern: '...' + - pattern: '""' + - metavariable-pattern: + metavariable: $PATTERN + patterns: + - pattern: '...' + - pattern-regex: .*\[\]?(?=[^]]*\\r)(?=[^]]*\\n)[^]]*\]\+ + - pattern-inside: | + $STR.replace($PATTERN, $S0); + ... + - pattern: org.apache.commons.text.StringEscapeUtils.unescapeJava(...); + pattern-sinks: + - pattern: '($RES: $X.servlet.http.HttpServletResponse).setHeader("$KEY", ...);' + - pattern: '($RES: $X.servlet.http.HttpServletResponse).addHeader("$KEY", ...);' + - pattern: '($WRP: $X.servlet.http.HttpServletResponseWrapper).setHeader("$KEY", ...);' + - pattern: '($WRP: $X.servlet.http.HttpServletResponseWrapper).addHeader("$KEY", ...);' + pattern-sources: + - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameter(...);' + - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameterNames();' + - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameterValues(...);' + - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameterMap();' + - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getHeader(...);' + - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getPathInfo();' + severity: ERROR + - id: kotlin_cors_rule-PermissiveCORSInjection languages: - - hcl - message: Ensure that the expiration date is set on all keys + - kotlin + message: | + Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for + JavaScript to access the contents of a Web page, both the JavaScript and the Web page must + originate from the same domain. Without the Same Origin Policy, a malicious website could serve + up JavaScript that loads sensitive information from other websites using a client's + credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible + for JavaScript to access data across domains if a new HTTP header called + Access-Control-Allow-Origin is defined. With this header, a Web server defines which other + domains are allowed to access its domain using cross-origin requests. However, caution should + be taken when defining the header because an overly permissive CORS policy will allow a + malicious application to communicate with the victim application in an inappropriate way, + leading to spoofing, data theft, relay and other attacks. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-262: Not Using Password Aging' - impact: MEDIUM - likelihood: LOW - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key#expiration_date - - https://docs.microsoft.com/en-us/powershell/module/az.keyvault/update-azkeyvaultkey?view=azps-5.8.0#example-1--modify-a-key-to-enable-it--and-set-the-expiration-date-and-tags - subcategory: - - vuln + cwe: CWE-942 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Permissive cross-domain policy with untrusted domains technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault_key" "..." { - ... - expiration_date = "..." - ... - } - - pattern-inside: | - resource "azurerm_key_vault_key" "..." { - ... - } - severity: INFO - - id: terraform.azure.security.keyvault.keyvault-ensure-secret-expires.keyvault-ensure-secret-expires + - kotlin + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: '($RES: HttpServletResponse).setHeader("$HEADER", ...)' + - pattern: '($RES: HttpServletResponse).addHeader("$HEADER", ...)' + - metavariable-regex: + metavariable: $HEADER + regex: (?i)(Access-Control-Allow-Origin) + pattern-sources: + - pattern: '($REQ: HttpServletRequest).getParameter(...)' + - pattern: '($REQ: HttpServletRequest).getHeader(...)' + - pattern: '($REQ: HttpServletRequest).getPathInfo()' + - pattern: '($REQ: HttpServletRequest).getQueryString()' + - pattern: '($REQ: HttpServletRequest).getAttribute(...)' + - pattern: '($REQ: HttpServletRequest).getSession().getAttribute(...)' + - pattern: '($REQ: HttpServletRequest).getServletContext().getAttribute(...)' + - pattern: '($REQ: HttpServletRequest).getParameterValues(...)' + - pattern: '($REQ: HttpServletRequest).getParameterNames()' + - pattern: '($REQ: HttpServletRequest).getParameterMap()' + severity: ERROR + - id: kotlin_crypto_rule-BlowfishKeySize languages: - - hcl - message: Ensure that the expiration date is set on all secrets + - kotlin + message: | + A small key size makes the ciphertext vulnerable to brute force attacks. At least 128 bits of + entropy should be used when generating the key if use of Blowfish is required. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-262: Not Using Password Aging' - impact: MEDIUM - likelihood: LOW - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret#expiration_date - - https://docs.microsoft.com/en-us/azure/key-vault/secrets/about-secrets - subcategory: - - vuln + cwe: CWE-326 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Inadequate encryption strength technology: - - terraform - - azure + - kotlin patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault_secret" "..." { - ... - expiration_date = "..." - ... - } - pattern-inside: | - resource "azurerm_key_vault_secret" "..." { + $KEYGEN = javax.crypto.KeyGenerator.getInstance("Blowfish", ...); ... - } - severity: INFO - - id: terraform.azure.security.keyvault.keyvault-purge-enabled.keyvault-purge-enabled + $KEYGEN.init($KEY_SIZE); + - metavariable-comparison: + comparison: $KEY_SIZE < 128 + metavariable: $KEY_SIZE + severity: WARNING + - id: kotlin_crypto_rule-CipherDESInsecure languages: - - hcl - message: Key vault should have purge protection enabled + - kotlin + message: | + DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage + of AES block ciphers instead of DES. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-693: Protection Mechanism Failure' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault#purge_protection_enabled - - https://docs.microsoft.com/en-us/azure/key-vault/general/soft-delete-overview#purge-protection - subcategory: - - vuln + cwe: CWE-326 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Inadequate encryption strength technology: - - terraform - - azure + - kotlin patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault" "..." { - ... - purge_protection_enabled = true - ... - } - - pattern-either: - - pattern-inside: | - resource "azurerm_key_vault" "..." { - ... - } - - pattern-inside: | - resource "azurerm_key_vault" "..." { - ... - purge_protection_enabled = false - ... - } + - pattern-inside: javax.crypto.Cipher.getInstance($TRANSFORMATION, ...) + - metavariable-regex: + metavariable: $TRANSFORMATION + regex: ^"DES(/|"$) severity: WARNING - - id: terraform.azure.security.storage.storage-enforce-https.storage-enforce-https + - id: kotlin_crypto_rule-CipherDESedeInsecure languages: - - hcl - message: Detected a Storage that was not configured to deny action by default. Add `enable_https_traffic_only = true` in your resource block. + - kotlin + message: | + Triple DES (also known as 3DES or DESede) is considered strong ciphers for modern + applications. NIST recommends the usage of AES block ciphers instead of 3DES. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: LOW + cwe: CWE-327 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#enable_https_traffic_only - - https://docs.microsoft.com/en-us/azure/storage/common/storage-require-secure-transfer - subcategory: - - vuln + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Use of a broken or risky cryptographic algorithm technology: - - terraform - - azure + - kotlin patterns: - - pattern-not-inside: | - resource "azurerm_storage_account" "..." { - ... - enable_https_traffic_only = true - ... - } - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - enable_https_traffic_only = false - ... - } + - pattern-inside: javax.crypto.Cipher.getInstance($ALG, ...) + - metavariable-regex: + metavariable: $ALG + regex: (?i)^"DESede(/|"$) severity: WARNING - - id: terraform.azure.security.storage.storage-use-secure-tls-policy.storage-use-secure-tls-policy + - id: kotlin_crypto_rule-CipherECBMode languages: - - hcl - message: 'Azure Storage currently supports three versions of the TLS protocol: 1.0, 1.1, and 1.2. Azure Storage uses TLS 1.2 on public HTTPS endpoints, but TLS 1.0 and TLS 1.1 are still supported for backward compatibility. This check will warn if the minimum TLS is not set to TLS1_2.' + - kotlin + message: | + An authentication cipher mode which provides better confidentiality of the encrypted data + should be used instead of Electronic Code Book (ECB) mode, which does not provide good + confidentiality. Specifically, ECB mode produces the same output for the same input each time. + This allows an attacker to intercept and replay the data. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#min_tls_version - - https://docs.microsoft.com/en-us/azure/storage/common/transport-layer-security-configure-minimum-version - subcategory: - - vuln + cwe: CWE-326 + security-severity: CRITICAL + shortDescription: Inadequate Encryption Strength technology: - - terraform - - azure + - kotlin patterns: - - pattern-either: - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - min_tls_version = "$ANYTHING" - ... - } - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_storage_account" "..." { - ... - min_tls_version = "TLS1_2" - ... - } + - pattern: javax.crypto.Cipher.getInstance($TRANSFORMATION, ...) + - metavariable-regex: + metavariable: $TRANSFORMATION + regex: ^"[^/]*/ECB(/.*)?"$ severity: ERROR - - id: terraform.gcp.security.gcp-cloud-storage-logging.gcp-cloud-storage-logging + - id: kotlin_crypto_rule-CipherIntegrity languages: - - hcl - message: Ensure bucket logs access. + - kotlin + message: | + The ciphertext produced is susceptible to alteration by an adversary. This mean that the + cipher provides no way to detect that the data has been tampered with. If the ciphertext can be + controlled by an attacker, it could be altered without detection. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-778: Insufficient Logging' - impact: LOW - likelihood: LOW + cwe: CWE-327 owasp: - - A10:2017 - Insufficient Logging & Monitoring - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - vuln + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: CRITICAL + shortDescription: Use of a broken or risky cryptographic algorithm technology: - - terraform - - gcp + - kotlin patterns: - pattern: | - resource "google_storage_bucket" $ANYTHING { - ... - } - - pattern-not-inside: "resource \"google_storage_bucket\" $ANYTHING {\n ...\n logging {\n log_bucket = ...\n } \n ...\n}\n" - severity: WARNING - - id: terraform.gcp.security.gcp-dns-key-specs-rsasha1.gcp-dns-key-specs-rsasha1 + javax.crypto.Cipher.getInstance($TRANSFORMATION, ...) + - metavariable-pattern: + metavariable: $TRANSFORMATION + patterns: + - pattern-regex: ^"[^/]*(/(CBC|OFB|CTR|ECB)(/.*)?)?"$ + - pattern-not-regex: ^"(ECIES|RSA)(/|"$) + severity: ERROR + - id: kotlin_crypto_rule-CipherPaddingOracle languages: - - hcl - message: "Ensure that RSASHA1 is not used for the zone-signing and key-signing keys in Cloud DNS DNSSEC\t" + - kotlin + message: | + This specific mode of CBC with PKCS5Padding is susceptible to padding oracle attacks. An + adversary could potentially decrypt the message if the system exposed the difference between + plaintext with invalid padding or valid padding. The distinction between valid and invalid + padding is usually revealed through distinct error messages being returned for each condition. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-327 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: CRITICAL + shortDescription: Use of a broken or risky cryptographic algorithm technology: - - terraform - - gcp + - java patterns: - - pattern: resource - - pattern-inside: | - resource "google_dns_managed_zone" "..." { - ... - dnssec_config { - ... - default_key_specs { - ... - algorithm = "rsasha1" - key_type = "zoneSigning" - ... - } - ... - } - ... - } - - pattern-inside: | - resource "google_dns_managed_zone" "..." { - ... - dnssec_config { - ... - default_key_specs { - ... - algorithm = "rsasha1" - key_type = "keySigning" - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-sql-database-require-ssl.gcp-sql-database-require-ssl + - pattern: javax.crypto.Cipher.getInstance($TRANSFORMATION) + - metavariable-regex: + metavariable: $TRANSFORMATION + regex: ^"[^/]*/CBC/PKCS5Padding + - metavariable-pattern: + metavariable: $TRANSFORMATION + patterns: + - pattern-not-regex: ^"(RSA|ECIES)/ + severity: ERROR + - id: kotlin_crypto_rule-CustomMessageDigest languages: - - hcl - message: Ensure all Cloud SQL database instance requires all incoming connections to use SSL + - kotlin + message: | + Implementing a custom MessageDigest is error-prone. National Institute of Standards and + Technology(NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or + SHA-512/256. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW + cwe: CWE-327 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln + - A6:2017-Security Misconfiguration + - A04:2021-Insecure Design + security-severity: MEDIUM + shortDescription: Use of a broken or risky cryptographic algorithm technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - } - - pattern-not-inside: | - resource "google_sql_database_instance" "..." { - ... - ip_configuration { - ... - require_ssl = true - ... - } - ... - } + - kotlin + pattern: | + class $CLAZZ : java.security.MessageDigest(...) { + ... + } severity: WARNING - - id: terraform.gcp.security.gcp-sql-public-database.gcp-sql-public-database + - id: kotlin_crypto_rule-HazelcastSymmetricEncryption languages: - - hcl - message: Ensure that Cloud SQL database Instances are not open to the world + - kotlin + message: | + The network communications for Hazelcast is configured to use a symmetric cipher (probably DES + or Blowfish). Those ciphers alone do not provide integrity or secure authentication. The use of + asymmetric encryption is preferred. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-284: Improper Access Control' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-326 owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Inadequate encryption strength technology: - - terraform - - gcp + - kotlin + pattern: com.hazelcast.config.SymmetricEncryptionConfig() + severity: WARNING + - id: kotlin_crypto_rule-InsufficientKeySizeRsa + languages: + - kotlin + message: | + Detected an insufficient key size for DSA. NIST recommends a key size + of 2048 or higher. + metadata: + category: security + cwe: CWE-326 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Inadequate encryption strength patterns: - - pattern: resource - pattern-either: - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - ip_configuration { - ... - authorized_networks { - ... - value = "0.0.0.0/0" - ... - } - ... - } - ... - } - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - ip_configuration { - ... - dynamic "authorized_networks" { - ... - content { - ... - value = "0.0.0.0/0" - ... - } + - patterns: + - pattern-inside: | + $GEN = KeyPairGenerator.getInstance($ALG, ...); ... - } - ... - } - ... - } + - pattern-either: + - pattern: $VAR.initialize($SIZE, ...); + - pattern: java.security.spec.RSAKeyGenParameterSpec($SIZE,...); + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE + - metavariable-regex: + metavariable: $ALG + regex: '"(RSA|DSA)"' severity: WARNING - - id: terraform.lang.security.ec2-imdsv1-optional.ec2-imdsv1-optional + - id: kotlin_crypto_rule-NullCipher languages: - - hcl - message: AWS EC2 Instance allowing use of the IMDSv1 + - kotlin + message: | + The NullCipher implements the Cipher interface by returning ciphertext identical to the + supplied plaintext. In a few contexts, such as testing, a NullCipher may be appropriate. Avoid + using the NullCipher. Its accidental use can introduce a significant confidentiality risk. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + cwe: CWE-327 owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#metadata-options - subcategory: - - vuln + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Use of a broken or risky cryptographic algorithm technology: - - terraform - - aws - pattern-either: - - patterns: - - pattern: http_tokens = "optional" - - pattern-inside: | - metadata_options { ... } - - patterns: - - pattern: | - resource "aws_instance" "$NAME" { - ... - } - - pattern-not: | - resource "aws_instance" "$NAME" { - ... - metadata_options { - ... - http_tokens = "required" - ... - } - ... - } - - pattern-not: | - resource "aws_instance" "$NAME" { - ... - metadata_options { - ... - http_tokens = "optional" - ... - } - ... - } - - pattern-not: | - resource "aws_instance" "$NAME" { - ... - metadata_options { - ... - http_endpoint = "disabled" - ... - } - ... - } - severity: ERROR - - id: terraform.lang.security.rds-insecure-password-storage-in-source-code.rds-insecure-password-storage-in-source-code + - kotlin + pattern: javax.crypto.NullCipher() + severity: WARNING + - id: kotlin_crypto_rule-RsaNoPadding languages: - - hcl - message: RDS instance or cluster with hardcoded credentials in source code. It is recommended to pass the credentials at runtime, or generate random credentials using the random_password resource. + - kotlin + message: | + The software uses the RSA algorithm but does not incorporate Optimal Asymmetric + Encryption Padding (OAEP), which might weaken the encryption. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-780 owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#master_password - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster#master_password - - https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password - subcategory: - - vuln - technology: - - terraform - - aws + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Use of RSA algorithm without OAEP pattern-either: - patterns: - - pattern: password = "..." - - pattern-inside: | - resource "aws_db_instance" "..." { - ... - } + - pattern: | + $VAR = "$ALG"; + ... + javax.crypto.Cipher.getInstance($VAR); + - metavariable-regex: + metavariable: $ALG + regex: .*RSA.*NoPadding.* - patterns: - - pattern: master_password = "..." - - pattern-inside: | - resource "aws_rds_cluster" "..." { - ... - } + - pattern: javax.crypto.Cipher.getInstance($ALG,...); + - metavariable-regex: + metavariable: $ALG + regex: .*RSA.*NoPadding.* severity: WARNING - - id: terraform.lang.security.s3-public-rw-bucket.s3-public-rw-bucket + - id: kotlin_crypto_rule-WeakMessageDigest languages: - - hcl - message: S3 bucket with public read-write access detected. + - kotlin + message: | + DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage + of AES block ciphers instead of DES. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: MEDIUM - likelihood: LOW + cwe: CWE-327 owasp: - - A01:2021 - Broken Access Control - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#acl - - https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl - subcategory: - - vuln + - A6:2017-Security Misconfiguration + - A04:2021-Insecure Design + security-severity: MEDIUM + shortDescription: Use of a broken or risky cryptographic algorithm (SHA1/MD5) technology: - - terraform - - aws - pattern: acl = "public-read-write" - severity: ERROR - - id: terraform.lang.security.s3-unencrypted-bucket.s3-unencrypted-bucket + - kotlin + patterns: + - pattern-either: + - pattern: MessageDigest.getInstance($ALG, ...) + - pattern: Signature.getInstance($ALG, ...) + - metavariable-regex: + metavariable: $ALG + regex: .*(MD5|MD4|MD2|SHA1|SHA-1).* + severity: WARNING + - id: kotlin_crypto_rule-WeakTLSProtocol languages: - - hcl - message: This rule has been deprecated, as all s3 buckets are encrypted by default with no way to disable it. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration for more info. + - kotlin + message: | + A HostnameVerifier that accept any host are often use because of certificate + reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middleattacks + attacks since the client will trust any certificate. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - deprecated: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-295 owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#server_side_encryption_configuration - - https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html - subcategory: - - vuln - technology: - - terraform - - aws + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Improper certificate validation patterns: - - pattern: a - - pattern: b - severity: INFO - - id: typescript.angular.security.audit.angular-domsanitizer.angular-bypasssecuritytrust + - pattern-either: + - pattern: org.apache.http.impl.client.DefaultHttpClient() + - pattern: javax.net.ssl.SSLContext.getInstance("SSL") + severity: WARNING + - id: kotlin_crypto_rule-WeakTLSProtocolVersion languages: - - typescript - message: Detected the use of `$TRUST`. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. If you have to use `$TRUST`, ensure it does not come from user-input or use the appropriate prevention mechanism e.g. input validation or sanitization depending on the context. + - kotlin + message: | + The application was found enabling insecure TLS protocol versions. When enabling protocol + versions for an `SSLContext`, only the following versions should be allowed: + - TLSv1.2 + - TLSv1.3 + - DTLSv1.2 + - DTLSv1.3 + + To mitigate potential security risks, it is strongly advised to enforce TLS 1.2 as the minimum + protocol version and disallow older versions such as TLS 1.0. Do note that newer versions of + Java do not even support TLS 1.0 and will throw `NoSuchAlgorithmException`. Versions of TLS + prior to 1.2 could expose the connection to downgrade attacks, where an adversary intercepts + the + connection and alters the requested protocol version to be a less secure one. + + In many scenarios, relying on the default system configuration does not meet compliance + standards. This is due to the application being deployed across diverse systems with varying + configurations and Java versions. While the default value may be secure on modern and + up-to-date systems, it may not hold true for older systems. Consequently, it is highly + recommended to explicitly define a secure configuration in all cases. + + Example configuring an SSLContext with TLSv1.2: + ``` + // Create an SSLContext with TLSv1.2 explicitly + SSLContext tlsContext = SSLContext.getInstance("TLSv1.2"); // or TLSv1.3, DTLSv1.2, DTLSv1.3 + + // Alternatively, set the enabled protocols + SSLContext serverSslContext = SSLContext.getInstance("TLS"); + SSLEngine serverEngine = serverSslContext.createSSLEngine(); + // Calling setEnabledProtocols will override the original context's configured protocol version + serverEngine.setEnabledProtocols(new String[]{ "TLSv1.2" }); + ``` + + For more information on `SSLContext` see: + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/javax/net/ssl/SSLContext.html + + For more information on MiTM attacks see: + - https://owasp.org/www-community/attacks/Manipulator-in-the-middle_attack metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW + cwe: CWE-326 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://angular.io/api/platform-browser/DomSanitizer - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - angular - - browser - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) - - patterns: - - pattern-either: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: MEDIUM + shortDescription: Inadequate encryption strength + patterns: + - pattern-either: + - pattern-inside: | + import javax.net.ssl.*; + ... + - pattern-inside: | + import javax.net.ssl.SSLContext; + ... + - pattern-either: + - pattern-inside: | + SSLContext.getInstance("$UNSAFE_VERSION"); + - pattern-inside: | + SSLContext.getInstance(...); + ... + $ENGINE.setEnabledProtocols(arrayOf(...,"$UNSAFE_VERSION",...)); + - pattern-not: + patterns: - pattern-inside: | - import $S from 'sanitize-html'; + $C = SSLContext.getInstance(...); ... + $ENGINE.setEnabledProtocols(arrayOf(...,"$DT_GOODNESS",...)); + - metavariable-regex: + metavariable: $DT_GOODNESS + regex: ^D?TLSv1\.[23]$ + - pattern-not: + patterns: - pattern-inside: | - import * as $S from "sanitize-html"; + $C = SSLContext.getInstance(...); ... - - pattern-inside: | - $S = require("sanitize-html") + $E = $C.createSSLEngine() ... - - pattern: $S(...) - - patterns: - - pattern: sanitizer.sanitize(...) - - pattern-not: sanitizer.sanitize(SecurityContext.NONE, ...); - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $X.$TRUST($Y) - - focus-metavariable: $Y - - pattern-not: | - $X.$TRUST(`...`) - - pattern-not: | - $X.$TRUST("...") - - metavariable-regex: - metavariable: $TRUST - regex: (bypassSecurityTrustHtml|bypassSecurityTrustStyle|bypassSecurityTrustScript|bypassSecurityTrustUrl|bypassSecurityTrustResourceUrl) - pattern-sources: + $E.enabledProtocols = arrayOf(...,"$DT_GOODNESS",...) + - metavariable-regex: + metavariable: $DT_GOODNESS + regex: ^DTLSv1\.[23]$ + - metavariable-regex: + metavariable: $UNSAFE_VERSION + regex: ^(TLS|(D)?TLSv1.(0|1))$ + severity: WARNING + - id: kotlin_csrf_rule-SpringCSRFDisabled + languages: + - kotlin + message: | + The application fails to protect against Cross-Site Request Forgery (CSRF) + due to disabling Spring's CSRF protection features. + metadata: + category: security + cwe: CWE-352 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Cross-Site Request Forgery (CSRF) + pattern-either: + - pattern: '($H: org.springframework.security.config.annotation.web.builders.HttpSecurity). ... .csrf().disable()' + - pattern: '($C: CsrfConfigurer).disable()' + severity: WARNING + - id: kotlin_endpoint_rule-UnvalidatedRedirect + languages: + - kotlin + message: | + Unvalidated redirects occur when an application redirects a user to a + destination URL specified by a user supplied parameter that is not validated. + Such vulnerabilities can be used to facilitate phishing attacks. + metadata: + category: security + cwe: CWE-601 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: URL redirection to untrusted site ('Open Redirect') + mode: taint + pattern-sanitizers: - patterns: + - pattern-inside: | + if ($SAFE.contains($URL)){ + ... + } - pattern-either: + - pattern: | + ($RES: $X.servlet.http.HttpServletResponse).sendRedirect($URL) + - pattern: | + ($RES: $X.servlet.http.HttpServletResponse).addHeader("Location", $URL) + pattern-sinks: + - pattern-either: + - pattern: | + ($RES: $X.servlet.http.HttpServletResponse).sendRedirect($URL) + - pattern: | + ($RES: $X.servlet.http.HttpServletResponse).addHeader("Location", $URL) + pattern-sources: + - patterns: + - pattern: | + $URL = ($REQ: $X.servlet.http.HttpServletRequest).$M(...); + - metavariable-regex: + metavariable: $M + regex: (getParameter|getCookies|getHeader|getHeaders|getHeaderNames|getPathInfo|getPathTranslated|getContextPath|getQueryString|getRemoteUser|getRequestedSessionId|getRequestURI|getRequestURL|getServletPath|getParts|getPart|getReader) + severity: ERROR + - id: kotlin_endpoint_rule-WeakHostNameVerification + languages: + - kotlin + message: | + A HostnameVerifier that accept any host are often use because of certificate + reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middle + attacks since the client will trust any certificate. + metadata: + category: security + cwe: CWE-295 + security-severity: MEDIUM + shortDescription: Improper Certificate Validation + patterns: + - pattern-either: + - patterns: - pattern-inside: | - function ...({..., $X: string, ...}) { ... } + class $V : HostnameVerifier { + ... + } + - pattern: | + fun verify(...): Boolean { + return true + } + - patterns: - pattern-inside: | - function ...(..., $X: string, ...) { ... } - - focus-metavariable: $X + class $V : X509TrustManager { + ... + } + - pattern-either: + - pattern: fun checkClientTrusted(...) {} + - pattern: fun checkServerTrusted(...) {} + - pattern: 'fun getAcceptedIssuers(): Array? {return null}' severity: WARNING - - id: typescript.aws-cdk.security.audit.awscdk-bucket-encryption.awscdk-bucket-encryption + - id: kotlin_file_rule-FileUploadFileName languages: - - typescript - message: 'Add "encryption: $Y.BucketEncryption.KMS_MANAGED" or "encryption: $Y.BucketEncryption.S3_MANAGED" to the bucket props for Bucket construct $X' + - kotlin + message: | + The filename provided by the FileUpload API can be tampered with by the client to reference + unauthorized files. The provided filename should be properly validated to ensure it's properly + structured, contains no unauthorized path characters (e.g., / \), and refers to an authorized + file. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW + cwe: CWE-22 owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html - subcategory: - - vuln + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') technology: - - AWS-CDK + - kotlin pattern-either: - patterns: - pattern-inside: | - import {Bucket} from '@aws-cdk/aws-s3' - ... - - pattern: const $X = new Bucket(...) - - pattern-not: | - const $X = new Bucket(..., {..., encryption: BucketEncryption.KMS_MANAGED, ...}) - - pattern-not: | - const $X = new Bucket(..., {..., encryption: BucketEncryption.KMS, ...}) - - pattern-not: | - const $X = new Bucket(..., {..., encryption: BucketEncryption.S3_MANAGED, ...}) - - patterns: - - pattern-inside: | - import * as $Y from '@aws-cdk/aws-s3' + $FILES = ($SFU: ServletFileUpload).parseRequest(($REQ: $X.servlet.http.HttpServletRequest?)) ... - - pattern: const $X = new $Y.Bucket(...) - - pattern-not: | - const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.KMS_MANAGED, ...}) - - pattern-not: | - const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.KMS, ...}) - - pattern-not: | - const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.S3_MANAGED, ...}) + for($ITEM in $FILES) { + ... + } + - pattern: $ITEM.getName() + - pattern: '($PART: $X.servlet.http.Part).getSubmittedFileName()' severity: ERROR - - id: typescript.aws-cdk.security.audit.awscdk-bucket-enforcessl.aws-cdk-bucket-enforcessl + - id: kotlin_file_rule-FilenameUtils languages: - - ts - message: Bucket $X is not set to enforce encryption-in-transit, if not explictly setting this on the bucket policy - the property "enforceSSL" should be set to true + - kotlin + message: | + A file is opened to read its content. The filename comes from an input + parameter. If an unfiltered parameter is passed to this file API, files from an + arbitrary filesystem location could be read. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-22 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html - subcategory: - - vuln + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') technology: - - AWS-CDK - pattern-either: - - patterns: - - pattern-inside: | - import {Bucket} from '@aws-cdk/aws-s3'; - ... - - pattern: const $X = new Bucket(...) - - pattern-not: | - const $X = new Bucket(..., {enforceSSL: true}, ...) - - patterns: - - pattern-inside: | - import * as $Y from '@aws-cdk/aws-s3'; - ... - - pattern: const $X = new $Y.Bucket(...) - - pattern-not: | - const $X = new $Y.Bucket(..., {..., enforceSSL: true, ...}) - severity: ERROR - - id: typescript.aws-cdk.security.audit.awscdk-sqs-unencryptedqueue.awscdk-sqs-unencryptedqueue + - kotlin + patterns: + - pattern-inside: | + import org.apache.commons.io.FilenameUtils + ... + - pattern-either: + - pattern: normalize(...) + - pattern: getExtension(...) + - pattern: isExtensions(...) + - pattern: getName(...) + - pattern: getBaseName(...) + - pattern: org.apache.commons.io.FilenameUtils.normalize(...) + - pattern: org.apache.commons.io.FilenameUtils.getExtension(...) + - pattern: org.apache.commons.io.FilenameUtils.isExtensions(...) + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + - pattern: org.apache.commons.io.FilenameUtils.getBaseName(...) + severity: WARNING + - id: kotlin_inject_rule-CommandInjection languages: - - ts - message: 'Queue $X is missing encryption at rest. Add "encryption: $Y.QueueEncryption.KMS" or "encryption: $Y.QueueEncryption.KMS_MANAGED" to the queue props to enable encryption at rest for the queue.' + - kotlin + message: | + The highlighted API is used to execute a system command. If unfiltered input is passed to this + API, it can lead to arbitrary command execution. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW + cwe: CWE-78 owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-data-protection.html - subcategory: - - vuln + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') technology: - - AWS-CDK + - kotlin pattern-either: - patterns: - pattern-inside: | - import {Queue} from '@aws-cdk/aws-sqs' + fun $FUNC(..., $PARAM: String, ...) { + ... + } + - pattern-inside: | + $R = Runtime.getRuntime() ... - - pattern: const $X = new Queue(...) - - pattern-not: | - const $X = new Queue(..., {..., encryption: QueueEncryption.KMS_MANAGED, ...}) + - pattern-either: + - pattern: $R.exec(<...$PARAM...>,...) + - patterns: + - pattern-either: + - pattern: | + $CMDARR = arrayOf("$SHELL",...,<...$PARAM...>,...) + ... + $R.exec($CMDARR,...) + - pattern: $R.exec(arrayOf("$SHELL",...,<...$PARAM...>,...), ...) + - pattern: $R.exec(java.util.String.format("...", ...,<...$PARAM...>,...)) + - pattern: '$R.exec(($A: String) + ($B: String))' + - metavariable-regex: + metavariable: $SHELL + regex: (/.../)?(sh|bash|ksh|csh|tcsh|zsh)$ + - pattern-not: $R.exec("...","...","...",...) - pattern-not: | - const $X = new Queue(..., {..., encryption: QueueEncryption.KMS, ...}) + $R.exec(arrayOf("...","...","...",...),...) - patterns: - pattern-inside: | - import * as $Y from '@aws-cdk/aws-sqs' + fun $FUNC(..., $PARAM: String, ...) { + ... + } + - pattern-inside: | + $PB = ProcessBuilder() ... - - pattern: const $X = new $Y.Queue(...) - - pattern-not: | - const $X = new $Y.Queue(..., {..., encryption: $Y.QueueEncryption.KMS_MANAGED, ...}) + - pattern-either: + - pattern: $PB.command(<...$PARAM...>,...) + - patterns: + - pattern-inside: $VAL = <...$PARAM...>; ... + - pattern: $PB.command(<...$VAL...>,...) + - patterns: + - pattern-either: + - pattern: $PB.command("$SHELL",...,<...$PARAM...>,...) + - pattern: | + $CMDARR = java.util.Arrays.asList("$SHELL",...,<...$PARAM...>,...) + ... + $PB.command($CMDARR,...) + - pattern: $PB.command(java.util.Arrays.asList("$SHELL",...,<...$PARAM...>,...),...) + - pattern: $PB.command(java.util.String.format("...", ...,<...$PARAM...>,...)) + - pattern: '$PB.command(($A: String) + ($B: String))' + - metavariable-regex: + metavariable: $SHELL + regex: (/.../)?(sh|bash|ksh|csh|tcsh|zsh)$ + - pattern-not: $PB.command("...","...","...",...) - pattern-not: | - const $X = new $Y.Queue(..., {..., encryption: $Y.QueueEncryption.KMS, ...}) + $PB.command(java.util.Arrays.asList("...","...","...",...)) severity: WARNING - - id: typescript.aws-cdk.security.awscdk-bucket-grantpublicaccessmethod.awscdk-bucket-grantpublicaccessmethod + - id: kotlin_inject_rule-ELInjection languages: - - ts - message: Using the GrantPublicAccess method on bucket contruct $X will make the objects in the bucket world accessible. Verify if this is intentional. + - kotlin + message: | + An expression is built with a dynamic value. The source of the value(s) should be verified to + avoid that unfiltered values fall into this risky code evaluation. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-306: Missing Authentication for Critical Function' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: HIGH + cwe: CWE-917 owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-overview.html - subcategory: - - vuln + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper neutralization of special elements used in an expression language statement ('Expression Language Injection') technology: - - AWS-CDK + - kotlin pattern-either: - patterns: - - pattern-inside: | - import {Bucket} from '@aws-cdk/aws-s3' - ... + - metavariable-regex: + metavariable: $METHOD + regex: ^create(Method|Value)Expression$ + - metavariable-pattern: + metavariable: $EXPR + patterns: + - pattern-not: '"..."' - pattern: | - const $X = new Bucket(...) - ... - $X.grantPublicAccess(...) + ($EXP: ExpressionFactory ).$METHOD(($CTX: $X.el.ELContext), $EXPR, ...) - patterns: - - pattern-inside: | - import * as $Y from '@aws-cdk/aws-s3' - ... - pattern: | - const $X = new $Y.Bucket(...) - ... - $X.grantPublicAccess(...) + ($P: $X.el.ELProcessor).$METHOD(...) + - pattern-not: | + ($P: $X.el.ELProcessor).$METHOD("...", ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(eval|(get|set)Value)$ severity: WARNING - - id: typescript.aws-cdk.security.awscdk-codebuild-project-public.awscdk-codebuild-project-public + - id: kotlin_inject_rule-FileDisclosure languages: - - ts - message: CodeBuild Project $X is set to have a public URL. This will make the build results, logs, artifacts publically accessible, including builds prior to the project being public. Ensure this is acceptable for the project. + - kotlin + message: | + Constructing a server-side redirect path with user input could allow an + attacker to download application binaries (including application classes or + jar files) or view arbitrary files within protected directories. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-306: Missing Authentication for Critical Function' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-552 owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://docs.aws.amazon.com/codebuild/latest/userguide/public-builds.html - subcategory: - - vuln - technology: - - AWS-CDK - pattern-either: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Files or directories accessible to external parties + mode: taint + pattern-sinks: + - patterns: + - pattern: org.springframework.web.servlet.ModelAndView($FST); + - pattern: $FST + - patterns: + - pattern: org.springframework.web.servlet.ModelAndView($FST, $SND); + - pattern: $FST + - patterns: + - pattern: org.springframework.web.servlet.ModelAndView($FST, $SND, $TRD); + - pattern: $FST + - patterns: + - pattern: org.apache.struts.action.ActionForward($FST) + - pattern: $FST + - patterns: + - pattern: org.apache.struts.action.ActionForward($FST, $SND) + - pattern: $FST + - patterns: + - pattern: org.apache.struts.action.ActionForward($FST, $SND, $TRD) + - pattern: $SND + - patterns: + - pattern: org.apache.struts.action.ActionForward($FST, $SND, $TRD) + - pattern: $TRD - patterns: - pattern-inside: | - import {Project} from '@aws-cdk/aws-codebuild' + $ACTION = org.apache.struts.action.ActionForward(); ... - - pattern: | - const $X = new Project(..., {..., badge: true, ...}) + - pattern: $ACTION.setPath(...) - patterns: - pattern-inside: | - import * as $Y from '@aws-cdk/aws-codebuild' + $MVC = org.springframework.web.servlet.ModelAndView(); ... - - pattern: | - const $X = new $Y.Project(..., {..., badge: true, ...}) - severity: WARNING - - id: typescript.react.security.audit.react-dangerouslysetinnerhtml.react-dangerouslysetinnerhtml + - pattern: $MVC.setViewName(...); + - patterns: + - pattern-inside: | + $REQ = $HTTP.getRequestDispatcher(...); + ... + - pattern-either: + - pattern: $REQ.include($FST, $SND) + - pattern: $REQ.forward($FST, $SND) + pattern-sources: + - pattern: '($VAR: javax.servlet.http.HttpServletRequest).getParameter(...)' + severity: ERROR + - id: kotlin_inject_rule-HttpParameterPollution languages: - - typescript - - javascript - message: Detection of dangerouslySetInnerHTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use dangerouslySetInnerHTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. + - kotlin + message: | + Concatenating unvalidated user input into a URL can allow an attacker to override the value of + a request parameter. Attacker may be able to override existing parameter values, inject a new + parameter or exploit variables out of a direct reach. HTTP Parameter Pollution (HPP) attacks + consist of injecting encoded query string delimiters into other existing parameters. If a web + application does not properly sanitize the user input, a malicious user may compromise the + logic of the application to perform either client-side or server-side attacks. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: CWE-88 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html - subcategory: - - vuln + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of argument delimiters in a command ('Argument Injection') technology: - - react + - kotlin mode: taint pattern-sanitizers: + - pattern: java.net.URLEncoder.encode(...) + - pattern: com.google.common.net.UrlEscapers.urlPathSegmentEscaper().escape(...) + pattern-sinks: + - pattern: org.apache.http.client.methods.HttpGet(...) + - pattern: org.apache.commons.httpclient.methods.GetMethod(...) + - pattern: '($GM: org.apache.commons.httpclient.methods.GetMethod).setQueryString(...)' + pattern-sources: + - pattern: '($REQ: HttpServletRequest).getParameter(...)' + severity: ERROR + - id: kotlin_inject_rule-LDAPInjection + languages: + - kotlin + message: | + Just like SQL, all inputs passed to an LDAP query need to be passed in safely. Unfortunately, + LDAP doesn't have prepared statement interfaces like SQL. Therefore, the primary defense + against LDAP injection is strong input validation of any untrusted data before including it in + an LDAP query. + metadata: + category: security + cwe: CWE-90 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper neutralization of special elements used in an LDAP query ('LDAP Injection') + technology: + - kotlin + mode: taint + pattern-sinks: + - pattern: javax.naming.ldap.LdapName(...) + - pattern: '($C: javax.naming.directory.Context).lookup(...)' + - pattern: '($C: javax.naming.Context).lookup(...)' - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) + - pattern-inside: '($C: com.unboundid.ldap.sdk.LDAPConnection).search($QUERY, ...)' + - pattern: $QUERY - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - pattern-either: - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) + - pattern-either: + - pattern: $CTX.lookup(...) + - patterns: + - pattern-inside: $CTX.search($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.search($NAME, $FILTER, ...) + - pattern: $FILTER + - metavariable-pattern: + metavariable: $CTX + pattern-either: + - pattern: '($C: DirContext)' + - pattern: '($IDC: InitialDirContext)' + - pattern: '($LC: LdapContext)' + - pattern: '($EDC: EventDirContext)' + - pattern: '($LC: LdapCtx)' + - pattern: '($C: javax.naming.directory.DirContext)' + - pattern: '($IDC: javax.naming.directory.InitialDirContext)' + - pattern: '($LC: javax.naming.ldap.LdapContext)' + - pattern: '($EDC: javax.naming.event.EventDirContext)' + - pattern: '($LC: com.sun.jndi.ldap.LdapCtx)' - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; - ... - - pattern-inside: | - $S = require("sanitize-html") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - $S = new Remarkable() - ... - - pattern: $S.render(...) - pattern-sinks: - - patterns: - - focus-metavariable: $X - - pattern-either: - - pattern: | - {...,dangerouslySetInnerHTML: {__html: $X},...} - - pattern: | - <$Y ... dangerouslySetInnerHTML={{__html: $X}} /> - - pattern-not: | - <$Y ... dangerouslySetInnerHTML={{__html: "..."}} /> - - pattern-not: | - {...,dangerouslySetInnerHTML:{__html: "..."},...} - - metavariable-pattern: - metavariable: $X - patterns: - - pattern-not: | - {...} - - pattern-not: | - <... {__html: "..."} ...> - - pattern-not: | - <... {__html: `...`} ...> + - pattern-either: + - pattern: $CTX.lookup(...) + - patterns: + - pattern-inside: $CTX.search($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.search($NAME, $FILTER, ...) + - pattern: $FILTER + - pattern-inside: + pattern-either: + - pattern: $CTX = DirContext(...);... + - pattern: $CTX = InitialDirContext(...);... + - pattern: $CTX = LdapContext(...);... + - pattern: $CTX = EventDirContext(...);... + - pattern: $CTX = LdapCtx(...);... + - pattern: $CTX = javax.naming.directory.DirContext(...);... + - pattern: $CTX = javax.naming.directory.InitialDirContext(...);... + - pattern: $CTX = javax.naming.ldap.LdapContext(...);... + - pattern: $CTX = javax.naming.event.EventDirContext(...);... + - pattern: $CTX = com.sun.jndi.ldap.LdapCtx(...);... + - pattern-either: + - patterns: + - pattern-either: + - patterns: + - pattern-inside: $CTX.list($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.lookup($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.search($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.search($NAME, $FILTER, ...) + - pattern: $FILTER + - metavariable-pattern: + metavariable: $CTX + pattern-either: + - pattern: '($LT: LdapTemplate)' + - pattern: '($LO: LdapOperations)' + - pattern: '($LT: org.springframework.ldap.core.LdapTemplate)' + - pattern: '($LO: org.springframework.ldap.core.LdapOperations)' + - patterns: + - pattern-either: + - patterns: + - pattern-inside: $CTX.list($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.lookup($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.search($QUERY, ...) + - pattern: $QUERY + - patterns: + - pattern-inside: $CTX.search($NAME, $FILTER, ...) + - pattern: $FILTER + - pattern-inside: + pattern-either: + - pattern: $CTX = LdapTemplate(...);... + - pattern: $CTX = LdapOperations(...);... + - pattern: $CTX = org.springframework.ldap.core.LdapTemplate(...);... + - pattern: $CTX = org.springframework.ldap.core.LdapOperations(...);... pattern-sources: - patterns: - - pattern-either: - - pattern-inside: | - function ...({..., $X, ...}) { ... } - - pattern-inside: | - function ...(..., $X, ...) { ... } - - focus-metavariable: $X - - pattern-not-inside: | - $F. ... .$SANITIZEUNC(...) + - pattern-inside: | + fun $FUNC(..., $VAR: String, ...) { + ... + } + - pattern: $VAR + - patterns: + - pattern-inside: | + fun $FUNC(..., $X: String, ...) { + ... + $VAR = ... + $X + ... + } + - pattern: $VAR severity: WARNING - - id: typescript.react.security.audit.react-unsanitized-method.react-unsanitized-method + - id: kotlin_inject_rule-OgnlInjection languages: - - typescript - - javascript - message: Detection of $HTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use $HTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. + - kotlin + message: | + "A expression is built with a dynamic value. The source of the value(s) should be verified to + avoid that unfiltered values fall into this risky code evaluation." metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + cwe: CWE-917 + security-severity: MEDIUM + shortDescription: Expression injection (OGNL) + technology: + - kotlin + patterns: + - pattern-either: + - pattern-inside: | + fun $FUNC(..., $VAR: String, ...) { + ... + } + - pattern-inside: | + fun $FUNC(..., $VAR: Map<$K,$V>, ...) { + ... + } + - pattern-inside: | + fun $FUNC(..., $VAR: Map<$K,*>, ...) { + ... + } + - pattern-inside: | + fun $FUNC(..., $VAR: java.util.HashMap<$K,$V>, ...) { + ... + } + - pattern-either: + - pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariables(...,$VAR, ...) + - pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariablesCollection(..., $VAR, ...) + - pattern: com.opensymphony.xwork2.util.TextParseUtil.shallBeIncluded(..., $VAR, ...) + - pattern: com.opensymphony.xwork2.util.TextParseUtil.commaDelimitedStringToSet(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.TextParser).evaluate(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.OgnlTextParser).evaluate(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getGetMethod(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getSetMethod(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getField(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setProperties(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setProperty(...,$VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getValue(...,$VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setValue(...,$VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getGetMethod(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getSetMethod(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getField(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setProperties(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setProperty(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getValue(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setValue(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setProperties(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setProperty(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).getValue(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setValue(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).callMethod(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).compile(..., $VAR, ...) + - pattern: ($P:org.apache.struts2.util.VelocityStrutsUtil).evaluate(...) + - pattern: org.apache.struts2.util.StrutsUtil.findString(...) + - pattern: org.apache.struts2.util.StrutsUtil.findValue(..., $VAL) + - pattern: org.apache.struts2.util.StrutsUtil.getText(...) + - pattern: org.apache.struts2.util.StrutsUtil.translateVariables(...) + - pattern: org.apache.struts2.util.StrutsUtil.makeSelectList(..., $VAR, ...) + - pattern: ($T:org.apache.struts2.views.jsp.ui.OgnlTool).findValue(..., $VAR, ...) + - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).findString(...) + - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).findValue(..., $VAR, ...) + - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).setValue(..., $VAR, ...) + - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).setParameter(..., $VAR, ...) + severity: WARNING + - id: kotlin_inject_rule-SpotbugsPathTraversalAbsolute + languages: + - kotlin + message: | + The software uses an HTTP request parameter to construct a pathname that should be within a + restricted directory, but it does not properly neutralize absolute path sequences such as + "/abs/path" that can resolve to a location that is outside of that directory. See + http://cwe.mitre.org/data/definitions/36.html for more information. + metadata: + category: security + cwe: CWE-22 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://developer.mozilla.org/en-US/docs/Web/API/Document/writeln - - https://developer.mozilla.org/en-US/docs/Web/API/Document/write - - https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML - subcategory: - - vuln + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') technology: - - react + - kotlin mode: taint pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: - patterns: + - pattern-inside: | + $U = java.net.URI($VAR) - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) + - pattern-inside: java.io.File($U) + - pattern-inside: java.nio.file.Paths.get($U) + - pattern: $VAR - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) + - pattern-inside: java.io.RandomAccessFile($INPUT,...) + - pattern: $INPUT + - pattern: java.io.FileReader(...) + - pattern: javax.activation.FileDataSource(...) + - pattern: java.io.FileInputStream(...) + - pattern: java.io.File(...) + - pattern: java.nio.file.Paths.get(...) + - pattern: java.io.File.createTempFile(...) + - pattern: java.io.File.createTempDirectory(...) + - pattern: java.nio.file.Files.createTempFile(...) + - pattern: java.nio.file.Files.createTempDirectory(...) + - patterns: + - pattern: $SRC.$METHOD(...) + - metavariable-pattern: + metavariable: $SRC + pattern-either: + - pattern: getClass() + - pattern: getClass().getClassLoader() + - pattern: '($C: ClassLoader)' + - pattern: '($C: Class)' + - pattern: $CLZ.getClassLoader() + - metavariable-pattern: + metavariable: $METHOD + pattern-either: + - pattern: getResourceAsStream + - pattern: getResource - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; - ... - - pattern-inside: | - $S = require("sanitize-html") - ... - - pattern: $S(...) + - pattern-inside: java.io.FileWriter($PATH, ...) + - pattern: $PATH - patterns: - - pattern-either: - - pattern-inside: | - $S = new Remarkable() - ... - - pattern: $S.render(...) - pattern-sinks: + - pattern-inside: java.io.FileOutputStream($PATH, ...) + - pattern: $PATH + pattern-sources: + - pattern: '($REQ: HttpServletRequest).getParameter(...)' - patterns: + - pattern-inside: fun $FUNC(..., @RequestParam $REQ:$TYPE, ...) {...} + - focus-metavariable: $REQ + severity: WARNING + - id: kotlin_inject_rule-SqlInjection + languages: + - kotlin + message: | + The input values included in SQL queries need to be passed in safely. Bind + variables in prepared statements can be used to easily mitigate the risk of + SQL injection. + metadata: + category: security + cwe: CWE-89 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') + technology: + - java + mode: taint + options: + taint_assume_safe_functions: true + pattern-propagators: + - from: $SRC + pattern: $SB.append($SRC) + to: $SB + - from: $SRC + patterns: + - pattern: $F(..., $SRC, ...) + - focus-metavariable: $F - pattern-either: - - pattern: "this.window.document. ... .$HTML('...',$SINK) \n" - - pattern: "window.document. ... .$HTML('...',$SINK) \n" - - pattern: "document.$HTML($SINK) \n" - - metavariable-regex: - metavariable: $HTML - regex: (writeln|write) - - focus-metavariable: $SINK + - pattern: String.format + - pattern: StringBuilder + to: $F + pattern-sinks: - patterns: - pattern-either: - - pattern: "$PROP. ... .$HTML('...',$SINK) \n" - - metavariable-regex: - metavariable: $HTML - regex: (insertAdjacentHTML) - - focus-metavariable: $SINK + - pattern: '($PM: javax.jdo.PersistenceManager).newQuery($ARG)' + - pattern: '($PM: javax.jdo.PersistenceManager).newQuery(..., $ARG)' + - pattern: '($Q: javax.jdo.Query).setFilter($ARG)' + - pattern: '($Q: javax.jdo.Query).setGrouping($ARG)' + - pattern: org.hibernate.criterion.Restrictions.sqlRestriction($ARG, ...) + - pattern: '($S: org.hibernate.Session).createQuery($ARG, ...)' + - pattern: '($S: org.hibernate.Session).createSQLQuery($ARG, ...)' + - pattern: '($S: java.sql.Statement).executeQuery($ARG, ...)' + - pattern: '($S: java.sql.Statement).execute($ARG, ...)' + - pattern: '($S: java.sql.Statement).executeUpdate($ARG, ...)' + - pattern: '($S: java.sql.Statement).executeLargeUpdate($ARG, ...)' + - pattern: '($S: java.sql.Statement).addBatch($ARG, ...)' + - pattern: '($S: java.sql.PreparedStatement).executeQuery($ARG, ...)' + - pattern: '($S: java.sql.PreparedStatement).execute($ARG, ...)' + - pattern: '($S: java.sql.PreparedStatement).executeUpdate($ARG, ...)' + - pattern: '($S: java.sql.PreparedStatement).executeLargeUpdate($ARG, ...)' + - pattern: '($S: java.sql.PreparedStatement).addBatch($ARG, ...)' + - pattern: '($S: java.sql.Connection).prepareCall($ARG, ...)' + - pattern: '($S: java.sql.Connection).prepareStatement($ARG, ...)' + - pattern: '($S: java.sql.Connection).nativeSQL($ARG, ...)' + - pattern: org.springframework.jdbc.core.PreparedStatementCreatorFactory($ARG, ...) + - pattern: '($F: org.springframework.jdbc.core.PreparedStatementCreatorFactory).newPreparedStatementCreator($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).batchUpdate($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).execute($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).query($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForList($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForMap($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForRowSet($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForInt($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForLong($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).update($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).batchUpdate($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).execute($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).query($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForList($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForMap($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForObject($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForRowSet($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForInt($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForLong($ARG, ...)' + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).update($ARG, ...)' + - pattern: '($O: io.vertx.sqlclient.SqlClient).query($ARG, ...)' + - pattern: '($O: io.vertx.sqlclient.SqlClient).preparedQuery($ARG, ...)' + - pattern: '($O: io.vertx.sqlclient.SqlConnection).prepare($ARG, ...)' + - pattern: '($O: org.apache.turbine.om.peer.BasePeer).executeQuery($ARG, ...)' + - pattern: '($O: org.apache.torque.util.BasePeer).executeQuery($ARG, ...)' + - pattern: '($O: javax.persistence.EntityManager).createQuery($ARG, ...)' + - pattern: '($O: javax.persistence.EntityManager).createNativeQuery($ARG, ...)' + - pattern: '($H: org.jdbi.v3.core.Handle).createQuery($ARG, ...)' + - pattern: '($H: org.jdbi.v3.core.Handle).createScript($ARG, ...)' + - pattern: '($H: org.jdbi.v3.core.Handle).createUpdate($ARG, ...)' + - pattern: '($H: org.jdbi.v3.core.Handle).execute($ARG, ...)' + - pattern: '($H: org.jdbi.v3.core.Handle).prepareBatch($ARG, ...)' + - pattern: '($H: org.jdbi.v3.core.Handle).select($ARG, ...)' + - pattern: org.jdbi.v3.core.statement.Script($H, $ARG) + - pattern: org.jdbi.v3.core.statement.Update($H, $ARG) + - pattern: org.jdbi.v3.core.statement.PreparedBatch($H, $ARG) + - focus-metavariable: $ARG pattern-sources: - patterns: - - pattern-either: - - pattern-inside: | - function ...({..., $X, ...}) { ... } - - pattern-inside: | - function ...(..., $X, ...) { ... } - - focus-metavariable: $X - - pattern-either: - - pattern: $X.$Y - - pattern: $X[...] + - pattern-inside: 'fun $FUNC(..., $SRC: String, ...) { ... }' + - pattern: $SRC + severity: ERROR + - id: kotlin_ldap_rule-AnonymousLDAP + languages: + - kotlin + message: | + Without proper access control, executing an LDAP statement that contains a + user-controlled value can allow an attacker to abuse poorly configured LDAP + context + metadata: + category: security + cwe: CWE-306 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: MEDIUM + shortDescription: Missing authentication for critical function (LDAP) + patterns: + - pattern-inside: | + import javax.naming.Context + ... + - pattern: $ENV[Context.SECURITY_AUTHENTICATION] = "none" severity: WARNING - - id: typescript.react.security.audit.react-unsanitized-property.react-unsanitized-property + - id: kotlin_password_rule-ConstantDBPassword languages: - - typescript - - javascript - message: Detection of $HTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use $HTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. + - kotlin + message: | + A potential hard-coded password was identified in a database connection string. + Passwords should not be stored directly in code + but loaded from secure locations such as a Key Management System (KMS). + + The purpose of using a Key Management System is so access can be audited and keys easily + rotated + in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine + when or if, a key is compromised. + + The recommendation on which KMS to use depends on the environment the application is running + in: + + - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) + - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) + - For on premise or other alternatives to cloud providers, consider [Hashicorp's + Vault](https://www.vaultproject.io/) + - For other cloud providers, please see their documentation metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: CWE-259 owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html - subcategory: - - vuln + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: Critical + shortDescription: Use of hard-coded password technology: - - react - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... + - kotlin + pattern: java.sql.DriverManager.getConnection($URI, $USR, "...") + severity: ERROR + - id: kotlin_password_rule-EmptyDBPassword + languages: + - kotlin + message: | + The application does not provide authentication when communicating a database + server. It is strongly recommended that the database server be configured with + authentication and restrict what queries users can execute. + + Please see your database server's documentation on how to configure a password. + + Additionally, passwords should not be stored directly in code + but loaded from secure locations such as a Key Management System (KMS). + + The purpose of using a Key Management System is so access can be audited and keys easily + rotated + in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine + when or if, a key is compromised. + + The recommendation on which KMS to use depends on the environment the application is running + in: + + - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) + - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) + - For on premise or other alternatives to cloud providers, consider [Hashicorp's + Vault](https://www.vaultproject.io/) + - For other cloud providers, please see their documentation + metadata: + category: security + cwe: CWE-306 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: Critical + shortDescription: Missing authentication for critical function (database) + technology: + - kotlin + pattern: java.sql.DriverManager.getConnection($URI, $USR, ""); + severity: ERROR + - id: kotlin_perm_rule-DangerousPermissions + languages: + - kotlin + message: | + Do not grant dangerous combinations of permissions. + metadata: + category: security + confidence: HIGH + cwe: CWE-277 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Insecure inherited permissions + patterns: + - pattern-either: + - patterns: - pattern-inside: | - $S = require("underscore.string") + $PC = $X.getPermissions(...) ... - - pattern-either: - - pattern: $S.escapeHTML(...) + - pattern: $PC.add($PERMISSION) + - pattern: | + $REFVAR = $PERMISSION + ...; + ($PC: PermissionCollection).add($REFVAR) + - pattern: '($PC: PermissionCollection).add($PERMISSION)' + - metavariable-pattern: + metavariable: $PERMISSION + pattern-either: + - pattern: ReflectPermission("suppressAccessChecks") + - pattern: RuntimePermission("createClassLoader") + severity: WARNING + - id: kotlin_perm_rule-OverlyPermissiveFilePermissionInline + languages: + - kotlin + message: | + Overly permissive file permission + metadata: + category: security + confidence: HIGH + cwe: CWE-732 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Incorrect permission assignment for critical resource + patterns: + - pattern-either: + - pattern: java.nio.file.Files.setPosixFilePermissions(..., java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING")); + - pattern: | + $PERMISSIONS = java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING"); + ... + java.nio.file.Files.setPosixFilePermissions(..., $PERMISSIONS); + - metavariable-regex: + metavariable: $PERM_STRING + regex: '[rwx-]{6}[rwx]{1,}' + severity: WARNING + - id: kotlin_script_rule-ScriptInjection + languages: + - kotlin + message: | + The software constructs all or part of a code segment using externally-influenced + input from an upstream component, but it does not neutralize or incorrectly + neutralizes special elements that could modify the syntax or behavior of the + intended code segment. + metadata: + category: security + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code ('Code Injection') + mode: taint + pattern-sinks: - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... + - patterns: - pattern-inside: | - $S = require("isomorphic-dompurify") + $ENGINE = $F.getEngineByExtension(...) ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) + - pattern: $ENGINE.eval($ARG, ...); + - pattern-not: $ENGINE.eval("..."); + - pattern-not: '$ENGINE.eval("...", ($BINDING: javax.script.Bindings));' + - patterns: + - pattern: '($ENGINE: javax.script.ScriptEngine).eval($ARG, ...);' + - pattern-not: '($ENGINE: javax.script.ScriptEngine).eval("...");' + - pattern-not: '($ENGINE: javax.script.ScriptEngine).eval("...", ($BINDING: javax.script.Bindings));' + - pattern: '($INVC: javax.script.Invocable).invokeFunction(..., $ARG)' + - pattern: '($INVC: javax.script.Invocable).invokeMethod(..., $ARG)' + pattern-sources: - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) + - pattern-inside: 'fun $FUNC(..., $VAR: String, ...) { ... }' + - pattern: $VAR + severity: ERROR + - id: kotlin_smtp_rule-InsecureSmtp + languages: + - kotlin + message: | + Server identity verification is disabled when making SSL connections. + metadata: + category: security + cwe: CWE-297 + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: CRITICAL + shortDescription: Improper validation of certificate with host mismatch + patterns: + - pattern-either: + - pattern-inside: | + $E = org.apache.commons.mail.SimpleEmail(...) + ... + - pattern-inside: | + $E = org.apache.commons.mail.Email(...) + ... + - pattern-inside: | + $E = org.apache.commons.mail.MultiPartEmail(...) + ... + - pattern-inside: | + $E = org.apache.commons.mail.HtmlEmail(...) + ... + - pattern-inside: | + $E = org.apache.commons.mail.ImageHtmlEmail(...) + ... + - pattern-not: | + $E.setSSLOnConnect(true) + ... + $E.setSSLCheckServerIdentity(true) + severity: ERROR + - id: kotlin_smtp_rule-SmtpClient + languages: + - kotlin + message: | + Simple Mail Transfer Protocol (SMTP) is a the text based protocol used for + email delivery. Like with HTTP, headers are separate by new line separator. If + kuser input is place in a header line, the application should remove or replace + new line characters (CR / LF). You should use a safe wrapper such as Apache + Common Email and Simple Java Mail which filter special characters that can lead + to header injection. + metadata: + category: security + cwe: CWE-77 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of special elements used in a command + patterns: + - pattern-inside: | + $M = MimeMessage(...); + ... + - pattern-either: + - patterns: + - pattern-either: + - pattern: $M.setSubject($VAR) + - pattern: $M.addHeader($ARG, $VAR) + - pattern: $M.addHeader($VAR, $ARG) + - pattern: $M.setDescription($VAR) + - pattern: $M.setDisposition($VAR) + - metavariable-regex: + metavariable: $VAR + regex: ^[a-zA-Z_$][a-zA-Z0-9_$]*$ + - patterns: + - pattern-either: + - pattern: $M.setSubject($OBJ.$GETTER(...)) + - pattern: $M.setSubject($OBJ.$GETTER(...) + ...) + - pattern: $M.setSubject(... + $OBJ.$GETTER(...)) + - pattern: $M.setSubject(... + $OBJ.$GETTER(...) + ...) + - pattern: $M.addHeader($ARG, $OBJ.$GETTER(...)) + - pattern: $M.addHeader($ARG, $OBJ.$GETTER(...) + ...) + - pattern: $M.addHeader($ARG, ... + $OBJ.$GETTER(...)) + - pattern: $M.addHeader($ARG, ... + $OBJ.$GETTER(...) + ...) + - pattern: $M.addHeader($OBJ.$GETTER(...), $ARG) + - pattern: $M.addHeader($OBJ.$GETTER(...) + ..., $ARG) + - pattern: $M.addHeader(... + $OBJ.$GETTER(...), $ARG) + - pattern: $M.addHeader(... + $OBJ.$GETTER(...) + ..., $ARG) + - pattern: $M.setDescription($OBJ.$GETTER(...)) + - pattern: $M.setDisposition($OBJ.$GETTER(...) + ...) + - pattern: $M.setDisposition(... + $OBJ.$GETTER(...)) + - pattern: $M.setDisposition(... + $OBJ.$GETTER(...) + ...) + - metavariable-regex: + metavariable: $GETTER + regex: ^get + severity: ERROR + - id: kotlin_ssrf_rule-SSRF + languages: + - kotlin + message: | + Server-Side Request Forgery occur when a web server executes a request to a user supplied + destination parameter that is not validated. Such vulnerabilities could allow an attacker to + access internal services or to launch attacks from your web server. + metadata: + category: security + cwe: CWE-918 + owasp: + - A1:2017-Injection + - A10:2021-Server-Side Request Forgery + security-severity: CRITICAL + shortDescription: Server-Side Request Forgery (SSRF) + pattern-either: - patterns: - pattern-either: - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; + import java.net.*; ... - pattern-inside: | - $S = require("sanitize-html") + import java.net.URL; ... - - pattern: $S(...) - - patterns: - - pattern-either: - pattern-inside: | - $S = new Remarkable() + import java.net.URI; ... - - pattern: $S.render(...) - pattern-sinks: + - pattern: $TYPE(...). ... .$FUNC + - pattern-not: $TYPE("..."). ... .$FUNC + - metavariable-pattern: + metavariable: $FUNC + pattern-either: + - pattern: connect + - pattern: GetContent + - pattern: openConnection + - pattern: openStream + - pattern: getContent + - pattern: content + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: URL + - pattern: java.net.URL + - pattern: URI + - pattern: java.net.URI - patterns: - pattern-either: - pattern-inside: | - $BODY = $REACT.useRef(...) - ... - - pattern-inside: | - $BODY = useRef(...) - ... - - pattern-inside: | - $BODY = findDOMNode(...) - ... - - pattern-inside: | - $BODY = createRef(...) - ... - - pattern-inside: | - $BODY = $REACT.findDOMNode(...) + import java.net.*; ... - pattern-inside: | - $BODY = $REACT.createRef(...) + import java.net.InetSocketAddress; ... - - pattern-either: - - pattern: "$BODY. ... .$HTML = $SINK \n" - - pattern: "$BODY.$HTML = $SINK \n" - - metavariable-regex: - metavariable: $HTML - regex: (innerHTML|outerHTML) - - focus-metavariable: $SINK - - patterns: - - pattern-either: - - pattern: ReactDOM.findDOMNode(...).$HTML = $SINK - - metavariable-regex: - metavariable: $HTML - regex: (innerHTML|outerHTML) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - function ...({..., $X, ...}) { ... } - - pattern-inside: | - function ...(..., $X, ...) { ... } - - focus-metavariable: $X - - pattern-either: - - pattern: $X.$Y - - pattern: $X[...] + - pattern: | + InetSocketAddress(..., $PORT) + - pattern-not: | + InetSocketAddress("...", $PORT) + severity: ERROR + - id: kotlin_strings_rule-BadHexConversion + languages: + - kotlin + message: | + When converting a byte array containing a hash signature to a human readable string, a + conversion mistake can be made if the array is read byte by byte. + metadata: + category: security + confidence: HIGH + cwe: CWE-704 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Incorrect type conversion or cast + patterns: + - pattern-inside: | + $B_ARR = ($MD: java.security.MessageDigest).digest(...); + ... + - pattern-either: + - pattern: | + for($B in $B_ARR) { + ... + $B_TOSTR + } + - pattern: | + while(...) { + ... + $B_TOSTR + } + - pattern: | + do { + ... + $B_TOSTR + } while(...) + - metavariable-pattern: + metavariable: $B_TOSTR + patterns: + - pattern-either: + - pattern: java.lang.Integer.toHexString($B_TOINT) + - pattern: Integer.toHexString($B_TOINT) + - pattern: $B_TOINT.toHexString(...) + - metavariable-pattern: + metavariable: $B_TOINT + pattern-either: + - pattern: $B_ARR[...].toInt() + - pattern: $B_ARR[...] + - pattern: $B.toInt() + - pattern: $B severity: WARNING - - id: typescript.react.security.react-insecure-request.react-insecure-request + - id: kotlin_strings_rule-FormatStringManipulation languages: - - typescript - - javascript - message: Unencrypted request over HTTP detected. + - kotlin + message: | + Allowing user input to control format parameters could enable an attacker to cause exceptions + to be thrown or leak information.Attackers may be able to modify the format string argument, + such that an exception is thrown. If this exception is left uncaught, it may crash the + application. Alternatively, if sensitive information is used within the unused arguments, + attackers may change the format string to reveal this information. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: LOW + confidence: HIGH + cwe: CWE-134 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.npmjs.com/package/axios - subcategory: - - vuln - technology: - - react - vulnerability: Insecure Transport - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - import $AXIOS from 'axios'; - ... - $AXIOS.$METHOD(...) + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Use of externally-controlled format string + patterns: + - pattern-either: + - patterns: - pattern-inside: | - $AXIOS = require('axios'); - ... - $AXIOS.$METHOD(...) - - pattern-either: - - pattern: $AXIOS.get("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.post("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.delete("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.head("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.patch("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.put("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.options("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - patterns: - - pattern-either: + $INPUT = ($REQ: HttpServletRequest).getParameter(...) + ... - pattern-inside: | - import $AXIOS from 'axios'; + $FORMAT_STR = ... + $INPUT ... - $AXIOS(...) + - patterns: - pattern-inside: | - $AXIOS = require('axios'); + $INPUT = ($REQ: HttpServletRequest).getParameter(...) ... - $AXIOS(...) - - pattern-either: - - pattern: '$AXIOS({url: "=~/[Hh][Tt][Tt][Pp]:\/\/.*/"}, ...)' - - pattern: | - $OPTS = {url: "=~/[Hh][Tt][Tt][Pp]:\/\/.*/"} + - pattern-inside: | + $FORMAT_STR = ... + $INPUT + ... ... - $AXIOS($OPTS, ...) - - pattern: fetch("=~/[Hh][Tt][Tt][Pp]:\/\/.*/", ...) + - pattern-inside: | + $FORMAT_STR = ... + ($REQ: HttpServletRequest).getParameter(...) + ... + ... + - pattern-inside: | + $FORMAT_STR = ... + ($REQ: HttpServletRequest).getParameter(...) + ... + - pattern-either: + - pattern: String.format($FORMAT_STR, ...) + - pattern: String.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) + - patterns: + - pattern-inside: | + $F = java.util.Formatter(...) + ... + - pattern-either: + - pattern: $F.format($FORMAT_STR, ...) + - pattern: $F.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) + - pattern: '($F: java.io.PrintStream).printf($FORMAT_STR, ...)' + - pattern: '($F: java.io.PrintStream).printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...)' + - pattern: '($F: java.io.PrintStream).format($FORMAT_STR, ...)' + - pattern: '($F: java.io.PrintStream).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...)' + - pattern: System.out.printf($FORMAT_STR, ...) + - pattern: System.out.printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...) + - pattern: System.out.format($FORMAT_STR, ...) + - pattern: System.out.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) severity: ERROR - - id: yaml.argo.security.argo-workflow-parameter-command-injection.argo-workflow-parameter-command-injection + - id: kotlin_strings_rule-ModifyAfterValidation languages: - - yaml - message: Using input or workflow parameters in here-scripts can lead to command injection or code injection. Convert the parameters to env variables instead. + - kotlin + message: | + CERT: IDS11-J. Perform any string modifications before validation metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - impact: HIGH - likelihood: MEDIUM + confidence: HIGH + cwe: CWE-182 owasp: - - A03:2021 – Injection - references: - - https://github.com/argoproj/argo-workflows/issues/5061 - - https://github.com/argoproj/argo-workflows/issues/5114#issue-808865370 - subcategory: - - vuln - technology: - - ci - - argo + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Collapse of data into unsafe value patterns: - pattern-inside: | - apiVersion: $VERSION + $PATTERN = Pattern.compile(...) + ... + - pattern-inside: | + $PATTERN.matcher($VAR) ... - - metavariable-regex: - metavariable: $VERSION - regex: (argoproj.io.*) - pattern-either: + - pattern: | + $VAR + $OTHER - patterns: - - pattern-inside: "command:\n ...\n - python\n ...\n...\nsource: \n $SCRIPT\n" - - focus-metavariable: $SCRIPT - - metavariable-pattern: - language: python - metavariable: $SCRIPT - patterns: - - pattern: | - $FUNC(..., $PARAM, ...) - - metavariable-pattern: - metavariable: $PARAM - pattern-either: - - pattern-regex: (.*{{.*inputs.parameters.*}}.*) - - pattern-regex: (.*{{.*workflow.parameters.*}}.*) - - patterns: - - pattern-inside: "command:\n ...\n - $LANG\n ...\n...\nsource: \n $SCRIPT\n" - - metavariable-regex: - metavariable: $LANG - regex: (bash|sh) - - focus-metavariable: $SCRIPT - - metavariable-pattern: - language: bash - metavariable: $SCRIPT - patterns: - - pattern: | - $CMD ... $PARAM ... - - metavariable-pattern: - metavariable: $PARAM - pattern-either: - - pattern-regex: (.*{{.*inputs.parameters.*}}.*) - - pattern-regex: (.*{{.*workflow.parameters.*}}.*) - - patterns: - - pattern-inside: | - container: - ... - command: $LANG - ... - args: $PARAM + - pattern: | + $VAR.$METHOD(...) - metavariable-regex: - metavariable: $LANG - regex: .*(sh|bash|ksh|csh|tcsh|zsh).* - - metavariable-pattern: - metavariable: $PARAM - pattern-either: - - pattern-regex: (.*{{.*inputs.parameters.*}}.*) - - pattern-regex: (.*{{.*workflow.parameters.*}}.*) - - focus-metavariable: $PARAM - severity: ERROR - - fix: | - false - id: yaml.docker-compose.security.privileged-service.privileged-service + metavariable: $METHOD + regex: (replace|replaceAll|replaceFirst|concat) + severity: WARNING + - id: kotlin_strings_rule-NormalizeAfterValidation languages: - - yaml - message: Service '$SERVICE' is running in privileged mode. This grants the container the equivalent of root capabilities on the host machine. This can lead to container escapes, privilege escalation, and other security concerns. Remove the 'privileged' key to disable this capability. + - kotlin + message: | + IDS01-J. Normalize strings before validating them metadata: category: security confidence: HIGH - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH + cwe: CWE-180 owasp: - - A06:2017 - Security Misconfiguration - - A05:2021 - Security Misconfiguration - references: - - https://www.trendmicro.com/en_us/research/19/l/why-running-a-privileged-container-in-docker-is-a-bad-idea.html - - https://containerjournal.com/topics/container-security/why-running-a-privileged-container-is-not-a-good-idea/ - subcategory: - - vuln - technology: - - docker-compose + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: 'Incorrect behavior order: validate before canonicalize' patterns: - - pattern-inside: | - version: ... + - pattern: | + $Y = java.util.regex.Pattern.compile("[<>]"); ... - services: - ... - $SERVICE: - ... - privileged: $TRUE - - focus-metavariable: $TRUE - - metavariable-regex: - metavariable: $TRUE - regex: (true) + $Y.matcher($VAR); + ... + java.text.Normalizer.normalize($VAR, ...); severity: WARNING - - id: yaml.github-actions.security.allowed-unsecure-commands.allowed-unsecure-commands + - id: kotlin_templateinjection_rule-TemplateInjection languages: - - yaml - message: The environment variable `ACTIONS_ALLOW_UNSECURE_COMMANDS` grants this workflow permissions to use the `set-env` and `add-path` commands. There is a vulnerability in these commands that could result in environment variables being modified by an attacker. Depending on the use of the environment variable, this could enable an attacker to, at worst, modify the system path to run a different command than intended, resulting in arbitrary code execution. This could result in stolen code or secrets. Don't use `ACTIONS_ALLOW_UNSECURE_COMMANDS`. Instead, use Environment Files. See https://github.com/actions/toolkit/blob/main/docs/commands.md#environment-files for more information. + - kotlin + message: | + A malicious user in control of a template can run malicious code on the + server-side. Velocity templates should be seen as scripts. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-749: Exposed Dangerous Method or Function' - impact: MEDIUM - likelihood: LOW - owasp: A06:2017 - Security Misconfiguration - references: - - https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/ - - https://github.com/actions/toolkit/security/advisories/GHSA-mfwh-5m23-j46w - - https://github.com/actions/toolkit/blob/main/docs/commands.md#environment-files - subcategory: - - vuln + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper control of generation of code ('Code Injection') + pattern-either: + - patterns: + - pattern: org.apache.velocity.app.Velocity.evaluate(..., $VAR) + - pattern-not: org.apache.velocity.app.Velocity.evaluate(..., "...") + - patterns: + - pattern-not-inside: | + $C = ($CFG: freemarker.template.Configuration).getTemplate("..."); + ... + - pattern-inside: | + $C = ($CFG: freemarker.template.Configuration).getTemplate($IN); + ... + - pattern: $C.process(...) + - patterns: + - pattern-inside: | + import com.mitchellbosecke.pebble.PebbleEngine; + ... + - pattern-inside: | + $C = $T.getTemplate($IN); + ... + - pattern-not-inside: | + $C = $T.getTemplate("..."); + ... + - pattern: $C.evaluate(...) + severity: ERROR + - id: kotlin_unsafe_rule-ExternalConfigControl + languages: + - kotlin + message: | + Allowing external control of system settings can disrupt service or cause an application to + behave in unexpected, and potentially malicious ways. An attacker could cause an error by + providing a nonexistent catalog name or connect to an unauthorized portion of the database. + metadata: + category: security + cwe: CWE-15 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: External control of system or configuration setting technology: - - github-actions + - kotlin patterns: - - pattern-either: - - patterns: - - pattern-inside: '{env: ...}' - - pattern: 'ACTIONS_ALLOW_UNSECURE_COMMANDS: true' + - metavariable-pattern: + metavariable: $GET_PARAMETER + pattern-either: + - pattern: '($REQ: HttpServletRequest).getParameter' + - pattern: '($REQ: HttpServletRequest?)?.getParameter' + - metavariable-pattern: + metavariable: $SET_CATALOG + pattern-either: + - pattern: '($CONN: java.sql.Connection).setCatalog' + - pattern: '($CONN: java.sql.Connection?)?.setCatalog' + - pattern: |- + $TAINTED = $GET_PARAMETER(...) + ... + $SET_CATALOG($TAINTED) severity: WARNING - - id: yaml.github-actions.security.github-script-injection.github-script-injection + - id: rules_lgpl_kotlin_other_rule-android-kotlin-webview-debug languages: - - yaml - message: 'Using variable interpolation `${{...}}` with `github` context data in a `actions/github-script`''s `script:` step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. `github` context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with `env:` to store the data and use the environment variable in the `run:` script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".' + - kotlin + message: "Remote WebView debugging is enabled.This can introduce security \nrisks as it allows remote debugging tools, such as Chrome DevTools, \nto inspect and manipulate the WebView content. This can potentially \nexpose sensitive information, including user data, session tokens, \nand other confidential data, to unauthorized parties.\n\nTo fix this security issue, you should disable remote WebView \ndebugging in production builds of your app. Here's how you can do it:\n```\nimport WebKit\n\nclass ViewController: UIViewController {\n\n override func viewDidLoad() {\n super.viewDidLoad()\n\n // Disable remote WebView debugging in production builds\n #if DEBUG\n WebViewConfiguration.shared().preferences.setValue(true, forKey: \"developerExtrasEnabled\")\n #else\n WebViewConfiguration.shared().preferences.setValue(false, forKey: \"developerExtrasEnabled\")\n #endif\n\n // Other setup code...\n }\n\n // Other methods...\n}\n```\n" metadata: category: security - confidence: HIGH - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: HIGH + cwe: CWE-489 owasp: - - A03:2021 - Injection - references: - - https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections - - https://securitylab.github.com/research/github-actions-untrusted-input/ - - https://github.com/actions/github-script - subcategory: - - vuln - technology: - - github-actions + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Leftover debug code patterns: - - pattern-inside: 'steps: [...]' + - pattern: | + $X.setWebContentsDebuggingEnabled(true) - pattern-inside: | - uses: $ACTION + WebView ... - - pattern-inside: | - with: - ... - script: ... - ... - - pattern: 'script: $SHELL' - - metavariable-regex: - metavariable: $ACTION - regex: actions/github-script@.* - - metavariable-pattern: - language: generic - metavariable: $SHELL - patterns: - - pattern-either: - - pattern: ${{ github.event.issue.title }} - - pattern: ${{ github.event.issue.body }} - - pattern: ${{ github.event.pull_request.title }} - - pattern: ${{ github.event.pull_request.body }} - - pattern: ${{ github.event.comment.body }} - - pattern: ${{ github.event.review.body }} - - pattern: ${{ github.event.review_comment.body }} - - pattern: ${{ github.event.pages. ... .page_name}} - - pattern: ${{ github.event.head_commit.message }} - - pattern: ${{ github.event.head_commit.author.email }} - - pattern: ${{ github.event.head_commit.author.name }} - - pattern: ${{ github.event.commits ... .author.email }} - - pattern: ${{ github.event.commits ... .author.name }} - - pattern: ${{ github.event.pull_request.head.ref }} - - pattern: ${{ github.event.pull_request.head.label }} - - pattern: ${{ github.event.pull_request.head.repo.default_branch }} - - pattern: ${{ github.head_ref }} - - pattern: ${{ github.event.inputs ... }} - severity: ERROR - - id: yaml.github-actions.security.run-shell-injection.run-shell-injection + severity: WARNING + - id: kotlin_xml_rule-SAMLIgnoreComments languages: - - yaml - message: 'Using variable interpolation `${{...}}` with `github` context data in a `run:` step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. `github` context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with `env:` to store the data and use the environment variable in the `run:` script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".' + - kotlin + message: | + Ignoring XML comments in SAML may lead to authentication bypass metadata: category: security - confidence: HIGH - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: HIGH + cwe: CWE-1390 owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections - - https://securitylab.github.com/research/github-actions-untrusted-input/ - subcategory: - - vuln - technology: - - github-actions - patterns: - - pattern-inside: 'steps: [...]' - - pattern-inside: | - - run: ... - ... - - pattern: 'run: $SHELL' - - metavariable-pattern: - language: generic - metavariable: $SHELL - patterns: - - pattern-either: - - pattern: ${{ github.event.issue.title }} - - pattern: ${{ github.event.issue.body }} - - pattern: ${{ github.event.pull_request.title }} - - pattern: ${{ github.event.pull_request.body }} - - pattern: ${{ github.event.comment.body }} - - pattern: ${{ github.event.review.body }} - - pattern: ${{ github.event.review_comment.body }} - - pattern: ${{ github.event.pages. ... .page_name}} - - pattern: ${{ github.event.head_commit.message }} - - pattern: ${{ github.event.head_commit.author.email }} - - pattern: ${{ github.event.head_commit.author.name }} - - pattern: ${{ github.event.commits ... .author.email }} - - pattern: ${{ github.event.commits ... .author.name }} - - pattern: ${{ github.event.pull_request.head.ref }} - - pattern: ${{ github.event.pull_request.head.label }} - - pattern: ${{ github.event.pull_request.head.repo.default_branch }} - - pattern: ${{ github.head_ref }} - - pattern: ${{ github.event.inputs ... }} - severity: ERROR - - id: yaml.github-actions.security.third-party-action-not-pinned-to-commit-sha.third-party-action-not-pinned-to-commit-sha + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: MEDIUM + shortDescription: Weak authentication + pattern: '($POOL: org.opensaml.xml.parse.BasicParserPool).setIgnoreComments(false);' + severity: WARNING + - id: kotlin_xml_rule-XmlDecoder languages: - - yaml - message: An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. + - kotlin + message: | + Avoid using XMLDecoder to parse content from an untrusted source. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-1357: Reliance on Insufficiently Trustworthy Component' - - 'CWE-353: Missing Support for Integrity Check' - impact: LOW - likelihood: LOW - owasp: A06:2021 - Vulnerable and Outdated Components - references: - - https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components - - https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions - subcategory: - - vuln - technology: - - github-actions + cwe: CWE-502 + owasp: + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + security-severity: MEDIUM + shortDescription: Deserialization of untrusted data patterns: - - pattern-inside: '{steps: ...}' - - pattern: | - uses: "$USES" - - metavariable-pattern: - language: generic - metavariable: $USES - patterns: - - pattern-not-regex: ^[.]/ - - pattern-not-regex: ^actions/ - - pattern-not-regex: ^github/ - - pattern-not-regex: '@[0-9a-f]{40}$' - - pattern-not-regex: ^docker://.*@sha256:[0-9a-f]{64}$ + - pattern-either: + - pattern: '($D: java.beans.XMLDecoder).readObject()' + - patterns: + - pattern: $D.readObject() + - pattern-inside: | + $D = XMLDecoder(...) + ... + - pattern-not: + pattern-either: + - patterns: + - pattern-inside: | + $DEC = java.beans.XMLDecoder(..., $CL) + ... + - pattern: $DEC.readObject() + - metavariable-pattern: + metavariable: $CL + patterns: + - pattern: | + object : ClassLoader() { + ... + fun loadClass(name: String, resolve: Boolean): $RET { + if($X){ + throw ... + } + ... + } + ... + } + - metavariable-pattern: + metavariable: $X + pattern-either: + - pattern: | + name != ... + - pattern: | + !$LIST.contains(name) + - patterns: + - pattern-inside: | + $CLASS_LOADER = $CL + ... + - pattern-inside: | + $DEC = java.beans.XMLDecoder(..., $CLASS_LOADER) + ... + - pattern: $DEC.readObject() + - metavariable-pattern: + metavariable: $CL + patterns: + - pattern: | + object : ClassLoader(){ + ... + fun loadClass(name: String, resolve: Boolean): $RET{ + if($X){ + throw ... + } + ... + } + ... + } + - metavariable-pattern: + metavariable: $X + pattern-either: + - pattern: | + name != ... + - pattern: | + !$LIST.contains(name) severity: WARNING - - id: yaml.github-actions.security.workflow-run-target-code-checkout.workflow-run-target-code-checkout + - id: kotlin_xml_rule-XsltTransform languages: - - yaml - message: This GitHub Actions workflow file uses `workflow_run` and checks out code from the incoming pull request. When using `workflow_run`, the Action runs in the context of the target repository, which includes access to all repository secrets. Normally, this is safe because the Action only runs code from the target repository, not the incoming PR. However, by checking out the incoming PR code, you're now using the incoming code for the rest of the action. You may be inadvertently executing arbitrary code from the incoming PR with access to repository secrets, which would let an attacker steal repository secrets. This normally happens by running build scripts (e.g., `npm build` and `make`) or dependency installation scripts (e.g., `python setup.py install`). Audit your workflow file to make sure no code from the incoming PR is executed. Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations. + - kotlin + message: | + It is possible to attach malicious behavior to those style sheets. Therefore, if an attacker + can control the content or the source of the style sheet, he might be able to trigger remote + code execution. metadata: category: security - confidence: MEDIUM - cwe: 'CWE-913: Improper Control of Dynamically-Managed Code Resources' - impact: MEDIUM - likelihood: MEDIUM - owasp: A01:2017 - Injection - references: - - https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ - - https://github.com/justinsteven/advisories/blob/master/2021_github_actions_checkspelling_token_leak_via_advice_symlink.md - - https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability - subcategory: - - vuln - technology: - - github-actions - patterns: - - pattern-inside: | - on: - ... - workflow_run: ... - ... - ... - - pattern-inside: | - jobs: - ... - $JOBNAME: - ... - steps: - ... - - pattern: | - ... - uses: "$ACTION" - with: - ... - ref: $EXPR - - metavariable-regex: - metavariable: $ACTION - regex: actions/checkout@.* - - metavariable-pattern: - language: generic - metavariable: $EXPR - patterns: - - pattern: ${{ github.event.workflow_run ... }} + cwe: CWE-91 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: XML injection (aka Blind XPath injection) + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: '($T: javax.xml.transform.TransformerFactory).newTransformer($SRC, ...)' + - pattern-inside: '($T: javax.xml.transform.Transformer).transform($SRC, ...)' + - patterns: + - pattern-inside: |- + $FACTORY = javax.xml.transform.TransformerFactory.newInstance(...) + ... + - pattern-inside: $FACTORY.newTransformer($SRC, ...) + - patterns: + - pattern-inside: |- + $FACTORY = javax.xml.transform.TransformerFactory(...) + ... + - pattern-inside: |- + $T = $FACTORY.newTransformer(...) + ... + - pattern-inside: $T.transform($SRC, ...) + - pattern: $SRC + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + fun $FUNC(...,$VAR: String, ...) { + ... + } + - pattern-either: + - pattern: FileInputStream(<... $VAR ...>); + - pattern: javaClass.getResourceAsStream(<... $VAR ...>) + - patterns: + - pattern-inside: | + class $CLZ { + var $X = "..."; + ... + } + - pattern-inside: | + fun $FUNC(...,$Y: String, ...) { + ... + } + - pattern-either: + - pattern: FileInputStream($X + $Y); + - pattern: javaClass.getResourceAsStream($X + $Y) severity: WARNING - - fix: | - securityContext: - allowPrivilegeEscalation: false - $NAME - id: yaml.kubernetes.security.allow-privilege-escalation-no-securitycontext.allow-privilege-escalation-no-securitycontext + - id: kotlin_xpathi_rule-XpathInjection + languages: + - kotlin + message: | + The input values included in SQL queries need to be passed in safely. Bind + variables in prepared statements can be used to easily mitigate the risk of + SQL injection. + metadata: + category: security + cwe: CWE-643 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper neutralization of data within XPath expressions ('XPath Injection') + mode: taint + pattern-sanitizers: + - pattern-either: + - pattern-inside: | + $X.xPathVariableResolver = ...; + ...; + $X.compile("..."); + - pattern-inside: | + $X.setXPathVariableResolver(...); + ...; + $X.compile("..."); + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: "import javax.xml.xpath.*; \n...\n" + - pattern-inside: "import javax.xml.xpath.XPath; \n...\n" + - patterns: + - pattern-either: + - patterns: + - pattern: $X.compile($VAR) + - pattern-not: $X.compile("...") + - patterns: + - pattern: $X.evaluate($VAR, ...) + - pattern-not: $X.evaluate("...", ...) + pattern-sources: + - patterns: + - pattern-inside: | + fun $FUNC(..., $VAR: $T, ...) { + ... + } + - pattern: $VAR + severity: ERROR + - id: kotlin_xss_rule-WicketXSS languages: - - yaml - message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. By adding a `securityContext` to your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. + - kotlin + message: | + Disabling HTML escaping put the application at risk for Cross-Site Scripting (XSS). metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-79 owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag - subcategory: - - vuln - technology: - - kubernetes + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') patterns: - pattern-inside: | - containers: - ... - - pattern-inside: | - - $NAME: $CONTAINER - ... - - pattern: | - image: ... + import org.apache.wicket.$A ... - - pattern-not: | - image: ... - ... - securityContext: - ... - - metavariable-regex: - metavariable: $NAME - regex: name - - focus-metavariable: $NAME + - pattern: | + $OBJ.setEscapeModelStrings(false); severity: WARNING - - fix: | - false - id: yaml.kubernetes.security.allow-privilege-escalation-true.allow-privilege-escalation-true + - id: kotlin_xss_rule-XSSReqParamToServletWriter languages: - - yaml - message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. In the container `$CONTAINER` this parameter is set to `true` which makes this container much more vulnerable to privelege escalation attacks. + - kotlin + message: | + Servlet reflected cross site scripting vulnerability metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-79 owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag - subcategory: - - vuln + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') technology: - - kubernetes - patterns: - - pattern-inside: | - containers: - ... - - pattern-inside: | - - name: $CONTAINER - ... - - pattern-inside: | - image: ... - ... - - pattern-inside: | - securityContext: - ... - - pattern: | - allowPrivilegeEscalation: $TRUE - - metavariable-pattern: - metavariable: $TRUE - pattern: | - true - - focus-metavariable: $TRUE + - kotlin + mode: taint + pattern-sanitizers: + - patterns: + - pattern-inside: org.owasp.encoder.Encode.forHtml($TAINTED); + - pattern: $TAINTED + pattern-sinks: + - patterns: + - pattern-inside: 'fun $FUNC(..., $RES: HttpServletResponse , ...) {...}' + - pattern-inside: | + $WRITER = $RES.getWriter(); + ... + - pattern: $WRITER.write($DATA,...); + - pattern: $DATA + - patterns: + - pattern-inside: 'fun $FUNC(..., $RES: HttpServletResponse , ...) {...}' + - pattern: $RES.getWriter().write($DATA,...); + - pattern: $DATA + pattern-sources: + - patterns: + - pattern-inside: 'fun $FUNC(..., $REQ: HttpServletRequest , ...) {...}' + - pattern: $REQ.getParameter(...); severity: WARNING - - fix: | - securityContext: - allowPrivilegeEscalation: false # - id: yaml.kubernetes.security.allow-privilege-escalation.allow-privilege-escalation + - id: kotlin_xxe_rule-SaxParserXXE languages: - - yaml - message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. By adding the `allowPrivilegeEscalation` parameter to your the `securityContext`, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. + - kotlin + message: | + XML External Entity (XXE) attacks can occur when an XML parser supports XML + entities while processing XML received from an untrusted source. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-611 owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag - subcategory: - - vuln - technology: - - kubernetes + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper restriction of XML external entity reference ('XXE') patterns: - pattern-inside: | - containers: - ... - - pattern-inside: | - - name: $CONTAINER - ... - - pattern: | - image: ... + $SF = SAXParserFactory.newInstance() ... - - pattern-inside: | - image: ... + - pattern-not-inside: | + $SF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); ... - $SC: - ... - - metavariable-regex: - metavariable: $SC - regex: ^(securityContext)$ - pattern-not-inside: | - image: ... + $SF.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); ... - securityContext: - ... - allowPrivilegeEscalation: $VAL - - focus-metavariable: $SC - severity: WARNING - - id: yaml.kubernetes.security.exposing-docker-socket-hostpath.exposing-docker-socket-hostpath + - pattern-inside: | + $P = $SFP.newSAXParser(); + ... + - pattern: $P.parse(...); + severity: ERROR + - id: kotlin_xxe_rule-XMLRdr languages: - - yaml - message: Exposing host's Docker socket to containers via a volume. The owner of this socket is root. Giving someone access to it is equivalent to giving unrestricted root access to your host. Remove 'docker.sock' from hostpath to prevent this. + - kotlin + message: | + XML External Entity (XXE) attacks can occur when an XML parser supports XML + entities while processing XML received from an untrusted source. metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: HIGH - likelihood: LOW - references: - - https://kubernetes.io/docs/concepts/storage/volumes/#hostpath - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#volumes-and-file-systems - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-1-do-not-expose-the-docker-daemon-socket-even-to-the-containers - subcategory: - - vuln - technology: - - kubernetes + cwe: CWE-611 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper restriction of XML external entity reference ('XXE') patterns: - pattern-inside: | - volumes: - ... - - pattern: | - hostPath: - ... - path: /var/run/docker.sock - severity: WARNING - - id: yaml.kubernetes.security.legacy-api-clusterrole-excessive-permissions.legacy-api-clusterrole-excessive-permissions + $R = XMLReaderFactory.createXMLReader() + ... + - pattern-not-inside: | + $R.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) + ... + - pattern: $R.parse(...) + severity: ERROR + - id: kotlin_xxe_rule-XMLStreamRdr languages: - - yaml - message: 'Semgrep detected a Kubernetes core API ClusterRole with excessive permissions. Attaching excessive permissions to a ClusterRole associated with the core namespace allows the V1 API to perform arbitrary actions on arbitrary resources attached to the cluster. Prefer explicit allowlists of verbs/resources when configuring the core API namespace. ' + - kotlin + message: | + XML External Entity (XXE) attacks can occur when an XML parser supports XML + entities while processing XML received from an untrusted source. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-269: Improper Privilege Management' - cwe2021-top25: false - impact: HIGH - likelihood: MEDIUM + cwe: CWE-611 owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole - - https://kubernetes.io/docs/concepts/security/rbac-good-practices/#general-good-practice - - https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#api-groups - subcategory: - - vuln - technology: - - kubernetes + - A1:2017-Injection + - A03:2021-Injection + security-severity: CRITICAL + shortDescription: Improper restriction of XML external entity reference ('XXE') patterns: - - pattern: | - "*" - pattern-inside: | - resources: $A + $SF = XMLInputFactory.newFactory(); ... - - pattern-inside: | - verbs: $A + - pattern-not-inside: | + $SF.setProperty(XMLInputFactory.SUPPORT_DTD, false); ... - - pattern-inside: | - - apiGroups: [""] - ... - - pattern-inside: | - apiVersion: rbac.authorization.k8s.io/v1 + - pattern-not-inside: | + $SF.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); ... - - pattern-inside: | - kind: ClusterRole + - pattern-not-inside: | + $SF.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); ... - severity: WARNING - - id: yaml.kubernetes.security.privileged-container.privileged-container - languages: - - yaml - message: Container or pod is running in privileged mode. This grants the container the equivalent of root capabilities on the host machine. This can lead to container escapes, privilege escalation, and other security concerns. Remove the 'privileged' key to disable this capability. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privileged - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html - subcategory: - - vuln - technology: - - kubernetes - pattern-either: - - patterns: - - pattern-inside: | - containers: - ... - - pattern: | - image: ... - ... - securityContext: - ... - privileged: true - - patterns: - - pattern-inside: | - spec: - ... - - pattern-not-inside: | - image: ... - ... - - pattern: | - privileged: true - severity: WARNING - - fix: | - true - id: yaml.kubernetes.security.run-as-non-root-unsafe-value.run-as-non-root-unsafe-value + - pattern-not-inside: | + $SF.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); + ... + - pattern: $SF.createXMLStreamReader(...) + severity: ERROR + - id: rules_lgpl_swift_other_rule-ios-biometric-acl languages: - - yaml - message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. + - swift + message: "Weak biometric ACL flag is associated with a key stored in Keychain. \nWith '.biometryAny/.userPresence/.touchIDAny' flag, an attacker with \nthe ability to add a biometry to the device can authenticate as the \nuser. It is recommended to use more specific and secure authentication \nmechanisms like '.biometryCurrentSet' and '.touchIDCurrentSet'.\n\nHere's an example of how to fix the problem by using .biometryCurrentSet \nfor biometric authentication in Swift:\n```\nimport LocalAuthentication\n\n// Create an instance of LAContext for biometric authentication\nlet context = LAContext()\n\n// Check if biometric authentication is available\nif context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {\n // Use biometryCurrentSet for biometric authentication\n context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, \n localizedReason: \"Authenticate with biometrics\", \n reply: { success, error in\n if success {\n print(\"Biometric authentication successful.\")\n // Proceed with authenticated actions\n } else {\n print(\"Biometric authentication failed: \n \\(error?.localizedDescription ?? \"Unknown error\")\")\n // Handle authentication failure\n }\n })\n} else {\n print(\"Biometric authentication not available.\")\n // Fallback to alternative authentication method\n}\n\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: HIGH - likelihood: MEDIUM + cwe: CWE-305 owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user - subcategory: - - audit - technology: - - kubernetes + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: CRITICAL + shortDescription: Authentication bypass by primary weakness patterns: - pattern-either: - - pattern: | - spec: - ... - securityContext: - ... - runAsNonRoot: $VALUE - - patterns: - - pattern-inside: | - containers: - ... - - pattern: | - image: ... - ... - securityContext: - ... - runAsNonRoot: $VALUE - - metavariable-pattern: - metavariable: $VALUE - pattern: | - false - - focus-metavariable: $VALUE - severity: INFO - - id: yaml.kubernetes.security.seccomp-confinement-disabled.seccomp-confinement-disabled + - pattern: .biometryAny + - pattern: .userPresence + - pattern: .touchIDAny + - pattern: SecAccessControlCreateWithFlags(...) + severity: ERROR + - id: rules_lgpl_swift_other_rule-ios-dtls1-used languages: - - yaml - message: 'Container is explicitly disabling seccomp confinement. This runs the service in an unrestricted state. Remove ''seccompProfile: unconfined'' to prevent this.' + - swift + message: "DTLS 1.2 should be used. Detected old version - DTLS 1.0.\nDTLS (Datagram Transport Layer Security) 1.0 suffers from \nvarious security vulnerabilities and weaknesses, as it is \nan outdated and less secure protocol compared to newer \nversions such as DTLS 1.2 or 1.3.\n\nHere's an example of how to use DTLS 1.2:\n```\nimport Network\n\n// Create a NWConnection instance with DTLS 1.2\nlet connection = NWConnection(host: NWEndpoint.Host(\"example.com\"), port: NWEndpoint.Port(\"443\"), using: .dtls)\n\n// Start the connection\nconnection.start(queue: .main)\n\n// Handle connection state changes\nconnection.stateUpdateHandler = { newState in\n switch newState {\n case .ready:\n print(\"Connection ready.\")\n // Perform data transfer or other operations\n case .failed(let error):\n print(\"Connection failed with error: \\(error)\")\n default:\n break\n }\n}\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-284: Improper Access Control' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-757 owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - subcategory: - - vuln - technology: - - kubernetes + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Selection of less-secure algorithm during negotiation ('algorithm downgrade') patterns: + - pattern: $Y.TLSMinimumSupportedProtocolVersion - pattern-inside: | - containers: - ... - - pattern: | - image: ... ... - securityContext: - ... - seccompProfile: unconfined + $X = "tls_protocol_version_t.DTLSv10" + ... severity: WARNING - - id: yaml.kubernetes.security.secrets-in-config-file.secrets-in-config-file + - id: rules_lgpl_swift_other_rule-ios-file-no-special languages: - - yaml - message: 'Secrets ($VALUE) should not be stored in infrastructure as code files. Use an alternative such as Bitnami Sealed Secrets or KSOPS to encrypt Kubernetes Secrets. ' + - swift + message: "The file has no special protections associated with it.\nUsing .noFileProtection or FileProtectionType.none for \nfile protection means that the file is not encrypted on disk, \nleaving it vulnerable to unauthorized access if the device is \ncompromised or if the file is accessed outside of the app's \nsandbox. To enhance security, it's crucial to use appropriate \nfile protection attributes based on the sensitivity of the data \nbeing stored. For sensitive data, you should use file protection \noptions that encrypt the data on disk, such as \nFileProtectionType.complete or \nFileProtectionType.completeUnlessOpen.\n\nHere's an example of how to fix the problem:\n```\nimport Foundation \n// Define the file URL\nlet fileURL = URL(fileURLWithPath: \"path/to/file\")\n// Define data to be written to the file\nlet data = \"Sensitive data\".data(using: .utf8)!\n// Write data to the file with complete file protection\ndo {\n try data.write(to: fileURL, options: .completeFileProtection)\n print(\"Data written to file with complete file protection.\")\n} catch {\n print(\"Error writing data to file: \\(error)\")\n}\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW + cwe: CWE-312 owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://kubernetes.io/docs/concepts/configuration/secret/ - - https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/0/CTR_Kubernetes_Hardening_Guidance_1.1_20220315.PDF - - https://docs.gitlab.com/ee/user/clusters/agent/gitops/secrets_management.html - - https://www.cncf.io/blog/2021/04/22/revealing-the-secrets-of-kubernetes-secrets/ - - https://github.com/bitnami-labs/sealed-secrets - - https://www.cncf.io/blog/2022/01/25/secrets-management-essential-when-using-kubernetes/ - - https://blog.oddbit.com/post/2021-03-09-getting-started-with-ksops/ - subcategory: - - vuln - technology: - - kubernetes - patterns: - - pattern: | - $KEY: $VALUE - - pattern-inside: | - data: ... - - pattern-inside: | - kind: Secret - ... - - metavariable-regex: - metavariable: $VALUE - regex: (?i)^[aA-zZ0-9+/]+={0,2}$ - - metavariable-analysis: - analyzer: entropy - metavariable: $VALUE - severity: WARNING - - id: yaml.kubernetes.security.skip-tls-verify-cluster.skip-tls-verify-cluster + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: CRITICAL + shortDescription: Cleartext storage of sensitive information + pattern-either: + - pattern: .noFileProtection + - pattern: FileProtectionType.none + severity: ERROR + - id: rules_lgpl_swift_other_rule-ios-keychain-weak-accessibility-value languages: - - yaml - message: 'Cluster is disabling TLS certificate verification when communicating with the server. This makes your HTTPS connections insecure. Remove the ''insecure-skip-tls-verify: true'' key to secure communication.' + - swift + message: "A key stored in the Keychain is using a weak accessibility value. \n\nkSecAttrAccessibleAlways allows access to the keychain item at all \ntimes, even when the device is locked. Storing sensitive data with \nthis accessibility option means that the data is accessible to anyone \nwho gains physical access to the device, regardless of whether it's \nlocked or not. This increases the risk of unauthorized access to \nsensitive information. kSecAttrAccessibleAfterFirstUnlock allows access\nto the keychain item only after the device has been unlocked once after\na reboot. While this provides some level of protection, the data becomes\naccessible as soon as the device is unlocked for the first time after a\nreboot. If sensitive data is stored with this accessibility option, it \ncould still be accessed by an attacker who gains physical access to the\ndevice before it's unlocked for the first time after a reboot.\n\nTo mitigate these security risks, it's important to use the appropriate \naccessibility option based on the sensitivity of the data being stored. \nFor sensitive data that should only be accessible when the device is \nunlocked, the kSecAttrAccessibleWhenUnlocked or \nkSecAttrAccessibleWhenUnlockedThisDeviceOnly \noptions should be used.\n\nHere's an example code that fixes the problem by using the \nkSecAttrAccessibleWhenUnlocked option:\n```\nimport Foundation\nimport Security\n\n// Define the data to be stored in the keychain\nlet secretData = \"superSecretData\".data(using: .utf8)!\n\n// Create query dictionary to specify the keychain item\nlet query: [String: Any] = [\n kSecClass as String: kSecClassGenericPassword,\n kSecAttrService as String: \"com.example.myApp\",\n kSecAttrAccount as String: \"userPassword\",\n kSecValueData as String: secretData,\n kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked\n]\n\n// Add the keychain item\nlet status = SecItemAdd(query as CFDictionary, nil)\nif status == errSecSuccess {\n print(\"Secret data successfully stored in keychain.\")\n} else {\n print(\"Error storing secret data in keychain: \\(status)\")\n}\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-305 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://kubernetes.io/docs/reference/config-api/client-authentication.v1beta1/#client-authentication-k8s-io-v1beta1-Cluster - subcategory: - - vuln - technology: - - kubernetes - pattern: | - cluster: - ... - insecure-skip-tls-verify: true + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: MEDIUM + shortDescription: Authentication bypass by primary weakness + pattern-either: + - pattern: kSecAttrAccessibleAlways + - pattern: kSecAttrAccessibleAfterFirstUnlock severity: WARNING - - id: yaml.kubernetes.security.skip-tls-verify-service.skip-tls-verify-service + - id: rules_lgpl_swift_other_rule-ios-tls3-not-used languages: - - yaml - message: 'Service is disabling TLS certificate verification when communicating with the server. This makes your HTTPS connections insecure. Remove the ''insecureSkipTLSVerify: true'' key to secure communication.' + - swift + message: "The app uses TLS 1.0, TLS 1.1 or TLS 1.2. TLS 1.3 should be used instead.\nTLS versions 1.1 and 1.0 were deprecated by the IETF in June 2018 due to \na number of attacks against the vulnerable versions. Use of a deprecated \nTLS version may result in the unauthorized retrieval of sensitive \ninformation. It is strongly recommended that all TLS connections\nuse TLS 1.3\n\nTLS 1.3 includes several security improvements over previous versions, such\nas stronger cryptographic algorithms and negotiation mechanisms, reducing \nthe risk of security vulnerabilities and attacks like BEAST and POODLE.\n\n\nExample using TLS 1.3:\n```\nimport Foundation\n// Create a URLSession configuration with TLS 1.3 support\nlet configuration = URLSessionConfiguration.default\nconfiguration.tlsMinimumSupportedProtocol = .TLSv13\n// Create a URLSession with the custom configuration\nlet session = URLSession(configuration: configuration) \n// Define the URL to connect to\nlet url = URL(string: \"https://example.com\")!\n// Create a data task to fetch data from the URL\nlet task = session.dataTask(with: url) { data, response, error in\n // Handle response\n if let error = error {\n print(\"Error: \\(error)\")\n return\n }\n if let httpResponse = response as? HTTPURLResponse {\n print(\"Status code: \\(httpResponse.statusCode)\")\n } \n if let data = data {\n // Process received data\n print(\"Received data: \\(data)\")\n }\n}\n// Start the data task\ntask.resume()\n```\n" metadata: category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-757 owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#apiservice-v1-apiregistration-k8s-io - subcategory: - - vuln - technology: - - kubernetes - pattern: | - spec: - ... - insecureSkipTLSVerify: true - severity: WARNING - - id: yaml.openapi.security.use-of-basic-authentication.use-of-basic-authentication + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: CRITICAL + shortDescription: Selection of less-secure algorithm during negotiation ('algorithm downgrade') + pattern-either: + - patterns: + - pattern: $X.TLSMinimumSupportedProtocolVersion = $VAL + - metavariable-pattern: + metavariable: $VAL + pattern-either: + - pattern: | + .TLSv1_0 + - pattern: | + .TLSv1_1 + - pattern: | + .TLSv1_2 + severity: ERROR + - id: scala_cookie_rule-CookieHTTPOnly languages: - - yaml - message: Basic authentication is considered weak and should be avoided. Use a different authentication scheme, such of OAuth2, OpenID Connect, or mTLS. + - scala + message: | + A new cookie is created without the HttpOnly flag set. The HttpOnly flag is a directive to the + browser to make sure that the cookie can not be red by malicious script. When a user is the + target of a "Cross-Site Scripting", the attacker would benefit greatly from getting the session + id for example. metadata: category: security - confidence: HIGH - cwe: 'CWE-287: Improper Authentication' - impact: HIGH - likelihood: MEDIUM - owasp: - - A04:2021 Insecure Design - - A07:2021 Identification and Authentication Failures - references: - - https://cwe.mitre.org/data/definitions/287.html - - https://owasp.org/Top10/A04_2021-Insecure_Design/ - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ - subcategory: - - vuln + cwe: CWE-1004 + security-severity: Low + shortDescription: Sensitive Cookie Without 'HttpOnly' Flag technology: - - openapi - patterns: - - pattern-inside: | - openapi: $VERSION - ... - components: - ... - securitySchemes: + - scala + pattern-either: + - patterns: + - pattern: | + val $C = new javax.servlet.http.Cookie(..., ...); ... - $SCHEME: - ... - - metavariable-regex: - metavariable: $VERSION - regex: 3.* - - pattern: | - type: http - ... - scheme: basic - severity: ERROR - - id: java_perm_rule-DangerousPermissions + $RESP.addCookie($C); + - pattern-not-inside: | + val $C = new javax.servlet.http.Cookie(..., ...); + ... + $C.setHttpOnly(true); + ... + $RESP.addCookie($C); + - pattern: (javax.servlet.http.Cookie $C).setHttpOnly(false); + severity: WARNING + - id: scala_cookie_rule-CookieInsecure languages: - - java + - scala message: | - The application was found to permit the `RuntimePermission` of `createClassLoader`, - `ReflectPermission` of `suppressAccessChecks`, or both. - - By granting the `RuntimePermission` of `createClassLoader`, a compromised application - could instantiate their own class loaders and load arbitrary classes. - - By granting the `ReflectPermission` of `suppressAccessChecks` an application will no longer - check Java language access checks on fields and methods of a class. This will effectively - grant access to protected and private members. - - For more information on `RuntimePermission` see: - https://docs.oracle.com/javase/8/docs/api/java/lang/RuntimePermission.html - - For more information on `ReflectPermission` see: - https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/ReflectPermission.html + "A new cookie is created without the Secure flag set. The Secure flag is a + directive to the browser to make sure that the cookie is not sent for insecure communication + (http://)" metadata: category: security - confidence: HIGH - cwe: CWE-732 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Incorrect permission assignment for critical resource - pattern-either: - - pattern: | - $RUNVAR = new RuntimePermission("createClassLoader"); + cwe: CWE-539 + security-severity: Low + shortDescription: Information Exposure Through Persistent Cookies + technology: + - scala + patterns: + - pattern-not-inside: | + val $C = new javax.servlet.http.Cookie(..., ...); ... - (PermissionCollection $PC).add($RUNVAR); - - pattern: | - $REFVAR = new ReflectPermission("suppressAccessChecks"); + $C.setSecure(true); ... - (PermissionCollection $PC).add($REFVAR); - - pattern: (PermissionCollection $PC).add(new ReflectPermission("suppressAccessChecks")) - - pattern: (PermissionCollection $PC).add(new RuntimePermission("createClassLoader")) + $RESP.addCookie($C); + - pattern-either: + - pattern: | + val $C = new javax.servlet.http.Cookie(..., ...); + ... + $RESP.addCookie($C); + - pattern: ($C:javax.servlet.http.Cookie).setSecure(false); severity: WARNING - - id: java_perm_rule-OverlyPermissiveFilePermissionInline + - id: scala_cookie_rule-CookiePersistent languages: - - java + - scala message: | - The application was found setting file permissions to overly permissive values. Consider - using the following values if the application user is the only process to access - the file: - - - `r--` - read only access to the file - - `w--` - write only access to the file - - `rw-` - read/write access to the file - - Example setting read/write permissions for only the owner of a `Path`: - ``` - // Get a reference to the path - Path path = Paths.get("/tmp/somefile"); - // Create a PosixFilePermission set from java.nio.file.attribute - Set permissions = - java.nio.file.attribute.PosixFilePermissions.fromString("rw-------"); - // Set the permissions - java.nio.file.Files.setPosixFilePermissions(path, permissions); - ``` - - For all other values please see: - https://en.wikipedia.org/wiki/File-system_permissions#Symbolic_notation + "Storing sensitive data in a persistent cookie for an extended period can lead to a breach of + confidentiality or account compromise." metadata: category: security - confidence: HIGH - cwe: CWE-732 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Incorrect permission assignment for critical resource + cwe: CWE-614 + security-severity: Info + shortDescription: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute + technology: + - scala patterns: - - pattern-either: - - pattern: java.nio.file.Files.setPosixFilePermissions(..., java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING")); - - pattern: | - $PERMISSIONS = java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING"); - ... - java.nio.file.Files.setPosixFilePermissions(..., $PERMISSIONS); - - metavariable-regex: - metavariable: $PERM_STRING - regex: '[rwx-]{6}[rwx]{1,}' + - pattern: | + ($C: Cookie).setMaxAge($AGE) + - metavariable-comparison: + comparison: $AGE >= 31536000 + metavariable: $AGE severity: WARNING - - id: java_strings_rule-BadHexConversion + - id: scala_cookie_rule-CookieUsage languages: - - java + - scala message: | - The application is using `Integer.toHexString` on a digest array buffer which - may lead to an incorrect version of values. - - Consider using the `java.util.HexFormat` object introduced in Java 17. For older Java applications - consider using the `javax.xml.bind.DatatypeConverter`. - - Example using `HexFormat` to create a human-readable string: - ``` - // Create a MessageDigest using the SHA-384 algorithm - MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384"); - // Call update with your data - sha384Digest.update("some input".getBytes(StandardCharsets.UTF_8)); - // Only call digest once all data has been fed into the update sha384digest instance - byte[] output = sha384Digest.digest(); - // Create a JDK 17 HexFormat object - HexFormat hex = HexFormat.of(); - // Use formatHex on the byte array to create a string (note that alphabet characters are - lowercase) - String hexString = hex.formatHex(output); - ``` - - For more information on DatatypeConverter see: - https://docs.oracle.com/javase/9/docs/api/javax/xml/bind/DatatypeConverter.html#printHexBinary-byte:A- + The information stored in a custom cookie should not be sensitive or related to the session. + In most cases, sensitive data should only be stored in session and referenced by the user's + session cookie. metadata: category: security - confidence: HIGH - cwe: CWE-704 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration + cwe: CWE-614 security-severity: Info - shortDescription: Incorrect type conversion or cast + shortDescription: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute + technology: + - scala patterns: - pattern-inside: | - $B_ARR = (java.security.MessageDigest $MD).digest(...); - ... + def $FUNC(..., $REQ: HttpServletRequest, ...): $TYPE = { + ... + } - pattern-either: - - pattern: | - for(...) { - ... - $B = $B_ARR[...]; - ... - Integer.toHexString($B); - } - - pattern: | - for(...) { - ... - Integer.toHexString($B_ARR[...]); - } - - pattern: | - for(byte $B :$B_ARR) { - ... - Integer.toHexString($B); - } - - pattern: | - while(...) { - ... - Integer.toHexString($B_ARR[...]) - } - - pattern: | - do { - ... - Integer.toHexString($B_ARR[...]) - } while(...) - - pattern: | - while(...) { - ... - $B = $B_ARR[...]; - ... - Integer.toHexString($B); - } - - pattern: | - do { - ... - $B = $B_ARR[...]; - ... - Integer.toHexString($B); - } while(...) + - patterns: + - pattern-inside: | + for ($C <- $REQ.getCookies) { + ... + } + - pattern-either: + - pattern: $C.getName + - pattern: $C.getValue + - pattern: $C.getPath + - pattern: '($C: Cookie).getName()' + - pattern: '($C: Cookie).getValue' + - pattern: '($C: Cookie).getPath' severity: WARNING - - id: java_strings_rule-FormatStringManipulation + - id: scala_cookie_rule-HttpResponseSplitting languages: - - java + - scala message: | - The application allows user input to control format string parameters. By passing invalid - format - string specifiers an adversary could cause the application to throw exceptions or possibly - leak - internal information depending on application logic. - - Never allow user-supplied input to be used to create a format string. Replace all format - string - arguments with hardcoded format strings containing the necessary specifiers. - - Example of using `String.format` safely: - ``` - // Get untrusted user input - String userInput = request.getParameter("someInput"); - // Ensure that user input is not included in the first argument to String.format - String.format("Hardcoded string expecting a string: %s", userInput); - // ... - ``` + When an HTTP request contains unexpected CR and LF characters, the server may respond with an + output stream that is interpreted as two different HTTP responses (instead of one). An attacker + can control the second response and mount attacks such as cross-site scripting and cache + poisoning attacks. metadata: category: security - confidence: HIGH - cwe: CWE-134 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Use of externally-controlled format string + cwe: CWE-113 + security-severity: High + shortDescription: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') + technology: + - scala + mode: taint + pattern-sanitizers: + - patterns: + - pattern-inside: $STR.replaceAll("$REPLACE_CHAR", "$REPLACE"); + - pattern: $STR + - metavariable-regex: + metavariable: $REPLACE_CHAR + regex: (.*\\r\\n.*) + - metavariable-regex: + metavariable: $REPLACE + regex: (?!(\\r\\n)) + - pattern: org.owasp.encoder.Encode.forUriComponent(...) + - pattern: org.owasp.encoder.Encode.forUri(...) + - pattern: java.net.URLEncoder.encode(..., $CHARSET) + pattern-sinks: + - pattern: new javax.servlet.http.Cookie("$KEY", ...) + - pattern: ($C:javax.servlet.http.Cookie).setValue(...) + pattern-sources: + - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameter(...)' + severity: WARNING + - id: scala_cookie_rule-RequestParamToCookie + languages: + - scala + message: | + This code constructs an HTTP Cookie using an untrusted HTTP parameter. If this cookie is added + to an HTTP response, it will allow a HTTP response splitting vulnerability. See + http://en.wikipedia.org/wiki/HTTP_response_splitting for more information. + metadata: + category: security + cwe: CWE-113 + security-severity: Info + shortDescription: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') + technology: + - scala + mode: taint + pattern-sanitizers: + - patterns: + - pattern-inside: $STR.replaceAll("$REPLACE_CHAR", "$REPLACE"); + - pattern: $STR + - metavariable-regex: + metavariable: $REPLACE_CHAR + regex: (.*\\r\\n.*) + - metavariable-regex: + metavariable: $REPLACE + regex: (?!(\\r\\n)) + - pattern: org.owasp.encoder.Encode.forUriComponent(...) + - pattern: org.owasp.encoder.Encode.forUri(...) + - pattern: java.net.URLEncoder.encode(..., $CHARSET) + pattern-sinks: + - pattern: new javax.servlet.http.Cookie("$KEY", ...); + - patterns: + - pattern-inside: | + $C = new javax.servlet.http.Cookie("$KEY", ...); + ... + - pattern: $C.setValue(...); + pattern-sources: + - pattern: '($REQ: HttpServletRequest).getParameter(...);' + severity: ERROR + - id: scala_cookie_rule-RequestParamToHeader + languages: + - scala + message: | + This code directly writes an HTTP parameter to an HTTP header, which allows for a HTTP + response splitting vulnerability. See http://en.wikipedia.org/wiki/HTTP_response_splitting for + more information. + metadata: + category: security + cwe: CWE-113 + security-severity: High + shortDescription: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') + technology: + - scala + mode: taint + pattern-sanitizers: + - patterns: + - pattern-inside: $STR.replaceAll("$REPLACE_CHAR", "$REPLACE"); + - pattern: $STR + - metavariable-regex: + metavariable: $REPLACE_CHAR + regex: (.*\\r\\n.*) + - metavariable-regex: + metavariable: $REPLACE + regex: (?!(\\r\\n)) + - pattern: org.owasp.encoder.Encode.forUriComponent(...) + - pattern: org.owasp.encoder.Encode.forUri(...) + - pattern: java.net.URLEncoder.encode(..., $CHARSET) + pattern-sinks: + - pattern: '($RES: HttpServletResponse).setHeader("$KEY", ...);' + - pattern: '($RES: HttpServletResponse).addHeader("$KEY", ...);' + - pattern: '($WRP: HttpServletResponseWrapper).setHeader("$KEY", ...);' + - pattern: '($WRP: HttpServletResponseWrapper).addHeader("$KEY", ...);' + pattern-sources: + - pattern: '($REQ: HttpServletRequest).getParameter(...);' + severity: ERROR + - id: scala_cookie_rule-TrustBoundaryViolation + languages: + - scala + message: | + A trust boundary can be thought of as line drawn through a program. On one side + of the line, data is untrusted. On the other side of the line, data is assumed + to be trustworthy. The purpose of validation logic is to allow data to safely + cross the trust boundary - to move from untrusted to trusted. A trust boundary + violation occurs when a program blurs the line between what is trusted and what + is untrusted. By combining trusted and untrusted data in the same data + structure, it becomes easier for programmers to mistakenly trust unvalidated + data. + metadata: + category: security + cwe: CWE-501 + security-severity: Info + shortDescription: Trust Boundary Violation patterns: - pattern-either: - patterns: - - pattern-inside: | - String $INPUT = (HttpServletRequest $REQ).getParameter(...); - ... - - pattern-inside: | - String $FORMAT_STR = ... + $INPUT; - ... + - pattern: '($H: HttpServletRequest). ... .setAttribute($ARG1, $ARG2)' + - pattern-not: '($H: HttpServletRequest). ... .setAttribute("...", "...")' - patterns: - - pattern-inside: | - String $INPUT = (HttpServletRequest $REQ).getParameter(...); - ... - - pattern-inside: | - String $FORMAT_STR = ... + $INPUT + ...; - ... - - pattern-inside: | - String $FORMAT_STR = ... + (HttpServletRequest $REQ).getParameter(...) + ...; - ... + - pattern: '($H: HttpServletRequest). ... .putValue($ARG1, $ARG2)' + - pattern-not: '($H: HttpServletRequest). ... .putValue("...", "...")' + severity: WARNING + - id: scala_cors_rule-PermissiveCORS + languages: + - scala + message: | + Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for + JavaScript to access the contents of a Web page, both the JavaScript and the Web page must + originate from the same domain. Without the Same Origin Policy, a malicious website could serve + up JavaScript that loads sensitive information from other websites using a client's + credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible + for JavaScript to access data across domains if a new HTTP header called + Access-Control-Allow-Origin is defined. With this header, a Web server defines which other + domains are allowed to access its domain using cross-origin requests. However, caution should + be taken when defining the header because an overly permissive CORS policy will allow a + malicious application to communicate with the victim application in an inappropriate way, + leading to spoofing, data theft, relay and other attacks. + metadata: + category: security + cwe: CWE-942 + security-severity: Info + shortDescription: Permissive Cross-domain Policy with Untrusted Domains + technology: + - scala + pattern-either: + - patterns: + - pattern-either: + - pattern: ($RESP:javax.servlet.http.HttpServletResponse).setHeader("$HEADER", "$VAL") + - pattern: ($RESP:javax.servlet.http.HttpServletResponse).addHeader("$HEADER", "$VAL") + - metavariable-regex: + metavariable: $HEADER + regex: (?i)(Access-Control-Allow-Origin) + - metavariable-regex: + metavariable: $VAL + regex: (\*|null) + - patterns: - pattern-inside: | - String $FORMAT_STR = ... + (HttpServletRequest $REQ).getParameter(...); + $REQVAL = ($REQ: javax.servlet.http.HttpServletRequest).getParameter(...) ... - - pattern-either: - - pattern: String.format($FORMAT_STR, ...); - - pattern: String.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - - pattern: (java.util.Formatter $F).format($FORMAT_STR, ...); - - pattern: (java.util.Formatter $F).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - - pattern: (java.io.PrintStream $F).printf($FORMAT_STR, ...); - - pattern: (java.io.PrintStream $F).printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - - pattern: (java.io.PrintStream $F).format($FORMAT_STR, ...); - - pattern: (java.io.PrintStream $F).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - - pattern: System.out.printf($FORMAT_STR, ...); - - pattern: System.out.printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - - pattern: System.out.format($FORMAT_STR, ...); - - pattern: System.out.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern-either: + - pattern-inside: ($RESP:javax.servlet.http.HttpServletResponse).setHeader("$HEADER", $REQVAL) + - pattern-inside: ($RESP:javax.servlet.http.HttpServletResponse).addHeader("$HEADER", $REQVAL) + - patterns: + - pattern-either: + - pattern-inside: '($RESP:javax.servlet.http.HttpServletResponse).setHeader("$HEADER",($REQ: javax.servlet.http.HttpServletRequest).getParameter(...))' + - pattern-inside: '($RESP:javax.servlet.http.HttpServletResponse).addHeader("$HEADER",($REQ: javax.servlet.http.HttpServletRequest).getParameter(...))' severity: ERROR - - id: java_strings_rule-ModifyAfterValidation + - id: scala_cors_rule-PermissiveCORSInjection languages: - java - message: |+ - The application was found matching a variable during a regular expression - pattern match, and then calling string modification functions after validation has occurred. - This is usually indicative of a poor input validation strategy as an adversary may attempt to - exploit the removal of characters. - - For example a common mistake in attempting to remove path characters to protect against path - traversal is to match '../' and then remove any matches. However, if an adversary were to - include in their input: '....//' then the `replace` method would replace the first `../` but - cause the leading `..` and trailing `/` to join into the final string of `../`, effectively - bypassing the check. - - To remediate this issue always perform string modifications before any validation of a string. - It is strongly recommended that strings be encoded instead of replaced or removed prior to - validation. - - - Example replaces `..` before validation. Do note this is still not a recommended method for - protecting against directory traversal, always use randomly generated IDs or filenames instead: - ``` - // This is ONLY for demonstration purpose, never use untrusted input - // in paths, always use randomly generated filenames or IDs. - String input = "test../....//dir"; - // Use replaceAll _not_ replace - input = input.replaceAll("\\.\\.", ""); - // Input would be test///dir at this point - // Create a pattern to match on - Pattern pattern = Pattern.compile("\\.\\."); - // Create a matcher - Matcher match = pattern.matcher(input); - // Call find to see if .. is still in our string - if (match.find()) { - throw new Exception(".. detected"); - } - // Use the input (but do not modify the string) - System.out.println(input + " safe"); - ``` - - For more information see Carnegie Mellon University's Secure Coding Guide: - https://wiki.sei.cmu.edu/confluence/display/java/IDS11-J.+Perform+any+string+modifications+before+validation - + message: | + Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for + JavaScript to access the contents of a Web page, both the JavaScript and the Web page must + originate from the same domain. Without the Same Origin Policy, a malicious website could serve + up JavaScript that loads sensitive information from other websites using a client's + credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible + for JavaScript to access data across domains if a new HTTP header called + Access-Control-Allow-Origin is defined. With this header, a Web server defines which other + domains are allowed to access its domain using cross-origin requests. However, caution should + be taken when defining the header because an overly permissive CORS policy will allow a + malicious application to communicate with the victim application in an inappropriate way, + leading to spoofing, data theft, relay and other attacks. + metadata: + category: security + cwe: CWE-942 + security-severity: Low + shortDescription: Permissive Cross-domain Policy with Untrusted Domains + technology: + - java + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: (HttpServletResponse $RES).setHeader("$HEADER", ...) + - pattern: (HttpServletResponse $RES).addHeader("$HEADER", ...) + - metavariable-regex: + metavariable: $HEADER + regex: (?i)(Access-Control-Allow-Origin) + pattern-sources: + - pattern: (HttpServletRequest $REQ).getParameter(...) + severity: ERROR + - id: scala_crypto_rule-BlowfishKeySize + languages: + - scala + message: | + A small key size makes the ciphertext vulnerable to brute force attacks. At least 128 bits of + entropy should be used when generating the key if use of Blowfish is required. metadata: category: security - confidence: HIGH - cwe: CWE-182 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Info - shortDescription: Collapse of data into unsafe value + cwe: CWE-326 + security-severity: Medium + shortDescription: Inadequate Encryption Strength + technology: + - scala patterns: - - pattern: | - (java.util.regex.Pattern $Y).matcher($VAR); + - pattern-inside: | + $KEYGEN = javax.crypto.KeyGenerator.getInstance("Blowfish", ...); ... - $VAR.$METHOD(...); - - metavariable-regex: - metavariable: $METHOD - regex: (replace|replaceAll|replaceFirst|concat) + $KEYGEN.init($KEY_SIZE); + - metavariable-comparison: + comparison: $KEY_SIZE < 128 + metavariable: $KEY_SIZE severity: WARNING - - id: java_strings_rule-NormalizeAfterValidation + - id: scala_crypto_rule-CipherDESInsecure languages: - - java + - scala message: | - The application was found matching a variable during a regular expression - pattern match, and then calling a Unicode normalize function after validation has occurred. - This is usually indicative of a poor input validation strategy as an adversary may attempt to - exploit the normalization process. - - To remediate this issue, always perform Unicode normalization before any validation of a - string. - - Example of normalizing a string before validation: - ``` - // User input possibly containing malicious unicode - String userInput = "\uFE64" + "tag" + "\uFE65"; - // Normalize the input - userInput = Normalizer.normalize(userInput, Normalizer.Form.NFKC); - // Compile our regex pattern looking for < or > characters - Pattern pattern = Pattern.compile("[<>]"); - // Create a matcher from the userInput - Matcher matcher = pattern.matcher(userInput); - // See if the matcher matches - if (matcher.find()) { - // It did so throw an error - throw new Exception("found banned characters in input"); - } - ``` - - For more information see Carnegie Mellon University's Secure Coding Guide: - https://wiki.sei.cmu.edu/confluence/display/java/IDS01-J.+Normalize+strings+before+validating+them + DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage + of AES block ciphers instead of DES. metadata: category: security - confidence: HIGH - cwe: CWE-180 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Info - shortDescription: 'Incorrect behavior order: validate before canonicalize' + cwe: CWE-326 + security-severity: Medium + shortDescription: Inadequate Encryption Strength + technology: + - scala patterns: - - pattern: | - $Y = java.util.regex.Pattern.compile("[<>]"); - ... - $Y.matcher($VAR); - ... - java.text.Normalizer.normalize($VAR, ...); + - pattern-inside: javax.crypto.Cipher.getInstance("$ALG") + - metavariable-regex: + metavariable: $ALG + regex: ^(DES)/.* severity: WARNING - - id: java_crypto_rule-DisallowOldTLSVersion + - id: scala_crypto_rule-CipherDESedeInsecure languages: - - java - message: "This application sets the `jdk.tls.client.protocols` system property to\ninclude insecure TLS or SSL versions (SSLv3, TLSv1, TLSv1.1), which are\ndeprecated due to serious security vulnerabilities like POODLE attacks and\nsusceptibility to man-in-the-middle attacks. Continuing to use these\nprotocols can expose data to interception or manipulation. \n\nTo mitigate the issue, upgrade to TLSv1.2 or higher, which provide stronger \nencryption and improved security. Refrain from using any SSL versions as they \nare entirely deprecated.\n\nSecure Code Example:\n```\npublic void safe() {\n java.lang.System.setProperty(\"jdk.tls.client.protocols\", \"TLSv1.3\");\n}\n```\n" + - scala + message: | + Triple DES (also known as 3DES or DESede) is considered strong ciphers for modern + applications. NIST recommends the usage of AES block ciphers instead of 3DES. metadata: category: security - confidence: MEDIUM cwe: CWE-326 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://stackoverflow.com/questions/26504653/is-it-possible-to-disable-sslv3-for-all-java-applications - security-severity: MEDIUM - shortDescription: Inadequate encryption strength - subcategory: - - vuln + security-severity: Medium + shortDescription: Inadequate Encryption Strength technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information + - scala patterns: - - pattern: $VALUE. ... .setProperty("jdk.tls.client.protocols", "$PATTERNS"); - - metavariable-pattern: - language: generic - metavariable: $PATTERNS - patterns: - - pattern-either: - - pattern-regex: ^(.*TLSv1|.*SSLv.*)$ - - pattern-regex: ^(.*TLSv1,.*|.*TLSv1.1.*) + - pattern-inside: javax.crypto.Cipher.getInstance("$ALG") + - metavariable-regex: + metavariable: $ALG + regex: ^(DESede)/.* severity: WARNING - - id: java_crypto_rule-HTTPUrlConnectionHTTPRequest + - id: scala_crypto_rule-CipherECBMode languages: - - java - message: "Detected an HTTP request sent via HttpURLConnection or URLConnection.\nThis could lead to sensitive information being sent over an insecure \nchannel, as HTTP does not encrypt data. Transmitting data over HTTP \nexposes it to potential interception by attackers, risking data \nintegrity and confidentiality. Using HTTP for transmitting sensitive \ndata such as passwords, personal information, or financial details can \nlead to information disclosure.\n\nTo mitigate the issue, switch to HTTPS to ensure all data transmitted \nis securely encrypted. This helps protect against eavesdropping and \nman-in-the-middle attacks. Modify the URL in your code from HTTP to \nHTTPS and ensure the server supports HTTPS.\n\nSecure Code Example:\n```\nprivate static void safe() {\n try {\n URL url = new URL(\"https://example.com/api/data\"); // Changed to HTTPS\n HttpURLConnection con = (HttpURLConnection) url.openConnection();\n con.setRequestMethod(\"GET\");\n\n int status = con.getResponseCode();\n if (status == HttpURLConnection.HTTP_OK) { \n BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n String inputLine;\n StringBuilder response = new StringBuilder();\n while ((inputLine = in.readLine()) != null) {\n response.append(inputLine);\n }\n in.close();\n System.out.println(\"Response: \" + response.toString());\n } else {\n System.out.println(\"HTTP error code: \" + status);\n }\n con.disconnect();\n } catch (Exception e) {\n e.printStackTrace();\n }\n}\n```\n" + - scala + message: | + An authentication cipher mode which provides better confidentiality of the encrypted data + should be used instead of Electronic Code Book (ECB) mode, which does not provide good + confidentiality. Specifically, ECB mode produces the same output for the same input each time. + This allows an attacker to intercept and replay the data. metadata: category: security - confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - subcategory: - - vuln + cwe: CWE-326 + security-severity: Medium + shortDescription: Inadequate Encryption Strength technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information + - scala patterns: - - pattern: | - "=~/[Hh][Tt][Tt][Pp]://.*/" - - pattern-either: - - pattern-inside: | - URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); - ... - $CON = (HttpURLConnection) $URL.openConnection(...); - ... - $CON.$FUNC(...); - - pattern-inside: | - URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); - ... - $CON = $URL.openConnection(...); - ... - $CON.$FUNC(...); - severity: WARNING - - id: java_crypto_rule-HttpComponentsRequest + - pattern-inside: javax.crypto.Cipher.getInstance("...") + - pattern-regex: (AES|DES(ede)?)(/ECB/*) + severity: ERROR + - id: scala_crypto_rule-CipherIntegrity languages: - - java - message: "Detected an HTTP GET request sent via Apache HTTP Components. Sending data\nover HTTP can expose sensitive information to interception or modification\nby attackers, as HTTP does not encrypt the data transmitted. It is critical\nto use HTTPS, which encrypts the communication, to protect the confidentiality\nand integrity of data in transit.\n\nTo mitigate the issue, ensure all data transmitted between the client and \nserver is sent over HTTPS. Update all HTTP URLs to HTTPS and configure your \nserver to redirect HTTP requests to HTTPS. Additionally, implement HSTS \n(HTTP Strict Transport Security) to enforce secure connections.\nSecure Code Example:\n```\nprivate static void safe() {\n CloseableHttpClient httpclient = HttpClients.createDefault();\n CloseableHttpResponse response = httpclient.execute(new HttpPost(\"https://example.com\"));\n}\n```\n" + - scala + message: | + The ciphertext produced is susceptible to alteration by an adversary. This mean that the + cipher provides no way to detect that the data has been tampered with. If the ciphertext can be + controlled by an attacker, it could be altered without detection. metadata: category: security - confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://hc.apache.org/httpcomponents-client-ga/quickstart.html - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - subcategory: - - vuln + cwe: CWE-353 + security-severity: Medium + shortDescription: Missing Support for Integrity Check technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information - mode: taint - pattern-sinks: - - pattern: (org.apache.http.impl.client.CloseableHttpClient $A).execute($HTTPREQ); - pattern-sources: - - pattern: | - "=~/^http://.+/i" - severity: WARNING - - id: java_crypto_rule-HttpGetHTTPRequest + - scala + patterns: + - pattern-inside: javax.crypto.Cipher.getInstance("...") + - pattern-either: + - pattern-regex: (/CBC/PKCS5Padding) + - pattern-regex: (AES|DES(ede)?)(/ECB/*) + - pattern-regex: (AES|DES(ede)?)(/CBC/*) + - pattern-regex: (AES|DES(ede)?)(/OFB/*) + - pattern-regex: (AES|DES(ede)?)(/CTR/*) + - pattern-not-regex: .*/(CCM|CWC|OCB|EAX|GCM)/.* + - pattern-not-regex: ^(RSA)/.* + - pattern-not-regex: ^(ECIES)$ + severity: ERROR + - id: scala_crypto_rule-CipherPaddingOracle languages: - - java - message: "Detected an HTTP GET request sent via HttpGet. Sending data over HTTP can\nexpose sensitive information to interception or modification by attackers,\nas HTTP does not encrypt the data transmitted. It is critical to use\nHTTPS, which encrypts the communication, to protect the confidentiality\nand integrity of data in transit.\n\nTo mitigate the issue, ensure all data transmitted between the client and \nserver is sent over HTTPS. Update all HTTP URLs to HTTPS and configure your \nserver to redirect HTTP requests to HTTPS. Additionally, implement HSTS \n(HTTP Strict Transport Security) to enforce secure connections.\n\nSecure Code Example:\n```\nprivate static void safe() throws IOException {\n HttpGet httpGet = new HttpGet(\"https://example.com\");\n HttpClients.createDefault().execute(httpGet);\n}\n```\n" + - scala + message: | + This specific mode of CBC with PKCS5Padding is susceptible to padding oracle attacks. An + adversary could potentially decrypt the message if the system exposed the difference between + plaintext with invalid padding or valid padding. The distinction between valid and invalid + padding is usually revealed through distinct error messages being returned for each condition. metadata: category: security - confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - subcategory: - - vuln + cwe: CWE-696 + security-severity: Medium + shortDescription: Incorrect Behavior Order technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information - mode: taint - pattern-sinks: - - patterns: - - pattern: | - $R = new org.apache.http.client.methods.HttpGet($PROT); - ... - $CLIENT. ... .execute($R, ...); - - focus-metavariable: $PROT - pattern-sources: - - pattern: | - "=~/^http:\/\/.+/i" - severity: WARNING - - id: java_crypto_rule_JwtDecodeWithoutVerify + - scala + patterns: + - pattern-inside: javax.crypto.Cipher.getInstance("...") + - pattern-regex: (/CBC/PKCS5Padding) + - pattern-not-regex: ^(RSA)/.* + - pattern-not-regex: ^(ECIES)$ + severity: ERROR + - id: scala_crypto_rule-CustomMessageDigest languages: - - java - message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token. + - scala + message: | + Implementing a custom MessageDigest is error-prone. National Institute of Standards and + Technology(NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or + SHA-512/256. metadata: category: security - confidence: MEDIUM - cwe: CWE-347 - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - references: https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures - security-severity: MEDIUM - shortDescription: Improper verification of cryptographic signature - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: vuln - technology: jwt - vulnerability_class: Improper Authentication + cwe: CWE-327 + security-severity: Medium + shortDescription: Use of a Broken or Risky Cryptographic Algorithm + technology: + - scala patterns: - pattern: | - com.auth0.jwt.JWT.decode(...); - - pattern-not-inside: |- - class $CLASS { + class $CLAZZ extends java.security.MessageDigest(...) { ... - $RETURNTYPE $FUNC (...) { - ... - $VERIFIER.verify(...); - ... - } } severity: WARNING - - id: java_crypto_rule-SpringFTPRequest + - id: scala_crypto_rule-DefaultHTTPClient languages: - - java - message: "This pattern detects configurations where the Spring Integration FTP plugin \nis used to set up connections to FTP servers. FTP is an insecure protocol \nthat transmits data, including potentially sensitive information, in plaintext. \nThis can expose personal identifiable information (PII) or other sensitive data \nto interception by attackers during transmission. \n\nTo mitigate the vulnerability, switch to a secure protocol such as SFTP or FTPS \nthat encrypts the connection to prevent data exposure. Ensure that any method \nused to set the host for an FTP session does not use plaintext FTP. \n\nSecure Code Example:\n```\npublic SessionFactory safe(FtpSessionFactoryProperties properties) {\n DefaultFtpSessionFactory ftpSessionFactory = new DefaultFtpSessionFactory();\n ftpSessionFactory.setHost(\"sftp://example.com\");\n ftpSessionFactory.setPort(properties.getPort());\n ftpSessionFactory.setUsername(properties.getUsername());\n ftpSessionFactory.setPassword(properties.getPassword());\n ftpSessionFactory.setClientMode(properties.getClientMode().getMode());\n return ftpSessionFactory;\n}\n```\n" + - scala + message: | + DefaultHttpClient with default constructor is not compatible with TLS 1.2 metadata: category: security - confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://docs.spring.io/spring-integration/api/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.html#setClientMode-int- - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - subcategory: - - vuln + cwe: CWE-326 + security-severity: Info + shortDescription: Inadequate encryption strength technology: - - spring - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information - mode: taint - pattern-sinks: - - patterns: - - pattern: | - (org.springframework.integration.ftp.session.DefaultFtpSessionFactory - $SF).setHost($URL); - - focus-metavariable: $URL - pattern-sources: - - pattern: | - "=~/^ftp://.+/i" + - scala + patterns: + - pattern: new org.apache.http.impl.client.DefaultHttpClient(...) severity: WARNING - - id: java_crypto_rule-SpringHTTPRequestRestTemplate + - id: scala_crypto_rule-HazelcastSymmetricEncryption languages: - - java - message: "This rule detects instances where Java Spring's RestTemplate API sends \nrequests to non-secure (http://) URLs. Sending data over HTTP is vulnerable \nas it does not use TLS encryption, exposing the data to interception, \nmodification, or redirection by attackers. \n\nTo mitigate this vulnerability, modify the request URLs to use HTTPS instead, \nwhich ensures that the data is encrypted during transit and prevents from\nMITM attacks. \n\nSecure Code Example:\n```\npublic void safe(Object obj) throws Exception {\n RestTemplate restTemplate = new RestTemplate();\n restTemplate.put(URI.create(\"https://example.com\"), obj);\n}\n``` \n" + - scala + message: | + The network communications for Hazelcast is configured to use a symmetric cipher (probably DES + or Blowfish). Those ciphers alone do not provide integrity or secure authentication. The use of + asymmetric encryption is preferred. metadata: category: security - confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#delete-java.lang.String-java.util.Map- - - https://www.baeldung.com/rest-template - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - subcategory: - - vuln + cwe: CWE-326 + security-severity: Medium + shortDescription: Inadequate Encryption Strength technology: - - spring - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information - mode: taint - pattern-sinks: - - patterns: - - pattern: | - (org.springframework.web.client.RestTemplate $RESTTEMP).$FUNC($URL, ...); - - focus-metavariable: $URL - - metavariable-regex: - metavariable: $FUNC - regex: (delete|doExecute|exchange|getForEntity|getForObject|headForHeaders|optionsForAllow|patchForObject|postForEntity|postForLocation|postForObject|put|execute) - pattern-sources: - - pattern: | - "=~/^http:\/\/.+/i" + - scala + patterns: + - pattern: new com.hazelcast.config.SymmetricEncryptionConfig() severity: WARNING - - id: java_crypto_rule-TLSUnsafeRenegotiation + - id: scala_crypto_rule-InsufficientKeySizeRsa languages: - - java - message: "This code enables unsafe renegotiation in SSL/TLS connections, which is\nvulnerable to man-in-the-middle attacks. In such attacks, an attacker\ncould inject chosen plaintext at the beginning of the secure\ncommunication, potentially compromising the security of data transmission. If \nexploited, this vulnerability can lead to unauthorized access to sensitive \ndata, data manipulation, and potentially full system compromise depending on \nthe data and operations protected by the TLS session.\n\nTo mitigate this vulnerability, disable unsafe renegotiation in the Java \napplication. Ensure that only secure renegotiation is allowed by setting the \nsystem property `sun.security.ssl.allowUnsafeRenegotiation` to `false`. \n\nSecure code example:\n```\npublic void safe() {\n java.lang.System.setProperty(\"sun.security.ssl.allowUnsafeRenegotiation\", false);\n}\n```\n" + - scala + message: | + Detected an insufficient key size for DSA. NIST recommends a key size + of 2048 or higher. metadata: category: security - confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://www.oracle.com/java/technologies/javase/tlsreadme.html - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - subcategory: - - vuln - technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information + cwe: CWE-326 + security-severity: Medium + shortDescription: Inadequate Encryption Strength patterns: - - pattern: | - java.lang.System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", $TRUE); - - metavariable-pattern: - metavariable: $TRUE - pattern-either: - - pattern: | - true - - pattern: | - "true" - - pattern: | - Boolean.TRUE + - pattern-either: + - patterns: + - pattern-inside: | + $GEN = KeyPairGenerator.getInstance($ALG, ...); + ... + - pattern-either: + - pattern: $VAR.initialize($SIZE, ...) + - pattern: new java.security.spec.RSAKeyGenParameterSpec($SIZE, ...) + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE + - metavariable-regex: + metavariable: $ALG + regex: '"(RSA|DSA)"' severity: WARNING - - id: java_crypto_rule-TelnetRequest + - id: scala_crypto_rule-NullCipher languages: - - java - message: "Checks for attempts to connect through telnet. Telnet is an outdated\nprotocol that transmits all data, including sensitive information like\npasswords, in clear text. This exposes it to interception and\neavesdropping on unsecured networks.\n\nTo mitigate this issue, replace Telnet usage with more secure protocols \nsuch as SSH (Secure Shell), which provides encrypted communication. Use \nthe SSH functionality provided by libraries like JSch or Apache MINA SSHD \nfor secure data transmission.\n\nSecure Code Example:\n```\nimport com.jcraft.jsch.JSch;\nimport com.jcraft.jsch.Session;\n\npublic class SecureConnector {\n public static void main(String[] args) {\n try {\n JSch jsch = new JSch();\n Session session = jsch.getSession(\"username\", \"hostname\", 22);\n session.setPassword(\"password\");\n session.setConfig(\"StrictHostKeyChecking\", \"no\");\n session.connect();\n System.out.println(\"Connected securely.\");\n } catch (Exception e) {\n System.err.println(\"Secure connection failed: \" + e.getMessage());\n }\n }\n}\n```\n" + - scala + message: | + The NullCipher implements the Cipher interface by returning ciphertext identical to the + supplied plaintext. In a few contexts, such as testing, a NullCipher may be appropriate. Avoid + using the NullCipher. Its accidental use can introduce a significant confidentiality risk. metadata: category: security - confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://commons.apache.org/proper/commons-net/javadocs/api-3.6/org/apache/commons/net/telnet/TelnetClient.html - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - subcategory: - - vuln + cwe: CWE-327 + security-severity: Medium + shortDescription: Use of a Broken or Risky Cryptographic Algorithm technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information - pattern: | - (org.apache.commons.net.telnet.TelnetClient $TELNETCLIENT).connect(...); + - scala + pattern: new javax.crypto.NullCipher() severity: WARNING - - id: java_crypto_rule-UnirestHTTPRequest + - id: scala_crypto_rule-RsaNoPadding languages: - - java - message: "This application uses the Unirest library to send\nnetwork requests to URLs starting with 'http://'. Communicating over HTTP\nis considered insecure because it does not encrypt traffic with TLS\n(Transport Layer Security), exposing data to potential interception or\nmanipulation by attackers.\n\nTo mitigate the issue, modify the request URL to begin with 'https://' \ninstead of 'http://'. Using HTTPS ensures that the data is encrypted and \nsecure during transmission. Review all instances where HTTP is used and \nupdate them to use HTTPS to prevent security risks.\n\nSecure Code Example:\n```\nimport kong.unirest.core.Unirest;\n\npublic void safe() {\n Unirest.get(\"https://httpbin.org\")\n .queryString(\"fruit\", \"apple\")\n .queryString(\"droid\", \"R2D2\")\n .asString();\n}\n```\n" + - scala + message: | + The software uses the RSA algorithm but does not incorporate Optimal Asymmetric + Encryption Padding (OAEP), which might weaken the encryption. metadata: category: security - confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: CWE-780 owasp: - A3:2017-Sensitive Data Exposure - A02:2021-Cryptographic Failures - references: - - https://kong.github.io/unirest-java/#requests - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - subcategory: - - vuln + security-severity: Medium + shortDescription: Use of RSA Algorithm without OAEP + patterns: + - pattern: javax.crypto.Cipher.getInstance("$ALG",...) + - metavariable-regex: + metavariable: $ALG + regex: .*NoPadding.* + severity: WARNING + - id: scala_crypto_rule-WeakMessageDigest + languages: + - scala + message: | + DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage + of AES block ciphers instead of DES. + metadata: + category: security + cwe: CWE-326 + security-severity: Medium + shortDescription: Inadequate Encryption Strength technology: - - unirest - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information + - scala patterns: - - pattern: | - Unirest.$METHOD("=~/[hH][tT][tT][pP]://.*/") + - pattern-either: + - pattern: MessageDigest.getInstance("$ALG", ...) + - pattern: Signature.getInstance("$ALG", ...) + - metavariable-regex: + metavariable: $ALG + regex: (.*(MD5|MD4|MD2|SHA1|SHA-1).*) severity: WARNING - - id: java_crypto_rule-UseOfRC2 + - id: scala_crypto_rule-WeakTLSProtocol languages: - - java - message: "Use of RC2, a deprecated cryptographic algorithm vulnerable to related-key\nattacks, was detected. Modern cryptographic standards recommend the\nadoption of algorithms that integrate message integrity to ensure the\nciphertext remains unaltered.\n\nTo mitigate the issue, use any of the below algorithms instead:\n1. `ChaCha20Poly1305` - Preferred for its simplicity and speed, suitable for \nenvironments where cryptographic acceleration is absent.\n2. `AES-256-GCM` - Highly recommended when hardware support is available, \ndespite being somewhat slower than `ChaCha20Poly1305`. It is crucial to avoid \nnonce reuse with AES-256-GCM to prevent security compromises.\n\nSecure code example using `ChaCha20Poly1305` in Java:\n```\npublic void encryptAndDecrypt() throws Exception {\n SecureRandom random = new SecureRandom();\n byte[] secretKey = new byte[32]; // 256-bit key\n byte[] nonce = new byte[12]; // 96-bit nonce\n random.nextBytes(secretKey);\n random.nextBytes(nonce);\n\n Cipher cipher = Cipher.getInstance(\"ChaCha20-Poly1305/None/NoPadding\");\n SecretKeySpec keySpec = new SecretKeySpec(secretKey, \"ChaCha20\");\n GCMParameterSpec spec = new GCMParameterSpec(128, nonce);\n\n cipher.init(Cipher.ENCRYPT_MODE, keySpec, spec);\n byte[] plaintext = \"Secret text\".getBytes(StandardCharsets.UTF_8);\n byte[] ciphertext = cipher.doFinal(plaintext);\n System.out.println(\"Encrypted: \" + Base64.getEncoder().encodeToString(ciphertext));\n\n cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);\n byte[] decrypted = cipher.doFinal(ciphertext);\n System.out.println(\"Decrypted: \" + new String(decrypted, StandardCharsets.UTF_8));\n}\n```\nFor more on Java Cryptography, refer:\nhttps://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html\n" + - scala + message: | + A HostnameVerifier that accept any host are often use because of certificate + reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middleattacks + attacks since the client will trust any certificate. metadata: category: security - confidence: HIGH - cwe: CWE-327 - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - security-severity: MEDIUM - shortDescription: Use of a broken or risky cryptographic algorithm - subcategory: - - vuln + cwe: CWE-295 + security-severity: Medium + shortDescription: Improper Certificate Validation + patterns: + - pattern-either: + - pattern: new org.apache.http.impl.client.DefaultHttpClient() + - pattern: javax.net.ssl.SSLContext.getInstance("SSL") + - patterns: + - pattern-inside: | + import javax.net.ssl._ + ... + - pattern: SSLContext.getInstance("SSL") + severity: WARNING + - id: scala_endpoint_rule-JaxRsEndpoint + languages: + - scala + message: | + This method is part of a REST Web Service (JSR311). The security of this web service should be + analyzed. For example: + - Authentication, if enforced, should be tested. + - Access control, if enforced, should be tested. + - The inputs should be tracked for potential vulnerabilities. + - The communication should ideally be over SSL. + - If the service supports writes (e.g., via POST), its vulnerability to CSRF should be + investigated. + metadata: + category: security + cwe: CWE-348 + security-severity: Medium + shortDescription: Use of less trusted source technology: - - java - pattern-either: - - pattern: | - javax.crypto.Cipher.getInstance("RC2") + - scala + mode: taint + pattern-sinks: + - pattern: <...$VAR...> + pattern-sources: - patterns: - pattern-inside: | - class $CLS{ - ... - String $ALG = "RC2"; - ... - } - - pattern: | - javax.crypto.Cipher.getInstance($ALG); - severity: WARNING - - id: java_crypto_rule-UseOfRC4 + @javax.ws.rs.Path("...") + def $FUNC(..., $VAR: $TYPE, ...) = ... + - pattern: $VAR + severity: INFO + - id: scala_endpoint_rule-JaxWsEndpoint languages: - - java - message: "Use of RC4 was detected. RC4 is vulnerable to several types of attacks,\nincluding stream cipher attacks where attackers can recover plaintexts by\nanalyzing a large number of encrypted messages, and bit-flipping attacks\nthat can alter messages without knowing the encryption key.\n\nTo mitigate the issue, use any of the below algorithms instead:\n1. `ChaCha20Poly1305` - Preferred for its simplicity and speed, suitable for \nenvironments where cryptographic acceleration is absent.\n2. `AES-256-GCM` - Highly recommended when hardware support is available, \ndespite being somewhat slower than `ChaCha20Poly1305`. It is crucial to avoid \nnonce reuse with AES-256-GCM to prevent security compromises.\n\nSecure code example using `ChaCha20Poly1305` in Java:\n```\npublic void encryptAndDecrypt() throws Exception {\n SecureRandom random = new SecureRandom();\n byte[] secretKey = new byte[32]; // 256-bit key\n byte[] nonce = new byte[12]; // 96-bit nonce\n random.nextBytes(secretKey);\n random.nextBytes(nonce);\n\n Cipher cipher = Cipher.getInstance(\"ChaCha20-Poly1305/None/NoPadding\");\n SecretKeySpec keySpec = new SecretKeySpec(secretKey, \"ChaCha20\");\n GCMParameterSpec spec = new GCMParameterSpec(128, nonce);\n\n cipher.init(Cipher.ENCRYPT_MODE, keySpec, spec);\n byte[] plaintext = \"Secret text\".getBytes(StandardCharsets.UTF_8);\n byte[] ciphertext = cipher.doFinal(plaintext);\n System.out.println(\"Encrypted: \" + Base64.getEncoder().encodeToString(ciphertext));\n\n cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);\n byte[] decrypted = cipher.doFinal(ciphertext);\n System.out.println(\"Decrypted: \" + new String(decrypted, StandardCharsets.UTF_8));\n}\n```\nFor more information, refer:\nhttps://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions\n" + - scala + message: | + This method is part of a SOAP Web Service (JSR224). The security of this web service should be + analyzed. For example: + - Authentication, if enforced, should be tested. + - Access control, if enforced, should be tested. + - The inputs should be tracked for potential vulnerabilities. + - The communication should ideally be over SSL. metadata: category: security - confidence: HIGH - cwe: CWE-327 - impact: MEDIUM - likelihood: MEDIUM + cwe: CWE-348 owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html - security-severity: MEDIUM - shortDescription: Use of a broken or risky cryptographic algorithm - subcategory: - - vuln + - A7:2017-Cross-Site Scripting (XSS) + - A03:2021-Injection + security-severity: Info + shortDescription: Use of less trusted source technology: - - java - pattern-either: - - pattern: | - javax.crypto.Cipher.getInstance("RC4") + - scala + mode: taint + pattern-sinks: + - pattern: <...$VAR...> + pattern-sources: - patterns: - pattern-inside: | - class $CLS{ - ... - String $ALG = "RC4"; - ... - } - - pattern: | - javax.crypto.Cipher.getInstance($ALG); - severity: WARNING - - id: java_deserialization_rule-InsecureJmsDeserialization + @javax.jws.WebMethod(...) + def $FUNC(..., $VAR: $TYPE, ...) = ... + - pattern: $VAR + severity: INFO + - id: scala_endpoint_rule-UnencryptedSocket languages: - - java - message: "Deserialization of untrusted JMS ObjectMessage can lead to arbitrary \ncode execution. This vulnerability occurs when `ObjectMessage.getObject()` \nis called to deserialize the payload of an ObjectMessage, potentially \nallowing remote attackers to execute arbitrary code with the permissions \nof the JMS MessageListener application. \n\nTo mitigate the issue, avoid deserialization of untrusted data and \nconsider alternative message formats or explicit whitelisting of \nallowable classes for deserialization.\n\nTo implement allowlisting, override the ObjectInputStream#resolveClass() \nmethod to limit deserialization to allowed classes only. This prevents \ndeserialization of any class except those explicitly permitted, such as \nin the following example that restricts deserialization to the Bicycle \nclass only:\n\n```\n// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html\npublic class LookAheadObjectInputStream extends ObjectInputStream {\n public LookAheadObjectInputStream(InputStream inputStream) throws IOException {\n super(inputStream);\n }\n /**\n * Only deserialize instances of our expected Bicycle class\n */\n @Override\n protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {\n if (!desc.getName().equals(Bicycle.class.getName())) {\n throw new InvalidClassException(\"Unauthorized deserialization attempt\", desc.getName());\n }\n return super.resolveClass(desc);\n }\n}\n```\n" + - scala + message: | + Beyond using an SSL socket, you need to make sure your use of SSLSocketFactory + does all the appropriate certificate validation checks to make sure you are not + subject to man-in-the-middle attacks. Please read the OWASP Transport Layer + Protection Cheat Sheet for details on how to do this correctly. metadata: category: security - confidence: MEDIUM - cwe: CWE-502 - cwe2021-top25: "true" - cwe2022-top25: "true" - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW + cwe: CWE-319 owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - references: - - https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities-wp.pdf - security-severity: High - shortDescription: Deserialization of untrusted data - subcategory: - - vuln - technology: - - java - vulnerability_class: - - 'Insecure Deserialization ' + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + security-severity: Info + shortDescription: Cleartext transmission of sensitive information patterns: - - pattern-inside: | - class $JMS_LISTENER implements MessageListener { - ... - public void onMessage(Message $JMS_MSG) { - ... - } - } - - pattern: $Y.getObject(...); + - pattern: new java.net.Socket(...) + severity: WARNING + - id: scala_endpoint_rule-UnvalidatedRedirect + languages: + - scala + message: | + Unvalidated redirects occur when an application redirects a user to a + destination URL specified by a user supplied parameter that is not validated. + Such vulnerabilities can be used to facilitate phishing attacks. + metadata: + category: security + cwe: CWE-601 + security-severity: Info + shortDescription: URL Redirection to Untrusted Site ('Open Redirect') + patterns: + - pattern-either: + - patterns: + - pattern: '($REQ: HttpServletResponse).sendRedirect(...)' + - pattern-not: '($REQ: HttpServletResponse).sendRedirect("...")' + - patterns: + - pattern: '($REQ: HttpServletResponse).addHeader(...)' + - pattern-not: '($REQ: HttpServletResponse).addHeader("...", "...")' + - patterns: + - pattern: '($REQ: HttpServletResponse).encodeURL(...)' + - pattern-not: '($REQ: HttpServletResponse).encodeURL("...")' + - patterns: + - pattern: '($REQ: HttpServletResponse).encodeRedirectUrl(...)' + - pattern-not: '($REQ: HttpServletResponse).encodeRedirectUrl("...")' severity: ERROR - - id: java_endpoint_rule-ManuallyConstructedURLs + - id: scala_endpoint_rule-WeakHostNameVerification languages: - - java + - scala message: | - User data flows into the host portion of this manually-constructed URL. - This could allow an attacker to send data to their own server, potentially - exposing sensitive data such as cookies or authorization information sent - with this request. They could also probe internal servers or other - resources that the server running this code can access. (This is called - server-side request forgery, or SSRF.) Do not allow arbitrary hosts. - Instead, create an allowlist for approved hosts hardcode the correct host, - or ensure that the user data can only affect the path or parameters. - - Example of using allowlist: - ``` - ArrayList allowlist = (ArrayList) - Arrays.asList(new String[] { "https://example.com/api/1", "https://example.com/api/2", "https://example.com/api/3"}); - - if(allowlist.contains(url)){ - ... - } - ``` + A HostnameVerifier that accept any host are often use because of certificate + reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middle + attacks since the client will trust any certificate. metadata: category: security - confidence: MEDIUM - cwe: CWE-918 - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A1:2017-Injection - - A10:2021-Server-Side Request Forgery - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - security-severity: CRITICAL - shortDescription: Detect manually constructed URLs - subcategory: - - vuln - technology: - - java - - spring - vulnerability_class: - - Server-Side Request Forgery (SSRF) - mode: taint - options: - interfile: true - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: "if($VALIDATION){\n ...\n new URL($ONEARG);\n ...\n} \n" - - pattern: | - $A = $VALIDATION; - ... - if($A){ - ... - new URL($ONEARG); - ... - } - - metavariable-pattern: - metavariable: $VALIDATION - pattern-either: - - pattern: "$AL.contains(...) \n" - - pattern: | - $AL.indexOf(...) != -1 - pattern-sinks: + cwe: CWE-295 + security-severity: Info + shortDescription: Improper Certificate Validation + patterns: - pattern-either: - - pattern: new URL($ONEARG) - patterns: - - pattern-either: - - pattern: | - "$URLSTR" + ... - - pattern: | - "$URLSTR".concat(...) - - patterns: - - pattern-inside: | - StringBuilder $SB = new StringBuilder("$URLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$URLSTR"; - ... - - pattern: $VAR += ... - - patterns: - - pattern: String.format("$URLSTR", ...) - - pattern-not: String.format("$URLSTR", "...", ...) - - patterns: - - pattern-inside: | - String $VAR = "$URLSTR"; - ... - - pattern: String.format($VAR, ...) - - metavariable-regex: - metavariable: $URLSTR - regex: http(s?)://%(v|s|q).* - pattern-sources: - - patterns: - - pattern-either: - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + class $V extends HostnameVerifier { ... } + - pattern-either: + - pattern: def verify(...) = true + - pattern: | + def verify(...) = { + return true + } + - patterns: - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + class $V extends X509TrustManager { ... } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE - severity: ERROR - - id: java_file_rule_rule-FilePathTraversalHttpServlet + - pattern-either: + - pattern: 'def checkClientTrusted(...): Unit = {}' + - pattern: 'def checkServerTrusted(...): Unit = {}' + - pattern: def checkClientTrusted(...) = {} + - pattern: def checkServerTrusted(...) = {} + - pattern: 'def getAcceptedIssuers(): Array[X509Certificate] = null' + - pattern: 'def getAcceptedIssuers(): Array[X509Certificate] = {}' + severity: WARNING + - id: scala_file_rule-FileUploadFileName languages: - - java - message: "Detected a potential path traversal. A malicious actor could control\nthe location of this file, to include going backwards in the directory\nwith '../'. \n\nTo address this, ensure that user-controlled variables in file\npaths are sanitized. You may also consider using a utility method such as\norg.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file\nname from the path.\n\nExample code using FilenameUtils.getName(...)\n\n```\npublic void ok(HttpServletRequest request, HttpServletResponse response)\n throws ServletException, IOException {\n String image = request.getParameter(\"image\");\n File file = new File(\"static/images/\", FilenameUtils.getName(image));\n\n if (!file.exists()) {\n log.info(image + \" could not be created.\");\n response.sendError();\n }\n\n response.sendRedirect(\"/index.html\");\n}\n```\n" + - scala + message: | + The filename provided by the FileUpload API can be tampered with by the client to reference + unauthorized files. The provided filename should be properly validated to ensure it's properly + structured, contains no unauthorized path characters (e.g., / \), and refers to an authorized + file. metadata: category: security - confidence: MEDIUM cwe: CWE-22 - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - A5:2017-Broken Access Control - A01:2021-Broken Access Control - references: - - https://www.owasp.org/index.php/Path_Traversal - security-severity: CRITICAL - shortDescription: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN + security-severity: Info + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') technology: - - java - vulnerability_class: - - Path Traversal - mode: taint - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: + - scala + patterns: + - pattern: | + def $FUNC (..., $REQ: HttpServletRequest, ... ) = { + ... + val $FILES = ($SFU: ServletFileUpload).parseRequest($REQ) + ... + for ($FILE <- $FILES.asScala) { + ... + } + } + - pattern: $ITEM.getName() + severity: WARNING + - id: scala_file_rule-FilenameUtils + languages: + - scala + message: | + A file is opened to read its content. The filename comes from an input + parameter. If an unfiltered parameter is passed to this file API, files from an + arbitrary filesystem location could be read. + metadata: + category: security + cwe: CWE-22 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + technology: + - scala + pattern-either: - patterns: + - pattern-inside: | + import org.apache.commons.io.FilenameUtils._ + ... - pattern-either: - - pattern: | - (java.io.File $FILE) = ... - - pattern: | - (java.io.FileOutputStream $FOS) = ... - - pattern: | - new java.io.FileInputStream(...) - pattern-sources: + - pattern: normalize(...) + - pattern: getExtension(...) + - pattern: isExtensions(...) + - pattern: isExtension(...) + - pattern: getName(...) + - pattern: getBaseName(...) - patterns: - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); ... - for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { - ... - } - - pattern: | - $COOKIE.getValue(...) - - patterns: - - pattern-inside: | - $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(...); - ... - - pattern: | - $PARAM = $VALS[$INDEX]; - severity: ERROR - - id: java_inject_rule-EnvInjection + - pattern: org.apache.commons.io.FilenameUtils.normalize(...) + - pattern: org.apache.commons.io.FilenameUtils.getExtension(...) + - pattern: org.apache.commons.io.FilenameUtils.isExtensions(...) + - pattern: org.apache.commons.io.FilenameUtils.isExtension(...) + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + - pattern: org.apache.commons.io.FilenameUtils.getBaseName(...) + severity: WARNING + - id: scala_form_rule-FormValidate languages: - - java - message: "Detected input from a HTTPServletRequest going into the environment\nvariables of an 'exec' command. The user input is passed directly to\nthe Runtime.exec() function to set an environment variable. This allows \nmalicious input from the user to modify the command that will be executed.\nTo remediate this, do not pass user input directly to Runtime.exec().\nValidate any user input before using it to set environment variables \nor command arguments. Consider using an allow list of allowed values\nrather than a deny list. If dynamic commands must be constructed, use\na map to look up valid values based on user input instead of using \nthe input directly.\nExample of safely executing an OS command:\n```\npublic void doPost(HttpServletRequest request, HttpServletResponse response)\n throws ServletException, IOException {\n response.setContentType(\"text/html;charset=UTF-8\");\n\n String param = \"\";\n if (request.getHeader(\"UserDefined\") != null) {\n param = request.getHeader(\"UserDefined\");\n }\n\n param = java.net.URLDecoder.decode(param, \"UTF-8\");\n String cmd = \"/bin/cmd\";\n\n String[] allowList = {\"FOO=true\",\"FOO=false\",\"BAR=true\", \"BAR=false\"}\n if(Arrays.asList(allowList).contains(param)){\n String[] argsEnv = {param};\n }\n \n Runtime r = Runtime.getRuntime();\n\n try {\n Process p = r.exec(cmd, argsEnv);\n printOSCommandResults(p, response); \n } catch (IOException e) {\n System.out.println(\"Problem executing command\");\n response.getWriter()\n .println(org.owasp.esapi.ESAPI.encoder().encodeForHTML(e.getMessage()));\n return;\n }\n```\n" + - scala + message: | + Form inputs should have minimal input validation. Preventive validation helps provide defense + in depth against a variety of risks. metadata: category: security - confidence: MEDIUM - cwe: CWE-78 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A1:2017-Injection - - A03:2021-Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - security-severity: HIGH - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') - subcategory: - - vuln + cwe: CWE-1289 + security-severity: Info + shortDescription: Improper validation of unsafe equivalence in input + patterns: + - pattern-inside: | + class $CLASS extends $SC { + ... + } + - metavariable-regex: + metavariable: $SC + regex: (ActionForm|ValidatorForm) + - pattern-not: public void validate() { ... } + severity: WARNING + - id: scala_inject_rule-AWSQueryInjection + languages: + - scala + message: | + Constructing SimpleDB queries containing user input can allow an attacker to view unauthorized + records. + metadata: + category: security + cwe: CWE-943 + security-severity: Info + shortDescription: Improper Neutralization of Special Elements in Data Query Logic technology: - - java - vulnerability_class: - - Other + - scala mode: taint - pattern-sanitizers: + pattern-sinks: + - pattern: new com.amazonaws.services.simpledb.model.SelectRequest($QUERY, ...); - patterns: - - pattern-either: - - pattern: | - if($VALIDATION){ - ... - } - - patterns: - - pattern-inside: | - $A = $VALIDATION; - ... - - pattern: | - if($A){ - ... - } + - pattern-inside: | + $DB.select(($SR: com.amazonaws.services.simpledb.model.SelectRequest).withSelectExpression($QUERY,...)); + - pattern: $QUERY - metavariable-pattern: - metavariable: $VALIDATION + metavariable: $DB pattern-either: - - pattern: | - $AL.contains(...) - pattern-sinks: - - pattern-either: - - patterns: - - pattern: (java.lang.Runtime $R).exec($CMD, $ENV_ARGS, ...); - - focus-metavariable: $ENV_ARGS - - patterns: - - pattern: (ProcessBuilder $PB).environment().put($...ARGS); - - focus-metavariable: $...ARGS - - patterns: - - pattern: | - $ENV = (ProcessBuilder $PB).environment(); - ... - $ENV.put($...ARGS); - - focus-metavariable: $...ARGS + - pattern: '($DB: com.amazonaws.services.simpledb.AmazonSimpleDB)' + - pattern: '($DB: com.amazonaws.services.simpledb.AmazonSimpleDBClient)' pattern-sources: - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) + - pattern-inside: | + def $FUNC(..., $REQ: HttpServletRequest, ...): $TYPE = { + ... + } + - pattern: $REQ - patterns: - pattern-inside: | - $FUNC(..., $VAR, ...) { - ... + def $FUNC(..., $X: $TYPE, ...): $RET_TYPE = { + ... + $QUERY = <...$X...> + ... } - - pattern: $VAR + - pattern: $QUERY severity: ERROR - - id: java_xxe_rule-DisallowDoctypeDeclFalse + - id: scala_inject_rule-BeanPropertyInjection languages: - - java - message: "DOCTYPE declarations are enabled for $DBFACTORY. Without prohibiting\nexternal entity declarations, this is vulnerable to XML external entity\nattacks. In an XXE attack, an attacker can exploit the processing of external \nentity references within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise.\n\nTo mitigate this vulnerability, disable this by setting the feature\n\"http://apache.org/xml/features/disallow-doctype-decl\" to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\nentities declarations. This can be done by setting the features\n\"http://xml.org/sax/features/external-general-entities\" and\n\"http://xml.org/sax/features/external-parameter-entities\" to false.\n\nSecure Code Example: \n``` \npublic void GoodXMLInputFactory() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n} \n```\n" + - scala + message: | + An attacker can set arbitrary bean properties that can compromise system integrity. An + attacker can leverage this functionality to access special bean properties like + class.classLoader that will allow them to override system properties and potentially execute + arbitrary code. metadata: category: security - confidence: HIGH - cwe: CWE-611 - cwe2021-top25: "true" - cwe2022-top25: "true" - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference + cwe: CWE-15 + security-severity: Info + shortDescription: External Control of System or Configuration Setting technology: - - java - - xml - vulnerability_class: - - XML Injection + - scala patterns: - - pattern: | - $DBFACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", - false); - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - } - severity: WARNING - - id: java_xxe_rule-DocumentBuilderFactoryDisallowDoctypeDeclMissing + - pattern-inside: 'def $FUNC(..., $REQ: HttpServletRequest, ...): $TYPE = { ... }' + - pattern-either: + - pattern: | + $MAP.put(..., $REQ.getParameter(...)) + ... + $BEAN_UTIL.populate(..., $MAP) + - pattern: | + while (...) { + ... + $MAP.put(..., $REQ.getParameterValues(...). ...) + } + ... + $BEAN_UTIL.populate(..., $MAP) + - metavariable-pattern: + metavariable: $BEAN_UTIL + pattern-either: + - pattern: (BeanUtilsBean $B) + - pattern: new BeanUtilsBean() + - pattern: org.apache.commons.beanutils.BeanUtils + severity: ERROR + - id: scala_inject_rule-CLRFInjectionLogs languages: - - java - message: "DOCTYPE declarations are enabled for this DocumentBuilderFactory. Enabling \nDOCTYPE declarations without proper restrictions can make your application \nvulnerable to XML External Entity (XXE) attacks. \nIn an XXE attack, an attacker can exploit the processing of external entity \nreferences within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise. \n\nTo mitigate this vulnerability, disable this by setting the\nfeature \"http://apache.org/xml/features/disallow-doctype-decl\" to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\nentities declarations. This can be done by setting the features\n\"http://xml.org/sax/features/external-general-entities\" and\n\"http://xml.org/sax/features/external-parameter-entities\" to false.\n\nSecure Code Example (You can do either of the following):\n```\npublic void GoodDocumentBuilderFactory() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n dbf.newDocumentBuilder();\n}\n\npublic void GoodDocumentBuilderFactory2() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n dbf.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n dbf.newDocumentBuilder();\n}\n```\n" + - scala + message: | + When data from an untrusted source is put into a logger and not neutralized correctly, an + attacker could forge log entries or include malicious content. Inserted false entries could be + used to skew statistics, distract the administrator or even to implicate another party in the + commission of a malicious act. If the log file is processed automatically, the attacker can + render the file unusable by corrupting the format of the file or injecting unexpected + characters. An attacker may also inject code or other commands into the log file and take + advantage of a vulnerability in the log processing utility (e.g. command injection or XSS). metadata: category: security - confidence: HIGH - cwe: CWE-611 - cwe2021-top25: "true" - cwe2022-top25: "true" - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference - subcategory: - - vuln + cwe: CWE-93 + security-severity: Info + shortDescription: Improper Neutralization of CRLF Sequences ('CRLF Injection') technology: - - java - - xml - vulnerability_class: - - XML Injection + - scala mode: taint pattern-sanitizers: - - by-side-effect: true - pattern-either: - - patterns: - - pattern-either: - - pattern: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); ... $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); ... $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - - focus-metavariable: $FACTORY - - patterns: - - pattern-either: - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", - true); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); - ... - } - ... - } - - pattern: $M($X) - - focus-metavariable: $X + - patterns: + - pattern-inside: $STR.replaceAll("$REPLACE_CHAR", "$REPLACE"); + - pattern: $STR + - metavariable-regex: + metavariable: $REPLACE_CHAR + regex: (.*\\r\\n.*) + - metavariable-regex: + metavariable: $REPLACE + regex: (?!(\\r\\n)) + - pattern: org.owasp.encoder.Encode.forUriComponent(...) + - pattern: org.owasp.encoder.Encode.forUri(...) + - pattern: java.net.URLEncoder.encode(..., $CHARSET) pattern-sinks: - patterns: - - pattern: | - $FACTORY.newDocumentBuilder(); + - patterns: + - pattern: $LOGGER.$METHOD(...,<...$TAINTED...>,...) + - focus-metavariable: $TAINTED + - metavariable-regex: + metavariable: $METHOD + regex: (log|logp|logrb|entering|exiting|fine|finer|finest|info|debug|trace|warn|warning|config|error|severe) + - metavariable-pattern: + metavariable: $LOGGER + pattern-either: + - pattern: Logger + - pattern: log + - pattern: logger + - pattern: org.pmw.tinylog.Logger + - pattern: org.apache.log4j.Logger + - pattern: org.apache.logging.log4j.Logger + - pattern: org.slf4j.Logger + - pattern: org.apache.commons.logging.Log + - pattern: java.util.logging.Logger pattern-sources: - - by-side-effect: true - patterns: - - pattern: | - $FACTORY + - patterns: - pattern-inside: | - $FACTORY = DocumentBuilderFactory.newInstance(); - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - ... - static { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - ... - } + def $FUNC(..., $REQ: HttpServletRequest, ...) : $TYPE = { ... } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - ... - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } + - pattern: $REQ.getParameter(...) + severity: ERROR + - id: scala_inject_rule-CommandInjection + languages: + - scala + message: | + The highlighted API is used to execute a system command. If unfiltered input is passed to this + API, it can lead to arbitrary command execution. + metadata: + category: security + cwe: CWE-78 + security-severity: Info + shortDescription: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') + technology: + - scala + pattern-either: + - patterns: + - pattern-inside: | + def $FUNC(..., $PARAM: String, ...): $TYPE = { ... } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - ... - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + - pattern-inside: | + val $RT = Runtime.getRuntime + ... + - pattern-either: + - pattern: $RT.exec($PARAM) + - pattern: | + var $CMDARR = new Array[String]("$SHELL",...,$PARAM,...) ... - } + $RT.exec($CMDARR,...) + - pattern: $RT.exec(Array[String]("$SHELL",...,$PARAM,...), ...) + - pattern: $RT.exec(java.util.String.format("...", ...,$PARAM,...)) + - pattern: '$RT.exec(($A: String) + ($B: String))' + - metavariable-regex: + metavariable: $SHELL + regex: (/.../)?(sh|bash|ksh|csh|tcsh|zsh)$ + - pattern-not: $RT.exec("...","...","...",...) + - pattern-not: $RT.exec(new Array[String]("...","...","...",...),...) + - patterns: + - pattern-inside: | + def $FUNC(...,$PARAM: String, ...): $TYPE = { ... } + - pattern-inside: | + val $PB = new ProcessBuilder() + ... + - pattern-either: + - pattern: $PB.command($PARAM,...) + - patterns: + - pattern-either: + - pattern: $PB.command("$SHELL",...,$PARAM,...) + - pattern: | + var $CMDARR = java.util.Arrays.asList("$SHELL",...,$PARAM,...) + ... + $PB.command($CMDARR,...) + - pattern: $PB.command(java.util.Arrays.asList("$SHELL",...,$PARAM,...),...) + - pattern: $PB.command(java.util.String.format("...", ...,$PARAM,...)) + - pattern: '$PB.command(($A: String) + ($B: String))' + - metavariable-regex: + metavariable: $SHELL + regex: (/.../)?(sh|bash|ksh|csh|tcsh|zsh)$ + - pattern-not: $PB.command("...","...","...",...) + - pattern-not: | + $PB.command(java.util.Arrays.asList("...","...","...",...)) severity: WARNING - - id: properties_spring_rule-SpringActuatorFullyEnabled + - id: scala_inject_rule-CustomInjection languages: - - generic - message: "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints\nsuch as /actuator/env, /actuator/logfile, /actuator/heapdump and others.\nIf the application lacks proper security measures (e.g., authentication and \nauthorization), sensitive data could be accessed, compromising the application and \nits infrastructure. This configuration poses a serious risk in production \nenvironments or public-facing deployments.\n\nTo mitigate the risks, take the following measures:\n - Expose only the Actuator endpoints required for your use case\n - For production environments, restrict exposure to non-sensitive endpoints \n like `health` or `info`\n - Ensure Actuator endpoints are protected with authentication and authorization \n (e.g., via Spring Security)\n - Use environment-specific configurations to limit exposure in production\n\nSecure Code Example:\nInstead of include: \"*\", list only the endpoints you need to expose:\n```\nmanagement.endpoints.web.exposure.include=\"health,info,metrics\"\n```\n\nReferences:\n- https://docs.spring.io/spring-boot/reference/actuator/endpoints.html#actuator.endpoints.exposing\n- https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785\n- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators\n" + - scala + message: | + The method identified is susceptible to injection. The input should be validated and properly + escaped. metadata: category: security - confidence: MEDIUM - cwe: CWE-497 - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2021-Broken Access Control - - A3:2017-Sensitive Data Exposure - security-severity: Medium - shortDescription: Exposure of sensitive system information to an unauthorized control sphere + cwe: CWE-89 + security-severity: Low + shortDescription: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') technology: - - java - paths: - include: - - '*properties' - pattern: management.endpoints.web.exposure.include=* + - scala + patterns: + - pattern-either: + - pattern-inside: | + val $ST = connection.createStatement + ... + - pattern-either: + - pattern: | + val $QUERY = ... + $VAR + ... + ... + $ST.executeQuery($QUERY) + - pattern: | + val $QUERY = ... + $VAR + ... + $ST.executeQuery($QUERY) + - pattern: | + val $QUERY = String.format("...",...,$VAR,...) + ... + $ST.executeQuery($QUERY) + - pattern: '$ST.executeQuery(($SB: StringBuilder).toString())' + - pattern: $ST.executeQuery(... + $VAR + ...) + - pattern: $ST.executeQuery(... + $VAR) + - pattern: $ST.executeQuery(...,String.format("...",...,$VAR,...), ...) severity: WARNING - - id: python_crypto_rule-HTTPConnectionPool + - id: scala_inject_rule-CustomInjectionSQLString languages: - - python - message: "The application is using HTTPConnectionPool method. This method transmits\ndata in cleartext, which is vulnerable to MITM (Man in the middle)\nattacks. In MITM attacks, the data transmitted over the unencrypted\nconnection can be intercepted, read and/or modified by unauthorized\nparties which can lead to data integrity and confidentiality loss. \n\nTo mitigate this issue, use HTTPSConnectionPool instead, which encrypts \ncommunications and enhances security.\n\nSecure Code Example:\n```\nimport urllib3\nspool = urllib3.connectionpool.HTTPSConnectionPool(\"example.com\")\n```\n" + - scala + message: | + The method identified is susceptible to injection. The input should be validated and properly + escaped. metadata: category: security - confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://urllib3.readthedocs.io/en/1.2.1/pools.html#urllib3.connectionpool.HTTPSConnectionPool - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - subcategory: - - audit + cwe: CWE-89 + security-severity: High + shortDescription: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') technology: - - python - pattern-either: - - pattern: urllib3.HTTPConnectionPool(...) - - pattern: urllib3.connectionpool.HTTPConnectionPool(...) + - scala + patterns: + - pattern-inside: | + def $FOO(..., $SQLIN: String, ...): $TYPE = { + ... + } + - pattern-either: + - pattern: | + "$SQL_STR" + $SQLIN + - pattern: String.format("$SQL_STR", ... + $SQLIN + ...) + - pattern: | + "$SQL_STR".concat(...) + - pattern: (StringBuilder $BUILDER). ... .append("$SQL_STR") + - patterns: + - pattern-inside: | + StringBuilder $BUILDER = new StringBuilder(... + "$SQL_STR" + ...); + ... + - pattern: $BUILDER.append(...) + - pattern-not: $BUILDER.append("...") + - patterns: + - pattern-inside: | + $QUERY = "$SQL_STR"; + ... + - pattern: $QUERY += ... + - metavariable-regex: + metavariable: $SQL_STR + regex: (?i)(select|insert|create|update|alter|delete|drop)\b severity: WARNING - - id: python_flask_rule-path-traversal-open + - id: scala_inject_rule-ELInjection languages: - - python - message: "Found request data in a call to 'open'. An attacker can manipulate this input to access files outside the intended \ndirectory. This can lead to unauthorized access to sensitive files or directories. To prevent path traversal attacks, \navoid using user-controlled input in file paths. If you must use user-controlled input, validate and sanitize the \ninput to ensure it does not contain any path traversal sequences. For example, you can use the `os.path.join` function \nto safely construct file paths or validate that the absolute path starts with the directory which is whitelisted for \naccessing file. The following code snippet demonstrates how to validate a file path from user-controlled input:\n```\nimport os\n\ndef safe_open_file(filename, base_path):\n # Resolve the absolute path of the user-supplied filename\n absolute_path = os.path.abspath(filename)\n\n # Check that the absolute path starts with the base path\n if not absolute_path.startswith(base_path):\n raise ValueError(\"Invalid file path\")\n\n return open(absolute_path, 'r')\n```\nFor more information, see the OWASP Path Traversal page: https://owasp.org/www-community/attacks/Path_Traversal\n" + - scala + message: | + An expression is built with a dynamic value. The source of the value(s) should be verified to + avoid that unfiltered values fall into this risky code evaluation. metadata: category: security - confidence: MEDIUM - cwe: CWE-22 - impact: HIGH - likelihood: MEDIUM - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - security-severity: CRITICAL - shortDescription: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') + cwe: CWE-94 + security-severity: High + shortDescription: Improper Control of Generation of Code ('Code Injection') technology: - - flask - pattern-either: - - patterns: - - pattern: open(...) - - pattern-either: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - open(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - with open(..., <... $ROUTEVAR ...>, ...) as $FD: - ... - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - $INTERIM = <... $ROUTEVAR ...> - ... - open(..., <... $INTERIM ...>, ...) - - pattern: open(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: open(..., <... flask.request.$W[...] ...>, ...) - - pattern: open(..., <... flask.request.$W(...) ...>, ...) - - pattern: open(..., <... flask.request.$W ...>, ...) + - scala + patterns: + - pattern-inside: | + import javax.el._ + ... + - pattern-either: + - pattern-inside: | + def $FUNC(..., $EXPR: String, ...) : $TYPE = { + ... + } + - pattern-inside: | + def $FUNC(..., $EXPR: String, ...) = { + ... + } + - pattern-either: + - pattern: $X.createValueExpression(..., $EXPR, ...) + - pattern: $X.createMethodExpression(..., $EXPR, ...) + severity: WARNING + - id: scala_inject_rule-FileDisclosure + languages: + - scala + message: | + Constructing a server-side redirect path with user input could allow an + attacker to download application binaries (including application classes or + jar files) or view arbitrary files within protected directories. + metadata: + category: security + cwe: CWE-552 + security-severity: Info + shortDescription: Files or Directories Accessible to External Parties + mode: taint + pattern-sinks: - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W.get(...) ...> - ... - open(<... $INTERIM ...>, ...) - - pattern: open(...) + - pattern: new org.springframework.web.servlet.ModelAndView($FST) + - pattern: $FST - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W[...] ...> - ... - open(<... $INTERIM ...>, ...) - - pattern: open(...) + - pattern: new org.springframework.web.servlet.ModelAndView($FST, $SND) + - pattern: $FST - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W(...) ...> - ... - open(<... $INTERIM ...>, ...) - - pattern: open(...) + - pattern: new org.springframework.web.servlet.ModelAndView($FST, $SND, $TRD) + - pattern: $FST - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W ...> - ... - open(<... $INTERIM ...>, ...) - - pattern: open(...) + - pattern: new org.apache.struts.action.ActionForward($FST) + - pattern: $FST - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W.get(...) ...> - ... - with open(<... $INTERIM ...>, ...) as $F: - ... - - pattern: open(...) + - pattern: new org.apache.struts.action.ActionForward($FST, $SND) + - pattern: $FST + - patterns: + - pattern: new org.apache.struts.action.ActionForward($FST, $SND, $TRD) + - pattern: $SND + - patterns: + - pattern: new org.apache.struts.action.ActionForward($FST, $SND, $TRD) + - pattern: $TRD - patterns: - pattern-inside: | - $INTERIM = <... flask.request.$W[...] ...> + $ACTION = new org.apache.struts.action.ActionForward() ... - with open(<... $INTERIM ...>, ...) as $F: - ... - - pattern: open(...) + - pattern: $ACTION.setPath(...) - patterns: - pattern-inside: | - $INTERIM = <... flask.request.$W(...) ...> + $MVC = new org.springframework.web.servlet.ModelAndView() ... - with open(<... $INTERIM ...>, ...) as $F: - ... - - pattern: open(...) + - pattern: $MVC.setViewName(...); - patterns: - pattern-inside: | - $INTERIM = <... flask.request.$W ...> + $REQ = $HTTP.getRequestDispatcher(...) ... - with open(<... $INTERIM ...>, ...) as $F: - ... - - pattern: open(...) + - pattern-either: + - pattern: $REQ.include($FST, $SND) + - pattern: $REQ.forward($FST, $SND) + pattern-sources: + - pattern: '($VAR: javax.servlet.http.HttpServletRequest).getParameter(...)' severity: ERROR - - id: python_jwt_rule-jwt-none-alg + - id: scala_inject_rule-HttpParameterPollution languages: - - python + - scala message: | - Detected use of the 'none' algorithm in a JWT token. - The 'none' algorithm assumes the integrity of the token has already - been verified. This would allow a malicious actor to forge a JWT token - that will automatically be verified. Do not explicitly use the 'none' - algorithm. Instead, use an algorithm such as 'HS256'. + Concatenating unvalidated user input into a URL can allow an attacker to override the value of + a request parameter. Attacker may be able to override existing parameter values, inject a new + parameter or exploit variables out of a direct reach. HTTP Parameter Pollution (HPP) attacks + consist of injecting encoded query string delimiters into other existing parameters. If a web + application does not properly sanitize the user input, a malicious user may compromise the + logic of the application to perform either client-side or server-side attacks. metadata: category: security - confidence: MEDIUM - cwe: CWE-327 - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - security-severity: MEDIUM - shortDescription: Use of a Broken or Risky Cryptographic Algorithm - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - vuln + cwe: CWE-88 + security-severity: Info + shortDescription: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') technology: - - jwt - pattern-either: - - pattern: jwt.encode(...,algorithm="none",...) - - pattern: jwt.decode(...,algorithms=[...,"none",...],...) + - scala + mode: taint + pattern-sanitizers: + - pattern: java.net.URLEncoder.encode(...) + - pattern: com.google.common.net.UrlEscapers.urlPathSegmentEscaper().escape(...) + pattern-sinks: + - pattern: new org.apache.http.client.methods.HttpGet(...) + - pattern: new org.apache.commons.httpclient.methods.GetMethod(...) + - pattern: '($GM: org.apache.commons.httpclient.methods.GetMethod).setQueryString(...)' + pattern-sources: + - pattern: '($REQ: HttpServletRequest ).getParameter(...)' severity: ERROR - - id: python_pyramid_rule-pyramid-csrf-origin-check + - id: scala_inject_rule-LDAPInjection languages: - - python - message: "Automatic check of the referrer for cross-site request forgery tokens\nhas been explicitly disabled globally, which might leave views unprotected\nwhen an unsafe CSRF storage policy is used. By passing `check_origin=False` \nto `set_default_csrf_options()` method, you opt out of checking the origin \nof the domain in the referrer header or the origin header, which can make \nthe application vulnerable to CSRF attacks, specially if CSRF token is not \nproperly implemented.\nCSRF attacks are a type of exploit where an attacker tricks a user into \nexecuting unwanted actions on a web application in which they are authenticated. \nIf a user is logged into a web application, an attacker could create a malicious \nlink or script on another site that causes the user's browser to make a request \nto the web application, carrying out an action without the user's consent.\n\nTo mitigate this vulnerability, use \n'pyramid.config.Configurator.set_default_csrf_options(check_origin=True)'\nto turn the automatic check for all unsafe methods (per RFC2616).\n\nSecure Code Example:\n```\ndef safe(config):\n config.set_csrf_storage_policy(CookieCSRFStoragePolicy())\n config.set_default_csrf_options(check_origin=True)\n```\n" + - scala + message: | + Just like SQL, all inputs passed to an LDAP query need to be passed in safely. Unfortunately, + LDAP doesn't have prepared statement interfaces like SQL. Therefore, the primary defense + against LDAP injection is strong input validation of any untrusted data before including it in + an LDAP query. metadata: category: security - confidence: MEDIUM - cwe: CWE-352 - cwe2021-top25: "true" - cwe2022-top25: "true" - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - - https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/security.html - security-severity: MEDIUM - shortDescription: Cross-site request forgery (CSRF) - subcategory: - - vuln + cwe: CWE-90 + security-severity: Medium + shortDescription: Improper Neutralization of Special Elements used in an LDAP Query ('LDAP Injection') technology: - - pyramid - vulnerability_class: - - Cross-Site Request Forgery (CSRF) + - scala patterns: - - pattern-inside: | - $CONFIG.set_default_csrf_options(..., check_origin=$CHECK_ORIGIN, ...) - - pattern: | - $CHECK_ORIGIN - - metavariable-comparison: - comparison: $CHECK_ORIGIN == False - metavariable: $CHECK_ORIGIN + - pattern-either: + - pattern-inside: | + def $FUNC(..., $VAR: String, ...): $TYPE = { + ... + } + - pattern-inside: | + def $FUNC(..., $X: String, ...): $TYPE = { + ... + $VAR = ... + $X; + ... + } + - pattern-either: + - pattern: '($P: java.util.Properties).put($KEY, $VAR)' + - pattern: $CTX.lookup(..., $VAR, ...) + - pattern: $CTX.search(..., $VAR, ...) + - pattern: $CTX.list(..., $VAR, ...) + - metavariable-pattern: + metavariable: $CTX + pattern-either: + - pattern: '($CTX: javax.naming.directory.DirContext)' + - pattern: '($CTX: javax.naming.directory.Context)' + - pattern: '($CTX: javax.naming.Context)' + - pattern: '($CTX: javax.naming.directory.InitialDirContext)' + - pattern: '($CTX: javax.naming.ldap.LdapContext)' + - pattern: '($CTX: com.unboundid.ldap.sdk.LDAPConnection)' + - pattern: '($CTX: javax.naming.event.EventDirContext)' + - pattern: '($CTX: com.sun.jndi.ldap.LdapCtx)' + - pattern: '($CTX: org.springframework.ldap.core.LdapTemplate)' + - pattern: '($CTX: org.springframework.ldap.core.LdapOperations)' severity: WARNING - - id: yaml_spring_rule-SpringActuatorFullyEnabled + - id: scala_inject_rule-OgnlInjection languages: - - yaml - message: "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints\nsuch as /actuator/env, /actuator/logfile, /actuator/heapdump and others.\nIf the application lacks proper security measures (e.g., authentication and \nauthorization), sensitive data could be accessed, compromising the application and \nits infrastructure. This configuration poses a serious risk in production \nenvironments or public-facing deployments.\n\nTo mitigate the risks, take the following measures:\n - Expose only the Actuator endpoints required for your use case\n - For production environments, restrict exposure to non-sensitive endpoints \n like `health` or `info`\n - Ensure Actuator endpoints are protected with authentication and authorization \n (e.g., via Spring Security)\n - Use environment-specific configurations to limit exposure in production\n\nSecure Code Example:\nInstead of include: \"*\", list only the endpoints you need to expose:\n```\nmanagement:\n endpoints:\n web:\n exposure:\n include: \"health,info,metrics\"\n```\n\nReferences:\n- https://docs.spring.io/spring-boot/reference/actuator/endpoints.html#actuator.endpoints.exposing\n- https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785\n- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators\n" + - scala + message: | + "A expression is built with a dynamic value. The source of the value(s) should be verified to + avoid that unfiltered values fall into this risky code evaluation." metadata: category: security - confidence: MEDIUM - cwe: CWE-497 - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2021-Broken Access Control - - A3:2017-Sensitive Data Exposure + cwe: CWE-917 security-severity: Medium - shortDescription: Exposure of sensitive system information to an unauthorized control sphere + shortDescription: Expression injection (OGNL) technology: - - java + - scala patterns: - - pattern: | - management: - ... - endpoints: - ... - web: + - pattern-either: + - pattern-inside: | + def $FUNC(..., $VAR: String, ...): $TYPE = { ... - exposure: - ... - include: "*" - ... + } + - pattern-inside: | + def $FUNC(..., $VAR: Map[$K,$V], ...): $TYPE = { + ... + } + - pattern-inside: | + def $FUNC(..., $VAR: java.util.HashMap[$K,$V], ...): $TYPE = { + ... + } + - pattern-either: + - pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariables(..., $VAR, ...) + - pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariablesCollection(..., $VAR, ...) + - pattern: com.opensymphony.xwork2.util.TextParseUtil.shallBeIncluded(..., $VAR, ...) + - pattern: com.opensymphony.xwork2.util.TextParseUtil.commaDelimitedStringToSet(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.TextParser).evaluate(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.OgnlTextParser).evaluate(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getGetMethod(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getSetMethod(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getField(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setProperties(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setProperty(...,$VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getValue(...,$VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setValue(...,$VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getGetMethod(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getSetMethod(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getField(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setProperties(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setProperty(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getValue(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setValue(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setProperties(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setProperty(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).getValue(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setValue(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).callMethod(..., $VAR, ...) + - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).compile(..., $VAR, ...) + - pattern: ($P:org.apache.struts2.util.VelocityStrutsUtil).evaluate(...) + - pattern: org.apache.struts2.util.StrutsUtil.findString(...) + - pattern: org.apache.struts2.util.StrutsUtil.findValue(..., $VAL) + - pattern: org.apache.struts2.util.StrutsUtil.getText(...) + - pattern: org.apache.struts2.util.StrutsUtil.translateVariables(...) + - pattern: org.apache.struts2.util.StrutsUtil.makeSelectList(..., $VAR, ...) + - pattern: ($T:org.apache.struts2.views.jsp.ui.OgnlTool).findValue(..., $VAR, ...) + - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).findString(...) + - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).findValue(..., $VAR, ...) + - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).setValue(..., $VAR, ...) + - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).setParameter(..., $VAR, ...) severity: WARNING - - id: kotlin_perm_rule-DangerousPermissions + - id: scala_inject_rule-PathTraversalIn languages: - - kotlin + - scala message: | - Do not grant dangerous combinations of permissions. + A file is opened to read its content. The filename comes from an input parameter. If an + unfiltered parameter is passed to this file API, files from an arbitrary filesystem location + could be read. This rule identifies potential path traversal vulnerabilities. In many cases, + the constructed file path cannot be controlled by the user. metadata: category: security - confidence: HIGH - cwe: CWE-277 + cwe: CWE-22 owasp: - A5:2017-Broken Access Control - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Insecure inherited permissions + security-severity: Medium + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + technology: + - scala patterns: - pattern-either: - patterns: - pattern-inside: | - $PC = $X.getPermissions(...) + def $FUNC(...,$ARGS: Array[String], ...): $TYPE = { ... - - pattern: $PC.add($PERMISSION) - - pattern: | - $REFVAR = $PERMISSION - ...; - ($PC: PermissionCollection).add($REFVAR) - - pattern: '($PC: PermissionCollection).add($PERMISSION)' - - metavariable-pattern: - metavariable: $PERMISSION - pattern-either: - - pattern: ReflectPermission("suppressAccessChecks") - - pattern: RuntimePermission("createClassLoader") + } + - pattern-inside: | + $VAR = $ARGS($IDX) + ... + - pattern-inside: | + def $FUNC(...,$VAR: String, ...): $TYPE = { + ... + } + - pattern-not-inside: | + ... + org.apache.commons.io.FilenameUtils.getName($VAR) + ... + - pattern-either: + - patterns: + - pattern-inside: | + $U = new java.net.URI($VAR) + ... + - pattern-either: + - pattern: new java.io.File($U) + - pattern: java.nio.file.Paths.get($U) + - pattern: new java.io.RandomAccessFile(..., $VAR,...) + - pattern: new java.io.FileReader(<...$VAR...>, ...) + - pattern: new javax.activation.FileDataSource(..., $VAR, ...) + - pattern: new java.io.FileInputStream(..., $VAR, ...) + - pattern: new java.io.File(<...$VAR...>, ...) + - pattern: java.nio.file.Paths.get(...,$VAR,...) + - pattern: java.io.File.createTempFile(...,$VAR, ...) + - pattern: java.io.File.createTempDirectory(...,$VAR,...) + - pattern: java.nio.file.Files.createTempFile(..., $VAR, ...) + - pattern: java.nio.file.Files.createTempDirectory(..., $VAR, ...) + - pattern: scala.io.Source.from(<...$VAR...>) + - pattern: scala.io.Source.fromFile(<...$VAR...>) + - pattern: scala.io.Source.fromString(<...$VAR...>) + severity: ERROR + - id: scala_inject_rule-PathTraversalOut + languages: + - scala + message: | + A file is opened to write to its contents. The filename comes from an input parameter. If an + unfiltered parameter is passed to this file API, files at an arbitrary filesystem location + could be modified. This rule identifies potential path traversal vulnerabilities. In many + cases, the constructed file path cannot be controlled by the user. + metadata: + category: security + cwe: CWE-22 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: High + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + technology: + - scala + mode: taint + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: + - patterns: + - pattern-inside: new java.io.FileWriter($PATH, ...) + - pattern: $PATH + - patterns: + - pattern-inside: new java.io.FileOutputStream($PATH, ...) + - pattern: $PATH + pattern-sources: + - patterns: + - pattern-inside: | + def $FUNC(..., $ARGS: Array[String], ...): $TYPE = { + ... + } + - pattern: $ARGS[$IDX] + - patterns: + - pattern-inside: | + def $FUNC(..., $VAR: String, ...): $TYPE = { + ... + } + - pattern: $VAR severity: WARNING - - id: kotlin_perm_rule-OverlyPermissiveFilePermissionInline + - id: scala_inject_rule-SpotbugsPathTraversalAbsolute languages: - - kotlin + - scala message: | - Overly permissive file permission + "The software uses an HTTP request parameter to construct a pathname that should be within a + restricted directory, but it does not properly neutralize absolute path sequences such as + "/abs/path" that can resolve to a location that is outside of that directory. See + http://cwe.mitre.org/data/definitions/36.html for more information." metadata: category: security - confidence: HIGH - cwe: CWE-732 + cwe: CWE-22 owasp: - A5:2017-Broken Access Control - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Incorrect permission assignment for critical resource - patterns: - - pattern-either: - - pattern: java.nio.file.Files.setPosixFilePermissions(..., java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING")); - - pattern: | - $PERMISSIONS = java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING"); - ... - java.nio.file.Files.setPosixFilePermissions(..., $PERMISSIONS); - - metavariable-regex: - metavariable: $PERM_STRING - regex: '[rwx-]{6}[rwx]{1,}' + security-severity: Info + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + technology: + - scala + mode: taint + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: + - patterns: + - pattern-inside: | + $U = new java.net.URI($VAR) + - pattern-either: + - pattern-inside: new java.io.File($U) + - pattern-inside: java.nio.file.Paths.get($U) + - pattern: $VAR + - patterns: + - pattern-inside: new java.io.RandomAccessFile($INPUT,...) + - pattern: $INPUT + - pattern: new java.io.FileReader(...) + - pattern: new javax.activation.FileDataSource(...) + - pattern: new java.io.FileInputStream(...) + - pattern: new java.io.File(...) + - pattern: java.nio.file.Paths.get(...) + - pattern: java.io.File.createTempFile(...) + - pattern: java.io.File.createTempDirectory(...) + - pattern: java.nio.file.Files.createTempFile(...) + - pattern: java.nio.file.Files.createTempDirectory(...) + - patterns: + - pattern-inside: new java.io.FileWriter($PATH, ...) + - pattern: $PATH + - patterns: + - pattern-inside: new java.io.FileOutputStream($PATH, ...) + - pattern: $PATH + pattern-sources: + - pattern: '($REQ: HttpServletRequest ).getParameter(...)' severity: WARNING - - id: kotlin_strings_rule-BadHexConversion + - id: scala_inject_rule-SpotbugsPathTraversalRelative languages: - - kotlin + - scala message: | - When converting a byte array containing a hash signature to a human readable string, a - conversion mistake can be made if the array is read byte by byte. + "The software uses an HTTP request parameter to construct a pathname that should be within a + restricted directory, but it does not properly neutralize sequences such as ".." that can + resolve to a location that is outside of that directory. See + http://cwe.mitre.org/data/definitions/23.html for more information." metadata: category: security - confidence: HIGH - cwe: CWE-704 + cwe: CWE-22 owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Incorrect type conversion or cast - patterns: - - pattern-inside: | - $B_ARR = ($MD: java.security.MessageDigest).digest(...); - ... - - pattern-either: - - pattern: | - for($B in $B_ARR) { - ... - $B_TOSTR - } - - pattern: | - while(...) { - ... - $B_TOSTR - } - - pattern: | - do { - ... - $B_TOSTR - } while(...) - - metavariable-pattern: - metavariable: $B_TOSTR - patterns: - - pattern-either: - - pattern: java.lang.Integer.toHexString($B_TOINT) - - pattern: Integer.toHexString($B_TOINT) - - pattern: $B_TOINT.toHexString(...) - - metavariable-pattern: - metavariable: $B_TOINT - pattern-either: - - pattern: $B_ARR[...].toInt() - - pattern: $B_ARR[...] - - pattern: $B.toInt() - - pattern: $B + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Info + shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + technology: + - scala + mode: taint + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: + - patterns: + - pattern-inside: | + $U = new java.net.URI($VAR) + - pattern-either: + - pattern-inside: new java.io.File($U) + - pattern-inside: java.nio.file.Paths.get($U) + - pattern: $VAR + - patterns: + - pattern-inside: new java.io.RandomAccessFile($INPUT,...) + - pattern: $INPUT + - pattern: new java.io.FileReader(...) + - pattern: new javax.activation.FileDataSource(...) + - pattern: new java.io.FileInputStream(...) + - pattern: new java.io.File(...) + - pattern: java.nio.file.Paths.get(...) + - pattern: java.io.File.createTempFile(...) + - pattern: java.io.File.createTempDirectory(...) + - pattern: java.nio.file.Files.createTempFile(...) + - pattern: java.nio.file.Files.createTempDirectory(...) + - patterns: + - pattern-inside: new java.io.FileWriter($PATH, ...) + - pattern: $PATH + - patterns: + - pattern-inside: new java.io.FileOutputStream($PATH, ...) + - pattern: $PATH + pattern-sources: + - patterns: + - pattern-inside: | + $P = ($REQ: HttpServletRequest ).getParameter(...); + ... + - pattern-either: + - pattern: $P + ... + - pattern: '... + $P' severity: WARNING - - id: kotlin_strings_rule-FormatStringManipulation + - id: scala_inject_rule-SqlInjection languages: - - kotlin + - scala message: | - Allowing user input to control format parameters could enable an attacker to cause exceptions - to be thrown or leak information.Attackers may be able to modify the format string argument, - such that an exception is thrown. If this exception is left uncaught, it may crash the - application. Alternatively, if sensitive information is used within the unused arguments, - attackers may change the format string to reveal this information. + The input values included in SQL queries need to be passed in safely. Bind + variables in prepared statements can be used to easily mitigate the risk of + SQL injection. metadata: category: security - confidence: HIGH - cwe: CWE-134 + cwe: CWE-89 owasp: - A1:2017-Injection - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Use of externally-controlled format string + security-severity: Medium + shortDescription: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') patterns: + - pattern-not-inside: | + $ARG = ... + ... + - pattern-not-inside: | + object $CLAZZ { + ... + $ARG = ... + ... + } + - pattern-not-inside: | + class $CLAZZ { + ... + $ARG = ... + ... + } - pattern-either: - patterns: - - pattern-inside: | - $INPUT = ($REQ: HttpServletRequest).getParameter(...) - ... - - pattern-inside: | - $FORMAT_STR = ... + $INPUT - ... + - pattern: ($PM:javax.jdo.PersistenceManager).newQuery(<...$ARG...>) + - pattern-not: ($PM:javax.jdo.PersistenceManager).newQuery("...") - patterns: - - pattern-inside: | - $INPUT = ($REQ: HttpServletRequest).getParameter(...) - ... - - pattern-inside: | - $FORMAT_STR = ... + $INPUT + ... - ... - - pattern-inside: | - $FORMAT_STR = ... + ($REQ: HttpServletRequest).getParameter(...) + ... - ... - - pattern-inside: | - $FORMAT_STR = ... + ($REQ: HttpServletRequest).getParameter(...) - ... - - pattern-either: - - pattern: String.format($FORMAT_STR, ...) - - pattern: String.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) + - pattern: ($PM:javax.jdo.PersistenceManager).newQuery(..., <...$ARG...>) + - pattern-not: ($PM:javax.jdo.PersistenceManager).newQuery(..., "...") + - patterns: + - pattern: '($Q: javax.jdo.Query).setFilter(<...$ARG...>)' + - pattern-not: '($Q: javax.jdo.Query).setFilter("...")' + - patterns: + - pattern: '($Q: javax.jdo.Query).setGrouping(<...$ARG...>)' + - pattern-not: '($Q: javax.jdo.Query).setGrouping("...")' + - patterns: + - pattern: '($Q: javax.jdo.Query).setGrouping(<...$ARG...>)' + - pattern-not: '($Q: javax.jdo.Query).setGrouping("...")' + - patterns: + - pattern: '($H: org.hibernate.criterion.Restrictions).sqlRestriction(<...$ARG...>, ...)' + - pattern-not: '($H: org.hibernate.criterion.Restrictions).sqlRestriction("...", ...)' + - patterns: + - pattern: '($S: org.hibernate.Session).createQuery(<...$ARG...>, ...)' + - pattern-not: '($S: org.hibernate.Session).createQuery("...", ...)' + - patterns: + - pattern: '($S: org.hibernate.Session).createSQLQuery(<...$ARG...>, ...)' + - pattern-not: '($S: org.hibernate.Session).createSQLQuery("...", ...)' + - patterns: + - pattern: '($S: java.sql.Statement).executeQuery(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.Statement).createSQLQuery("...", ...)' + - patterns: + - pattern: '($S: java.sql.Statement).execute(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.Statement).execute("...", ...)' + - patterns: + - pattern: '($S: java.sql.Statement).executeUpdate(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.Statement).executeUpdate("...", ...)' + - patterns: + - pattern: '($S: java.sql.Statement).executeLargeUpdate(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.Statement).executeLargeUpdate("...", ...)' + - patterns: + - pattern: '($S: java.sql.Statement).addBatch(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.Statement).addBatch("...", ...)' + - patterns: + - pattern: '($S: java.sql.PreparedStatement).executeQuery(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.PreparedStatement).executeQuery("...", ...)' + - patterns: + - pattern: '($S: java.sql.PreparedStatement).execute(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.PreparedStatement).execute("...", ...)' + - patterns: + - pattern: '($S: java.sql.PreparedStatement).executeUpdate(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.PreparedStatement).executeUpdate("...", ...)' + - patterns: + - pattern: '($S: java.sql.PreparedStatement).executeLargeUpdate(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.PreparedStatement).executeLargeUpdate("...", ...)' + - patterns: + - pattern: '($S: java.sql.PreparedStatement).addBatch(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.PreparedStatement).addBatch("...", ...)' + - patterns: + - pattern: '($S: java.sql.Connection).prepareCall(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.Connection).prepareCall("...", ...)' + - patterns: + - pattern: '($S: java.sql.Connection).prepareStatement(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.Connection).prepareStatement("...", ...)' + - patterns: + - pattern: '($S: java.sql.Connection).nativeSQL(<...$ARG...>, ...)' + - pattern-not: '($S: java.sql.Connection).nativeSQL("...", ...)' + - patterns: + - pattern: new org.springframework.jdbc.core.PreparedStatementCreatorFactory(<...$ARG...>, ...) + - pattern-not: new org.springframework.jdbc.core.PreparedStatementCreatorFactory("...", ...) + - patterns: + - pattern: (org.springframework.jdbc.core.PreparedStatementCreatorFactory $F).newPreparedStatementCreator(<...$ARG...>, ...) + - pattern-not: (org.springframework.jdbc.core.PreparedStatementCreatorFactory $F).newPreparedStatementCreator("...", ...) + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).batchUpdate(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).batchUpdate("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).execute(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).execute("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).query(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).query("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForList(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForList("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForMap(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForMap("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForRowSet(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForRowSet("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForInt(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForInt("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForLong(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForLong("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).update(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).update("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).batchUpdate(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).batchUpdate("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).execute(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).execute("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).query(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).query("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForList(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForList("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForMap(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForMap("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForObject(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForObject("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForRowSet(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForRowSet("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForInt(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForInt("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForLong(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForLong("...", ...)' + - patterns: + - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).update(<...$ARG...>, ...)' + - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).update("...", ...)' + - patterns: + - pattern: '($O: io.vertx.sqlclient.SqlClient).query(<...$ARG...>, ...)' + - pattern-not: '($O: io.vertx.sqlclient.SqlClient).query("...", ...)' + - patterns: + - pattern: '($O: io.vertx.sqlclient.SqlClient).preparedQuery(<...$ARG...>, ...)' + - pattern-not: '($O: io.vertx.sqlclient.SqlClient).preparedQuery("...", ...)' + - patterns: + - pattern: '($O: io.vertx.sqlclient.SqlConnection).prepare(<...$ARG...>, ...)' + - pattern-not: '($O: io.vertx.sqlclient.SqlConnection).prepare("...", ...)' + - patterns: + - pattern: '($O: org.apache.turbine.om.peer.BasePeer).executeQuery(<...$ARG...>, ...)' + - pattern-not: '($O: org.apache.turbine.om.peer.BasePeer).executeQuery("...", ...)' + - patterns: + - pattern: '($O: org.apache.torque.util.BasePeer).executeQuery(<...$ARG...>, ...)' + - pattern-not: '($O: org.apache.torque.util.BasePeer).executeQuery("...", ...)' + - patterns: + - pattern: '($O: javax.persistence.EntityManager).createQuery(<...$ARG...>, ...)' + - pattern-not: '($O: javax.persistence.EntityManager).createQuery("...", ...)' + - patterns: + - pattern: '($O: javax.persistence.EntityManager).createNativeQuery(<...$ARG...>, ...)' + - pattern-not: '($O: javax.persistence.EntityManager).createNativeQuery("...", ...)' + - patterns: + - pattern: anorm.SQL(<...$ARG...>) + - pattern-not: anorm.SQL("...") - patterns: - pattern-inside: | - $F = java.util.Formatter(...) + import anorm._ ... - - pattern-either: - - pattern: $F.format($FORMAT_STR, ...) - - pattern: $F.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) - - pattern: '($F: java.io.PrintStream).printf($FORMAT_STR, ...)' - - pattern: '($F: java.io.PrintStream).printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...)' - - pattern: '($F: java.io.PrintStream).format($FORMAT_STR, ...)' - - pattern: '($F: java.io.PrintStream).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...)' - - pattern: System.out.printf($FORMAT_STR, ...) - - pattern: System.out.printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...) - - pattern: System.out.format($FORMAT_STR, ...) - - pattern: System.out.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) + - pattern: SQL(<...$ARG...>) + - pattern-not: SQL("...") severity: ERROR - - id: kotlin_strings_rule-ModifyAfterValidation + - id: scala_ldap_rule-AnonymousLDAP languages: - - kotlin + - scala message: | - CERT: IDS11-J. Perform any string modifications before validation + Without proper access control, executing an LDAP statement that contains a + user-controlled value can allow an attacker to abuse poorly configured LDAP + context metadata: category: security - confidence: HIGH - cwe: CWE-182 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Collapse of data into unsafe value + cwe: CWE-358 + security-severity: Info + shortDescription: Improperly implemented security check for standard patterns: - pattern-inside: | - $PATTERN = Pattern.compile(...) - ... - - pattern-inside: | - $PATTERN.matcher($VAR) + import javax.naming.Context; ... - - pattern-either: - - pattern: | - $VAR + $OTHER - - patterns: - - pattern: | - $VAR.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (replace|replaceAll|replaceFirst|concat) + - pattern: $ENV.put(Context.SECURITY_AUTHENTICATION, "none"); severity: WARNING - - id: kotlin_strings_rule-NormalizeAfterValidation + - id: scala_ldap_rule-EntryPoisoning languages: - - kotlin + - scala message: | - IDS01-J. Normalize strings before validating them + Without proper access control, executing an LDAP statement that contains a + user-controlled value can allow an attacker to abuse poorly configured LDAP + context metadata: category: security - confidence: HIGH - cwe: CWE-180 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: 'Incorrect behavior order: validate before canonicalize' + cwe: CWE-358 + security-severity: High + shortDescription: Improperly implemented security check for standard patterns: - - pattern: | - $Y = java.util.regex.Pattern.compile("[<>]"); - ... - $Y.matcher($VAR); - ... - java.text.Normalizer.normalize($VAR, ...); - severity: WARNING + - pattern: new javax.naming.directory.SearchControls($SCOPE, $CLIMIT, $TLIMIT, $ATTR, true, $DEREF) + severity: ERROR + - id: scala_password_rule-ConstantDBPassword + languages: + - scala + message: | + A potential hard-coded password was identified in a database connection string. + Passwords should not be stored directly in code + but loaded from secure locations such as a Key Management System (KMS). + + The purpose of using a Key Management System is so access can be audited and keys easily + rotated + in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine + when or if, a key is compromised. + + The recommendation on which KMS to use depends on the environment the application is running + in: + + - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) + - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) + - For on premise or other alternatives to cloud providers, consider [Hashicorp's + Vault](https://www.vaultproject.io/) + - For other cloud providers, please see their documentation + metadata: + category: security + cwe: CWE-259 + security-severity: Critical + shortDescription: Use of Hard-coded Password + technology: + - scala + patterns: + - pattern: java.sql.DriverManager.getConnection($URI, $USR, "..."); + severity: ERROR + - id: scala_password_rule-EmptyDBPassword + languages: + - scala + message: | + The application does not provide authentication when communicating a database + server. It is strongly recommended that the database server be configured with + authentication and restrict what queries users can execute. + + Please see your database server's documentation on how to configure a password. + + Additionally, passwords should not be stored directly in code + but loaded from secure locations such as a Key Management System (KMS). + + The purpose of using a Key Management System is so access can be audited and keys easily + rotated + in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine + when or if, a key is compromised. + + The recommendation on which KMS to use depends on the environment the application is running + in: + + - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) + - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) + - For on premise or other alternatives to cloud providers, consider [Hashicorp's + Vault](https://www.vaultproject.io/) + - For other cloud providers, please see their documentation + metadata: + category: security + cwe: CWE-259 + security-severity: Critical + shortDescription: Use of Hard-coded Password + technology: + - scala + patterns: + - pattern: java.sql.DriverManager.getConnection($URI, $USR, ""); + severity: ERROR + - id: scala_password_rule-HardcodePassword + languages: + - scala + message: | + A potential hard-coded password was identified in the source code. + Passwords should not be stored directly in code + but loaded from secure locations such as a Key Management System (KMS). + + The purpose of using a Key Management System is so access can be audited and keys easily + rotated + in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine + when or if, a key is compromised. + + The recommendation on which KMS to use depends on the environment the application is running + in: + + - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) + - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) + - For on premise or other alternatives to cloud providers, consider [Hashicorp's + Vault](https://www.vaultproject.io/) + - For other cloud providers, please see their documentation + metadata: + category: security + cwe: CWE-259 + security-severity: High + shortDescription: Use of Hard-coded Password + technology: + - scala + pattern-either: + - pattern: java.security.KeyStore.PasswordProtection("...".toCharArray()) + - pattern: java.security.KeyStore.getInstance(...).load(..., "...".toCharArray()) + - pattern: '($KS: java.security.KeyStore).load(..., "...".toCharArray())' + - pattern: KeyManagerFactory.getInstance(...).init(..., "...".toCharArray()) + - pattern: '($KMF: KeyManagerFactory).init(..., "...".toCharArray())' + - pattern: PBEKeySpec("...", ...) + - pattern: PasswordAuthentication("...", "...") + - pattern: '($CB: PasswordCallback).setPassword("...")' + - pattern: KerberosKey(...,"...",...) + - pattern: java.sql.DriverManager.getConnection(..., "...") + - pattern: io.vertx.ext.web.handler.CSRFHandler.create(..., "...") + - pattern: $S.setPassword("...") + severity: ERROR - id: scala_perm_rule-DangerousPermissions languages: - scala @@ -34135,6 +102875,215 @@ rules: metavariable: $P regex: (PosixFilePermission.){0,1}(OTHERS_) severity: WARNING + - id: scala_script_rule-ScriptInjection + languages: + - scala + message: | + The software constructs all or part of a code segment using externally-influenced + input from an upstream component, but it does not neutralize or incorrectly + neutralizes special elements that could modify the syntax or behavior of the + intended code segment. + metadata: + category: security + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Info + shortDescription: Improper Control of Generation of Code ('Code Injection') + patterns: + - pattern: '($ENGINE: javax.script.ScriptEngine).eval($ARG)' + - pattern-not: '($ENGINE: javax.script.ScriptEngine).eval("...")' + severity: ERROR + - id: scala_script_rule-SpelView + languages: + - scala + message: | + The software constructs all or part of a code segment using externally-influenced + input from an upstream component, but it does not neutralize or incorrectly + neutralizes special elements that could modify the syntax or behavior of the + intended code segment. + metadata: + category: security + cwe: CWE-94 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Improper Control of Generation of Code ('Code Injection') + patterns: + - pattern: '($P: org.springframework.expression.spel.standard.SpelExpressionParser).parseExpression($ARG);' + - pattern-not: '($P: org.springframework.expression.spel.standard.SpelExpressionParser ).parseExpression("...");' + severity: ERROR + - id: scala_smtp_rule-InsecureSmtp + languages: + - scala + message: | + Server identity verification is disabled when making SSL connections. + metadata: + category: security + cwe: CWE-297 + owasp: + - A2:2017-Broken Authentication + - A07:2021-Identification and Authentication Failures + security-severity: High + shortDescription: Improper Validation of Certificate with Host Mismatch + patterns: + - pattern-either: + - pattern-inside: | + $E = new org.apache.commons.mail.SimpleEmail(...); + ... + - pattern-inside: | + $E = new org.apache.commons.mail.Email(...); + ... + - pattern-inside: | + $E = new org.apache.commons.mail.MultiPartEmail(...); + ... + - pattern-inside: | + $E = new org.apache.commons.mail.HtmlEmail(...); + ... + - pattern-inside: | + $E = new org.apache.commons.mail.ImageHtmlEmail(...); + ... + - pattern-not: | + $E.setSSLOnConnect(true); + ... + $E.setSSLCheckServerIdentity(true); + severity: ERROR + - id: scala_smtp_rule-SmtpClient + languages: + - scala + message: | + Simple Mail Transfer Protocol (SMTP) is a the text based protocol used for + email delivery. Like with HTTP, headers are separate by new line separator. If + kuser input is place in a header line, the application should remove or replace + new line characters (CR / LF). You should use a safe wrapper such as Apache + Common Email and Simple Java Mail which filter special characters that can lead + to header injection. + metadata: + category: security + cwe: CWE-77 + security-severity: High + shortDescription: Improper Neutralization of Special Elements used in a Command + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $M = new MimeMessage(...); + ... + - pattern: $M.setSubject($ARG); + - pattern-not: $M.setSubject("...") + - patterns: + - pattern-inside: | + $M = new MimeMessage(...); + ... + - pattern: $M.addHeader($ARG1, $ARG2) + - pattern-not: $M.addHeader("...", "...") + - patterns: + - pattern-inside: | + $M = new MimeMessage(...); + ... + - pattern: $M.setDescription($ARG) + - pattern-not: $M.setDescription("...") + - patterns: + - pattern-inside: | + $M = new MimeMessage(...); + ... + - pattern: $M.setDisposition($ARG) + - pattern-not: $M.setDisposition("...") + severity: ERROR + - id: scala_ssrf_rule-PlaySSRF + languages: + - scala + message: | + Server-Side Request Forgery occur when a web server executes a request to a user supplied + destination parameter that is not validated. Such vulnerabilities could allow an attacker to + access internal services or to launch attacks from your web server. + metadata: + category: security + cwe: CWE-918 + security-severity: Medium + shortDescription: Server-Side Request Forgery (SSRF) + patterns: + - pattern-not-inside: | + object $CLAZZ { + ... + $ARG = ... + ... + } + - pattern-not-inside: | + class $CLAZZ { + ... + $ARG = ... + ... + } + - pattern-either: + - patterns: + - pattern-inside: | + import play.api.libs.ws._ + ... + - pattern-not: ($W:WSClient).url("...") + - pattern-not: ($W:WSClient).url("..." + "...") + - pattern: ($W:WSClient).url(<...$ARG...>) + - patterns: + - pattern: ($W:play.api.libs.ws.WSClient).url(<...$ARG...>) + - pattern-not: ($W:play.api.libs.ws.WSClient).url("...") + - pattern-not: ($W:play.api.libs.ws.WSClient).url("..." + "...") + severity: ERROR + - id: scala_ssrf_rule-SSRF + languages: + - scala + message: | + Server-Side Request Forgery occur when a web server executes a request to a user supplied + destination parameter that is not validated. Such vulnerabilities could allow an attacker to + access internal services or to launch attacks from your web server. + metadata: + category: security + cwe: CWE-918 + security-severity: Low + shortDescription: Server-Side Request Forgery (SSRF) + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + import java.net._ + ... + - pattern-inside: | + import java.net.URL + ... + - pattern-inside: | + import java.net.URI + ... + - pattern: new $TYPE(...). ... .$FUNC + - pattern-not: new $TYPE("..."). ... .$FUNC + - metavariable-pattern: + metavariable: $FUNC + pattern-either: + - pattern: connect + - pattern: GetContent + - pattern: openConnection + - pattern: openStream + - pattern: getContent + - metavariable-pattern: + metavariable: $TYPE + pattern-either: + - pattern: URL + - pattern: java.net.URL + - pattern: URI + - pattern: java.net.URI + - patterns: + - pattern-either: + - pattern-inside: | + import java.net.*; + ... + - pattern-inside: | + import java.net.InetSocketAddress; + ... + - pattern: | + new InetSocketAddress(..., $PORT) + - pattern-not: | + new InetSocketAddress("...", $PORT) + severity: ERROR - id: scala_strings_rule-BadHexConversion languages: - scala @@ -34280,6 +103229,514 @@ rules: ... java.text.Normalizer.normalize($VAR, ...); severity: WARNING + - id: scala_templateinjection_rule-TemplateInjection + languages: + - scala + message: | + A malicious user in control of a template can run malicious code on the + server-side. Velocity templates should be seen as scripts. + metadata: + category: security + cwe: CWE-94 + security-severity: Info + shortDescription: Improper Control of Generation of Code ('Code Injection') + pattern-either: + - patterns: + - pattern: org.apache.velocity.app.Velocity.evaluate(..., $VAR) + - pattern-not: org.apache.velocity.app.Velocity.evaluate(..., "...") + - patterns: + - pattern-not-inside: | + $C = ($CFG: freemarker.template.Configuration).getTemplate("..."); + ... + - pattern-inside: | + $C = ($CFG: freemarker.template.Configuration).getTemplate($IN); + ... + - pattern: $C.process(...) + - patterns: + - pattern-inside: | + import com.mitchellbosecke.pebble.PebbleEngine; + ... + - pattern-inside: | + $C = $T.getTemplate($IN); + ... + - pattern-not-inside: | + $C = $T.getTemplate("..."); + ... + - pattern: $C.evaluate(...) + severity: ERROR + - id: scala_unsafe_rule-ExternalConfigControl + languages: + - scala + message: | + Allowing external control of system settings can disrupt service or cause an application to + behave in unexpected, and potentially malicious ways. An attacker could cause an error by + providing a nonexistent catalog name or connect to an unauthorized portion of the database. + metadata: + category: security + cwe: CWE-15 + security-severity: High + shortDescription: External Control of System or Configuration Setting + technology: + - scala + patterns: + - pattern: | + $TAINTED = ($REQ: HttpServletRequest).getParameter(...); + ... + ($CONN: java.sql.Connection).setCatalog($TAINTED); + severity: WARNING + - id: scala_unsafe_rule-InformationExposure + languages: + - scala + message: | + The sensitive information may be valuable information on its own (such as a password), or it + may be useful for launching other, more deadly attacks. If an attack fails, an attacker may use + error information provided by the server to launch another more focused attack. For example, an + attempt to exploit a path traversal weakness (CWE-22) might yield the full pathname of the + installed application. + metadata: + category: security + cwe: CWE-209 + security-severity: Low + shortDescription: Information Exposure Through an Error Message + technology: + - scala + patterns: + - pattern: $E.printStackTrace(...) + severity: WARNING + - id: scala_unsafe_rule-SensitiveDataExposure + languages: + - scala + message: | + Applications can unintentionally leak information about their configuration, internal + workings, or violate privacy through a variety of application problems. Pages that provide + different responses based on the validity of the data can lead to Information Leakage; + specifically when data deemed confidential is being revealed as a result of the web + application's design. + metadata: + category: security + cwe: CWE-497 + security-severity: Info + shortDescription: Exposure of sensitive system information to an unauthorized control sphere + technology: + - scala + - play + patterns: + - pattern-inside: | + def $FUNC(..., $ARG: String, ...) = $TYPE { + ... + } + - pattern-inside: | + $VAL = ($C: play.api.Configuration).underlying.getString($ARG) + ... + - pattern: Ok(<...$VAL...>) + severity: WARNING + - id: scala_xml_rule-ApacheXmlRpc + languages: + - scala + message: | + Enabling extensions in Apache XML RPC server or client can lead to deserialization + vulnerability which would allow an attacker to execute arbitrary code. + metadata: + category: security + cwe: CWE-502 + security-severity: Info + shortDescription: Deserialization of Untrusted Data + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + val $VAR = new XmlRpcServerConfigImpl(); + ... + - pattern: $VAR.setEnabledForExtensions(true); + - patterns: + - pattern-inside: | + val $VAR = new org.apache.xmlrpc.client.XmlRpcClientConfigImpl(); + ... + - pattern: $VAR.setEnabledForExtensions(true); + severity: WARNING + - id: scala_xml_rule-SAMLIgnoreComments + languages: + - scala + message: | + Ignoring XML comments in SAML may lead to authentication bypass + metadata: + category: security + cwe: CWE-1390 + security-severity: Medium + shortDescription: Weak authentication + pattern: '($POOL: BasicParserPool).setIgnoreComments(false);' + severity: WARNING + - id: scala_xml_rule-XmlDecoder + languages: + - scala + message: | + Avoid using XMLDecoder to parse content from an untrusted source. + metadata: + category: security + cwe: CWE-502 + security-severity: High + shortDescription: Deserialization of Untrusted Data + patterns: + - pattern-inside: | + $D = new java.beans.XMLDecoder($IN); + ... + - pattern-not-inside: | + $DX = new java.beans.XMLDecoder("..."); + ... + - pattern: $D.readObject + severity: WARNING + - id: scala_xml_rule-XsltTransform + languages: + - java + message: | + It is possible to attach malicious behavior to those style sheets. Therefore, if an attacker + can control the content or the source of the style sheet, he might be able to trigger remote + code execution. + metadata: + category: security + cwe: CWE-91 + security-severity: Medium + shortDescription: XML injection (aka Blind XPath injection) + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: (javax.xml.transform.TransformerFactory $T).newTransformer($SRC, ...) + - pattern-inside: (javax.xml.transform.Transformer $T).transform($SRC, ...) + - pattern: $SRC + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $FUNC(...,String $VAR, ...) { + ... + } + - pattern-either: + - pattern: new FileInputStream(<... $VAR ...>); + - pattern: getClass.getResourceAsStream(<... $VAR ...>) + - patterns: + - pattern-inside: | + class $CLZ { + String $X = "..."; + ... + } + - pattern-inside: | + $FUNC(...,String $Y, ...) { + ... + } + - pattern-either: + - pattern: new FileInputStream($X + $Y); + - pattern: getClass.getResourceAsStream($X + $Y) + severity: WARNING + - id: scala_xpathi_rule-XpathInjection + languages: + - scala + message: | + The input values included in SQL queries need to be passed in safely. Bind + variables in prepared statements can be used to easily mitigate the risk of + SQL injection. + metadata: + category: security + cwe: CWE-611 + security-severity: Medium + shortDescription: Improper Restriction of XML External Entity Reference ('XXE') + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: |- + import javax.xml.xpath._ + ... + - pattern-inside: |- + import javax.xml.xpath.XPath + ... + - pattern-either: + - pattern: $Y.compile(...) + - pattern: $X.evaluate(..., $ARG2) + pattern-sources: + - patterns: + - pattern-inside: | + def $FUNC(..., $ARG: $TYPE,...): $RET = { + ... + } + - pattern: $ARG + severity: ERROR + - id: scala_xss_rule-MVCApi + languages: + - scala + message: | + Disabling HTML escaping put the application at risk for Cross-Site Scripting (XSS). + metadata: + category: security + cwe: CWE-79 + security-severity: Info + shortDescription: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') + mode: taint + pattern-sanitizers: + - pattern: org.owasp.encoder.Encode.forHtml(...) + pattern-sinks: + - pattern: Ok(...) + pattern-sources: + - patterns: + - pattern-inside: | + def $FUNC(..., $ARG: String, ...) = Action { + ... + } + - focus-metavariable: $ARG + severity: WARNING + - id: scala_xss_rule-RequestWrapper + languages: + - scala + message: | + Avoid using custom XSS filtering. Please use standard sanitization functions. + metadata: + category: security + cwe: CWE-79 + security-severity: Medium + shortDescription: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') + patterns: + - pattern-inside: | + class $CLASS(...) extends HttpServletRequestWrapper(...) { + ... + } + - pattern: def stripXSS(...) = { ... } + severity: INFO + - id: scala_xss_rule-WicketXSS + languages: + - scala + message: | + Disabling HTML escaping put the application at risk for Cross-Site Scripting (XSS). + metadata: + category: security + cwe: CWE-79 + security-severity: Medium + shortDescription: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') + patterns: + - pattern: '($X: Label).setEscapeModelStrings(false);' + severity: WARNING + - id: scala_xss_rule-XSSReqParamToServletWriter + languages: + - scala + message: | + Servlet reflected cross site scripting vulnerability + metadata: + category: security + cwe: CWE-79 + security-severity: Medium + shortDescription: Improper Neutralization of Input During Web Page Generation + technology: + - scala + mode: taint + pattern-sanitizers: + - pattern: Encode.forHtml(...) + - pattern: org.owasp.esapi.Encoder.encodeForSQL(...) + pattern-sinks: + - patterns: + - pattern-inside: 'def $FUNC(..., $RES: HttpServletResponse, ...): $TYPE = {...}' + - pattern-inside: | + $WRITER = $RES.getWriter + ... + - pattern: $WRITER.write(...) + - patterns: + - pattern-inside: 'def $FUNC(..., $RES: HttpServletResponse, ...): $TYPE = {...}' + - pattern: $RES.getWriter.write(...) + - patterns: + - pattern-inside: 'def $FUNC(..., $RES: HttpServletResponse, ...): $TYPE = {...}' + - pattern: $RES.getWriter.print(...) + pattern-sources: + - patterns: + - pattern-inside: 'def $FUNC(..., $REQ: HttpServletRequest, ...): $TYPE = {...}' + - pattern-either: + - pattern: $REQ.getParameter(...) + - pattern: $REQ.getQueryString + severity: WARNING + - id: scala_xss_rule-XSSServlet + languages: + - scala + message: | + A potential XSS was found. It could be used to execute unwanted JavaScript in a + client's browser. + metadata: + category: security + cwe: CWE-79 + security-severity: Info + shortDescription: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') + mode: taint + pattern-sanitizers: + - patterns: + - pattern-inside: org.owasp.encoder.Encode.forHtml($TAINTED); + - pattern: $TAINTED + pattern-sinks: + - patterns: + - pattern-inside: 'def $FUNC(..., $RES: HttpServletResponse, ...): $TYPE = {...}' + - pattern-inside: | + $WRITER = $RES.getWriter; + ... + - pattern: $WRITER.write($DATA,...); + - pattern: $DATA + - patterns: + - pattern-inside: 'def $FUNC(..., $RES: HttpServletResponse, ...): $TYPE = {...}' + - pattern: $RES.getWriter.write($DATA,...); + - pattern: $DATA + pattern-sources: + - patterns: + - pattern-inside: 'def $FUNC(..., $REQ: HttpServletRequest, ...): $TYPE = {...}' + - pattern: $REQ.getParameter(...); + severity: WARNING + - id: scala_xxe_rule-Document + languages: + - scala + message: | + XML External Entity (XXE) attacks can occur when an XML parser supports XML + entities while processing XML received from an untrusted source. + metadata: + category: security + cwe: CWE-611 + security-severity: Medium + shortDescription: Improper Restriction of XML External Entity Reference ('XXE') + patterns: + - pattern-inside: | + $DF = DocumentBuilderFactory.newInstance + ... + - pattern-not-inside: | + $DF.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + - pattern-not-inside: | + $DF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) + ... + - pattern: $DB.parse(...) + severity: ERROR + - id: scala_xxe_rule-SaxParserXXE + languages: + - scala + message: | + XML External Entity (XXE) attacks can occur when an XML parser supports XML + entities while processing XML received from an untrusted source. + metadata: + category: security + cwe: CWE-611 + security-severity: Info + shortDescription: Improper Restriction of XML External Entity Reference ('XXE') + patterns: + - pattern-inside: | + val $SF = SAXParserFactory.newInstance + ... + - pattern-not-inside: | + $SF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) + ... + - pattern-not-inside: | + $SF.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + - pattern-inside: | + val $P = $SFP.newSAXParser + ... + - pattern: $P.parse(...); + severity: ERROR + - id: scala_xxe_rule-Trans + languages: + - scala + message: | + XML External Entity (XXE) attacks can occur when an XML parser supports XML + entities while processing XML received from an untrusted source. + metadata: + category: security + cwe: CWE-611 + security-severity: Medium + shortDescription: Improper Restriction of XML External Entity Reference ('XXE') + mode: taint + pattern-sanitizers: + - pattern: $T.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + - pattern: $T.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + - pattern: $T.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + pattern-sinks: + - pattern: $T.transform(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: |- + import javax.xml.transform._ + ... + - pattern-inside: |- + import javax.xml.transform.Transformer + ... + - pattern: $FACT.newTransformer + severity: ERROR + - id: scala_xxe_rule-XMLRdr + languages: + - scala + message: | + XML External Entity (XXE) attacks can occur when an XML parser supports XML + entities while processing XML received from an untrusted source. + metadata: + category: security + cwe: CWE-611 + security-severity: Medium + shortDescription: Improper Restriction of XML External Entity Reference ('XXE') + patterns: + - pattern-inside: | + val $R = XMLReaderFactory.createXMLReader + ... + - pattern-not-inside: | + $R.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) + ... + - pattern: $R.parse(...) + severity: ERROR + - id: scala_xxe_rule-XMLStreamRdr + languages: + - scala + message: | + XML External Entity (XXE) attacks can occur when an XML parser supports XML + entities while processing XML received from an untrusted source. + metadata: + category: security + cwe: CWE-611 + security-severity: Medium + shortDescription: Improper Restriction of XML External Entity Reference ('XXE') + patterns: + - pattern-inside: | + $SF = XMLInputFactory.newFactory + ... + - pattern-not-inside: | + $SF.setProperty(XMLInputFactory.SUPPORT_DTD, false) + ... + - pattern-not-inside: | + $SF.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false) + ... + - pattern: $SF.createXMLStreamReader(...) + severity: ERROR + - id: scala_xxe_rule-XPathXXE + languages: + - scala + message: | + XML External Entity (XXE) attacks can occur when an XML parser supports XML + entities while processing XML received from an untrusted source. + metadata: + category: security + cwe: CWE-611 + security-severity: Medium + shortDescription: Improper Restriction of XML External Entity Reference ('XXE') + patterns: + - pattern-inside: | + val $DF = DocumentBuilderFactory.newInstance + ... + - pattern-not-inside: | + $DF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "") + ... + - pattern-not-inside: | + $DF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "") + ... + - pattern-not-inside: | + $DF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) + ... + - pattern-not-inside: | + $DF.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + - pattern-inside: | + $B = $DF.newDocumentBuilder + ... + - pattern: $XPATH.evaluate(...) + severity: ERROR - id: codacy.java.security.hard-coded-password languages: - java @@ -34349,17 +103806,6 @@ rules: metavariable: $PASSWORD regex: (?i).*(password|motdepasse|heslo|adgangskode|wachtwoord|salasana|passwort|passord|senha|geslo|clave|losenord|clave|parola|secret|pwd).* severity: ERROR - - id: codacy.generic.plsql.empty-strings - languages: - - generic - message: Empty strings can lead to unexpected behavior and should be handled carefully. - metadata: - category: security - confidence: MEDIUM - description: Detects empty strings in the code which might cause issues or bugs. - impact: MEDIUM - pattern: $VAR VARCHAR2($LENGTH) := ''; - severity: WARNING - id: codacy.generic.plsql.find-all-passwords languages: - generic @@ -34415,6 +103861,104 @@ rules: - pattern: | $RESOURCE := WPG_DOCLOAD.DOWNLOAD_FILE($...ARGS); severity: ERROR + - id: codacy.generic.sql.grant-all + languages: + - generic + message: | + GRANT ALL privileges should not be used as it gives excessive permissions that violate the principle of least privilege. Instead, grant only the specific privileges that are required. + metadata: + category: security + confidence: LOW + description: Detects use of GRANT ALL which gives excessive database privileges + impact: HIGH + owasp: + - A5:2017 Broken Access Control + paths: + include: + - '*.sql' + pattern: | + GRANT ALL $X + severity: ERROR + - id: codacy.generic.sql.grant-select-no-role + languages: + - generic + message: | + GRANT SELECT privileges should only be given to role-based accounts (ending in '_role'). Direct grants to users or non-role accounts violate security best practices. + metadata: + category: security + confidence: LOW + description: Detects GRANT SELECT statements that are not targeting role-based accounts + impact: MEDIUM + owasp: + - A5:2017 Broken Access Control + paths: + include: + - '*.sql' + pattern-regex: GRANT\s+(DELETE|INSERT|SELECT|UPDATE)(\s*,\s*(DELETE|INSERT|SELECT|UPDATE))*\s+ON\s+[a-zA-Z0-9_]+(\.[a-zA-Z0-9_*]+)?\s+TO\s+(?![a-zA-Z0-9_]*_role\b)[a-zA-Z0-9_]+ + severity: ERROR + - id: codacy.generic.sql.fnd-profile-in-query + languages: + - generic + message: | + FND_PROFILE functions should not be used directly in SELECT or WHERE clauses. Instead, assign the FND_PROFILE function value to a variable first and then use that variable in the query. This improves performance and maintainability. + metadata: + category: performance + confidence: LOW + description: Detects direct usage of FND_PROFILE functions in SQL queries instead of using variables + impact: MEDIUM + paths: + include: + - '*.sql' + patterns: + - pattern-either: + - pattern-regex: (?i)SELECT\s+.*\bFND_PROFILE\.[a-zA-Z0-9_]+\( + - pattern-regex: (?i)SELECT\s+.*\bFROM\b.*\bWHERE\b.*\bFND_PROFILE\.[a-zA-Z0-9_]+\( + severity: ERROR + - id: codacy.java.security.flexible-search-sql-injection + languages: + - java + message: 'Possible SQL Injection: Avoid concatenating user input in FlexibleSearchQuery.' + metadata: + category: security + confidence: LOW + technology: + - sap-commerce + - hybris + patterns: + - pattern-either: + - pattern: | + new FlexibleSearchQuery("SELECT " + ...) + - pattern: | + new FlexibleSearchQuery("..." + $VAR + "...") + - pattern-not: | + new FlexibleSearchQuery("SELECT ... ?param") + severity: ERROR + - id: codacy.csharp.security.null-dereference + languages: + - csharp + message: | + Potential null dereference detected. The parameter or variable could be null and should be validated before accessing its members. Add a null check before dereferencing the object to prevent NullReferenceException at runtime. + metadata: + category: security + confidence: LOW + technology: + - csharp + - dotnet + patterns: + - pattern-inside: | + $RETURNTYPE $METHOD(...,$TYPE $NULLABLE, ...) { ... } + - pattern-not-inside: | + if ($NULLABLE == null) { ... } + ... + - pattern-either: + - pattern: | + $NULLABLE.$MEMBER + - pattern: | + $FUNCTION_NAME($NULLABLE, ...); + - pattern-not: | + if ($NULLABLE == null) { return ... } + ... + severity: ERROR - id: codacy.generic.security.detect-invisible-unicode languages: - yaml @@ -34435,3 +103979,19 @@ rules: - '*.yml' pattern-regex: "[​‌‍⁠\uFEFF]" severity: WARNING + - id: codacy.generic.csharp-lowercase-variables + languages: + - csharp + message: Variable names should be lowercase + metadata: + category: codestyle + confidence: LOW + description: Variable names should be lowercase + impact: LOW + technology: + - .net + paths: + include: + - '*.cs' + pattern-regex: (?:int|string|long|float|char|double|bool|var)\s([A-Z0-9]) + severity: INFO diff --git a/plugins/tools/trivy/plugin.yaml b/plugins/tools/trivy/plugin.yaml index c96221eb..bb93a023 100644 --- a/plugins/tools/trivy/plugin.yaml +++ b/plugins/tools/trivy/plugin.yaml @@ -1,6 +1,6 @@ name: trivy description: Trivy is a comprehensive security scanner for containers and other artifacts. -default_version: 0.65.0 +default_version: 0.66.0 download: url_template: "https://github.com/aquasecurity/trivy/releases/download/v{{.Version}}/trivy_{{.Version}}_{{.OS}}-{{.Arch}}.{{.Extension}}" file_name_template: "trivy_{{.Version}}_{{.OS}}_{{.Arch}}" diff --git a/plugins/tools/trivy/test/expected.sarif b/plugins/tools/trivy/test/expected.sarif index ac01ee90..747aa1d1 100644 --- a/plugins/tools/trivy/test/expected.sarif +++ b/plugins/tools/trivy/test/expected.sarif @@ -34,7 +34,7 @@ "text": "Package: brace-expansion\nInstalled Version: 1.1.11\nVulnerability CVE-2025-5889\nSeverity: LOW\nFixed Version: 2.0.2, 1.1.12, 3.0.1, 4.0.1\nLink: [CVE-2025-5889](https://avd.aquasec.com/nvd/cve-2025-5889)" }, "ruleId": "CVE-2025-5889", - "ruleIndex": 0 + "ruleIndex": 4 }, { "level": "error", @@ -115,7 +115,7 @@ "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2021-33203\nSeverity: MEDIUM\nFixed Version: 2.2.24, 3.1.12, 3.2.4\nLink: [CVE-2021-33203](https://avd.aquasec.com/nvd/cve-2021-33203)" }, "ruleId": "CVE-2021-33203", - "ruleIndex": 3 + "ruleIndex": 5 }, { "level": "warning", @@ -142,7 +142,34 @@ "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2024-45231\nSeverity: MEDIUM\nFixed Version: 5.1.1, 5.0.9, 4.2.16\nLink: [CVE-2024-45231](https://avd.aquasec.com/nvd/cve-2024-45231)" }, "ruleId": "CVE-2024-45231", - "ruleIndex": 4 + "ruleIndex": 6 + }, + { + "level": "error", + "locations": [ + { + "message": { + "text": "requirements.txt: django@1.11.29" + }, + "physicalLocation": { + "artifactLocation": { + "uri": "requirements.txt", + "uriBaseId": "ROOTPATH" + }, + "region": { + "endColumn": 1, + "endLine": 1, + "startColumn": 1, + "startLine": 1 + } + } + } + ], + "message": { + "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2025-57833\nSeverity: HIGH\nFixed Version: 4.2.24, 5.1.12, 5.2.6\nLink: [CVE-2025-57833](https://avd.aquasec.com/nvd/cve-2025-57833)" + }, + "ruleId": "CVE-2025-57833", + "ruleIndex": 3 }, { "level": "warning", @@ -178,10 +205,10 @@ "informationUri": "https://github.com/aquasecurity/trivy", "name": "Trivy", "rules": null, - "version": "0.65.0" + "version": "0.66.0" } } } ], "version": "2.1.0" -} +} \ No newline at end of file diff --git a/tools/semgrepConfigCreator.go b/tools/semgrepConfigCreator.go index a4e6d5e4..d51f9df5 100644 --- a/tools/semgrepConfigCreator.go +++ b/tools/semgrepConfigCreator.go @@ -35,7 +35,7 @@ func FilterRulesFromFile(rulesData []byte, config []domain.PatternConfiguration) // Create a map of enabled pattern IDs for faster lookup enabledPatterns := make(map[string]bool) for _, pattern := range config { - if pattern.Enabled && pattern.PatternDefinition.Enabled { + if pattern.Enabled { // Extract rule ID from pattern ID parts := strings.SplitN(pattern.PatternDefinition.Id, "_", 2) if len(parts) == 2 { diff --git a/tools/testdata/repositories/trivy/expected.sarif b/tools/testdata/repositories/trivy/expected.sarif index 1088e5b7..3c4b75be 100644 --- a/tools/testdata/repositories/trivy/expected.sarif +++ b/tools/testdata/repositories/trivy/expected.sarif @@ -37,7 +37,7 @@ } } ], - "version": "0.65.0" + "version": "0.66.0" } }, "results": [ From a765c93ce3eb0d86ee3ca36c6c9f2bda393ebfd9 Mon Sep 17 00:00:00 2001 From: Pedro Pereira Date: Thu, 18 Sep 2025 14:49:32 +0100 Subject: [PATCH 2/2] fix: semgrep rules updated CF-1809 --- codacy-client/client.go | 21 +- codacy-client/client_test.go | 63 +- .../expected/tools-configs/semgrep.yaml | 45 +- .../expected/tools-configs/semgrep.yaml | 31 + .../expected/tools-configs/semgrep.yaml | 123705 ++++----------- plugins/tools/semgrep/embedded/rules.yaml | 232 +- plugins/tools/trivy/test/expected.sarif | 66 +- .../tools/trivy/test/src/.codacy/codacy.yaml | 2 +- tools/semgrepConfigCreator.go | 5 - 9 files changed, 27485 insertions(+), 96685 deletions(-) diff --git a/codacy-client/client.go b/codacy-client/client.go index c7768d8f..4b548f57 100644 --- a/codacy-client/client.go +++ b/codacy-client/client.go @@ -172,12 +172,29 @@ func parsePatternConfigurations(response []byte) ([]domain.PatternConfiguration, // GetDefaultToolPatternsConfig fetches the default patterns for a tool func GetDefaultToolPatternsConfig(initFlags domain.InitFlags, toolUUID string, onlyEnabledPatterns bool) ([]domain.PatternConfiguration, error) { - baseURL := fmt.Sprintf("%s/api/v3/tools/%s/patterns", CodacyApiBase, toolUUID) + return GetDefaultToolPatternsConfigWithCodacyAPIBase(CodacyApiBase, initFlags, toolUUID, onlyEnabledPatterns) +} + +// GetDefaultToolPatternsConfigWithCodacyAPIBase fetches the default patterns for a tool, and a base api url +func GetDefaultToolPatternsConfigWithCodacyAPIBase(codacyAPIBaseURL string, initFlags domain.InitFlags, toolUUID string, onlyEnabledPatterns bool) ([]domain.PatternConfiguration, error) { + baseURL := fmt.Sprintf("%s/api/v3/tools/%s/patterns", codacyAPIBaseURL, toolUUID) if onlyEnabledPatterns { baseURL += "?enabled=true" } - return getAllPages(baseURL, initFlags, parseDefaultPatternConfigurations) + allPaterns, err := getAllPages(baseURL, initFlags, parseDefaultPatternConfigurations) + if err != nil { + return nil, err + } + + onlyRecommendedPatterns := make([]domain.PatternConfiguration, 0) + for _, pattern := range allPaterns { + if pattern.PatternDefinition.Enabled { + onlyRecommendedPatterns = append(onlyRecommendedPatterns, pattern) + } + } + + return onlyRecommendedPatterns, nil } // GetRepositoryToolPatterns fetches the patterns for a tool in a repository diff --git a/codacy-client/client_test.go b/codacy-client/client_test.go index 2e921ce9..072905ad 100644 --- a/codacy-client/client_test.go +++ b/codacy-client/client_test.go @@ -2,6 +2,7 @@ package codacyclient import ( "encoding/json" + "fmt" "net/http" "net/http/httptest" "testing" @@ -100,15 +101,55 @@ func TestGetDefaultToolPatternsConfig_Empty(t *testing.T) { })) defer ts.Close() - // TODO: Refactor GetDefaultToolPatternsConfig to accept a baseURL for easier testing - // oldBase := CodacyApiBase - // CodacyApiBase = ts.URL - // defer func() { CodacyApiBase = oldBase }() - - // Placeholder: test cannot be run until function is refactored for testability - _ = ts // avoid unused warning - // initFlags := domain.InitFlags{ApiToken: "dummy"} - // patterns, err := GetDefaultToolPatternsConfig(initFlags, "tool-uuid") - // assert.NoError(t, err) - // assert.Empty(t, patterns) + CodacyApiBase = ts.URL + + initFlags := domain.InitFlags{ApiToken: "dummy"} + patterns, err := GetDefaultToolPatternsConfigWithCodacyAPIBase(CodacyApiBase, initFlags, "tool-uuid", true) + assert.NoError(t, err) + assert.Empty(t, patterns) +} + +func TestGetDefaultToolPatternsConfig_WithNonRecommended(t *testing.T) { + + config := []domain.PatternDefinition{ + { + Id: "internal_id_1", + Enabled: true, + }, + { + Id: "internal_id_2", + Enabled: false, + }, + } + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + resp := map[string]interface{}{ + "data": config, + "pagination": map[string]interface{}{"cursor": ""}, + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(resp) + })) + defer ts.Close() + + expected := []domain.PatternConfiguration{ + { + Enabled: true, + PatternDefinition: domain.PatternDefinition{ + Id: "internal_id_1", + Enabled: true, + }, + }, + } + + CodacyApiBase = ts.URL + + initFlags := domain.InitFlags{ApiToken: "dummy"} + patterns, err := GetDefaultToolPatternsConfigWithCodacyAPIBase(CodacyApiBase, initFlags, "tool-uuid", true) + + fmt.Println(len(patterns)) + + assert.NoError(t, err) + assert.Equal(t, expected, patterns) } diff --git a/integration-tests/config-discover/expected/tools-configs/semgrep.yaml b/integration-tests/config-discover/expected/tools-configs/semgrep.yaml index bf5e218f..3ff8d613 100644 --- a/integration-tests/config-discover/expected/tools-configs/semgrep.yaml +++ b/integration-tests/config-discover/expected/tools-configs/semgrep.yaml @@ -29501,6 +29501,43 @@ rules: } - focus-metavariable: $SECRET severity: WARNING + - id: terraform.aws.security.aws-provisioner-exec.aws-provisioner-exec + languages: + - terraform + message: Provisioners are a tool of last resort and should be avoided where possible. Provisioner behavior cannot be mapped by Terraform as part of a plan, and execute arbitrary shell commands by design. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-77: Improper Neutralization of Special Elements used in a Command (''Command Injection'')' + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2021 - Injection + - A01:2017 - Injection + references: + - https://developer.hashicorp.com/terraform/language/resources/provisioners/remote-exec + - https://developer.hashicorp.com/terraform/language/resources/provisioners/local-exec + subcategory: + - guardrail + technology: + - terraform + patterns: + - pattern-either: + - pattern: | + provisioner "remote-exec" { + ... + } + - pattern: | + provisioner "local-exec" { + ... + } + - pattern-inside: | + resource "aws_instance" "..." { + ... + } + severity: WARNING - id: terraform.aws.security.aws-rds-backup-no-retention.aws-rds-backup-no-retention languages: - hcl @@ -34374,8 +34411,12 @@ rules: - A3:2017 Sensitive Data Exposure options: generic_ellipsis_max_span: 0 - pattern: | - $PASSWORD VARCHAR2($LENGTH) := $...VALUE; + patterns: + - pattern: | + $PASSWORD VARCHAR2($LENGTH) := $...VALUE; + - metavariable-regex: + metavariable: $PASSWORD + regex: (?i).*(password|motdepasse|heslo|adgangskode|wachtwoord|salasana|passwort|passord|senha|geslo|clave|losenord|clave|parola|secret|pwd).* severity: ERROR - id: codacy.generic.plsql.resource-injection languages: diff --git a/integration-tests/init-with-token/expected/tools-configs/semgrep.yaml b/integration-tests/init-with-token/expected/tools-configs/semgrep.yaml index 9ae36146..d36cdca7 100644 --- a/integration-tests/init-with-token/expected/tools-configs/semgrep.yaml +++ b/integration-tests/init-with-token/expected/tools-configs/semgrep.yaml @@ -1,4 +1,22 @@ rules: + - id: bash.lang.correctness.unquoted-expansion.unquoted-variable-expansion-in-command + languages: + - bash + message: Variable expansions must be double-quoted so as to prevent being split into multiple pieces according to whitespace or whichever separator is specified by the IFS variable. If you really wish to split the variable's contents, you may use a variable that starts with an underscore e.g. $_X instead of $X, and semgrep will ignore it. If what you need is an array, consider using a proper bash array. + metadata: + category: correctness + technology: + - bash + patterns: + - pattern-either: + - pattern: | + ... ${$VAR} ... + - pattern: | + ... ...${$VAR}... ... + - metavariable-regex: + metavariable: $VAR + regex: '[*@0-9]|[A-Za-z].*' + severity: INFO - id: clojure.lang.security.use-of-md5.use-of-md5 languages: - clojure @@ -30,6 +48,19 @@ rules: - pattern: (java.security.MessageDigest/getInstance MessageDigestAlgorithms/MD5) - pattern: (java.security.MessageDigest/getInstance org.apache.commons.codec.digest.MessageDigestAlgorithms/MD5) severity: WARNING + - fix: Bitwise.bnot($VAL) + id: elixir.lang.best-practice.deprecated-bnot-operator.deprecated_bnot_operator + languages: + - elixir + message: The bitwise operator (`^^^`) is already deprecated. Please use `Bitwise.bnot($VAL)` instead. + metadata: + category: best-practice + references: + - https://github.com/elixir-lang/elixir/commit/f1b9d3e818e5bebd44540f87be85979f24b9abfc + technology: + - elixir + pattern: ~~~$VAL + severity: WARNING - id: codacy.generic.plsql.empty-strings languages: - generic diff --git a/integration-tests/init-without-token/expected/tools-configs/semgrep.yaml b/integration-tests/init-without-token/expected/tools-configs/semgrep.yaml index d79dcc00..3ff8d613 100644 --- a/integration-tests/init-without-token/expected/tools-configs/semgrep.yaml +++ b/integration-tests/init-without-token/expected/tools-configs/semgrep.yaml @@ -1,367 +1,4 @@ rules: - - id: ai.csharp.detect-openai.detect-openai - languages: - - csharp - message: 'Possibly found usage of AI: OpenAI' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: using OpenAI - - pattern: (ChatClient $CLIENT) - - pattern: (ChatClient $CLIENT).$FUNC(...) - severity: INFO - - id: ai.dart.detect-gemini.detect-gemini - languages: - - dart - message: 'Possibly found usage of AI: Gemini' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import 'package:google_generative_ai'; - - pattern: final $MODEL = GenerativeModel(...); - severity: INFO - - id: ai.go.detect-gemini.detect-gemini - languages: - - go - message: 'Possibly found usage of AI: Gemini' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import "github.com/google/generative-ai-go" - - pattern: genai.NewClient(...) - severity: INFO - - id: ai.go.detect-openai.detect-openai - languages: - - go - message: 'Possibly found usage of AI: OpenAI' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import "github.com/sashabaranov/go-openai" - - pattern: gogpt.NewClient(...) - severity: INFO - - id: ai.kotlin.detect-gemini.detect-gemini - languages: - - kotlin - message: 'Possibly found usage of AI: Gemini' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import com.google.ai - - pattern: GenerativeModel(...) - severity: INFO - - id: ai.python.detect-anthropic.detect-anthropic - languages: - - python - message: 'Possibly found usage of AI: Anthropic' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import anthropic - - pattern: from anthropic import $ANYTHING - - pattern: Anthropic(...) - - pattern: anthropic.Anthropic(...) - - pattern: $CLIENT.messages.$FUNC(...,model=...,...) - severity: INFO - - id: ai.python.detect-gemini.detect-gemini - languages: - - python - message: 'Possibly found usage of AI: Gemini' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import google.generativeai - severity: INFO - - id: ai.python.detect-huggingface.detect-huggingface - languages: - - python - message: 'Possibly found usage of AI: HuggingFace' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import huggingface_hub - severity: INFO - - id: ai.python.detect-langchain.detect-langchain - languages: - - python - message: 'Possibly found usage of AI tooling: LangChain' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import langchain_openai - - pattern: ChatOpenAI(...) - - pattern: import langchain_community - - pattern: Ollama(...) - - pattern: import langchain_anthropic - - pattern: ChatAnthropic(...) - - pattern: import langchain_cohere - - pattern: ChatCohere(...) - - pattern: import langchain_core - - pattern: import langchain - severity: INFO - - id: ai.python.detect-mistral.detect-mistral - languages: - - python - message: 'Possibly found usage of AI: Mistral' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import mistralai - - pattern: MistralClient(...) - - pattern: $CLIENT.chat(...,model=...,...) - severity: INFO - - id: ai.python.detect-openai.detect-openai - languages: - - python - message: 'Possibly found usage of AI: OpenAI' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import openai - - pattern: from openai import $ANYTHING - - pattern: OpenAI(...) - - pattern: $CLIENT.chat.completions.$FUNC(...) - severity: INFO - - id: ai.python.detect-pytorch.detect-pytorch - languages: - - python - message: 'Possibly found usage of AI tooling: PyTorch' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import torch - - pattern: torch.$FUNC(...) - severity: INFO - - id: ai.python.detect-tensorflow.detect-tensorflow - languages: - - python - message: 'Possibly found usage of AI tooling: Tensorflow' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import tensorflow - severity: INFO - - id: ai.swift.detect-apple-core-ml.detect-apple-core-ml - languages: - - swift - message: 'Possibly found usage of AI: Apple CoreML' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: VNCoreMLModel(...) - - pattern: MLModelConfiguration(...) - severity: INFO - - id: ai.swift.detect-gemini.detect-gemini - languages: - - swift - message: 'Possibly found usage of AI: Gemini' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import GoogleGenerativeAI - - pattern: GenerativeModel(...) - severity: INFO - - id: ai.typescript.detect-anthropic.detect-anthropic - languages: - - js - - ts - message: 'Possibly found usage of AI: Anthropic' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import "@anthropic-ai" - - pattern: import $ANYTHING from "@anthropic-ai"; - - pattern: new Anthropic(...) - - pattern: anthropic.messages.$FUNC(...) - severity: INFO - - id: ai.typescript.detect-gemini.detect-gemini - languages: - - js - - ts - message: 'Possibly found usage of AI: Gemini' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import "@google/generative-ai" - - pattern: import $ANYTHING from "@google/generative-ai"; - - pattern: new GoogleGenerativeAI(...) - - pattern: $GENAI.getGenerativeModel(...) - severity: INFO - - id: ai.typescript.detect-mistral.detect-mistral - languages: - - js - - ts - message: 'Possibly found usage of AI: Mistral' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import "@mistralai" - - pattern: new MistralClient(...) - - pattern: '$CLIENT.chat({model: ...})' - severity: INFO - - id: ai.typescript.detect-openai.detect-openai - languages: - - js - - ts - message: 'Possibly found usage of AI: OpenAI' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import "openai" - - pattern: import $ANYTHING from "openai"; - - pattern: new OpenAI(...) - - pattern: $CLIENT.chat.completions.$FUNC(...) - severity: INFO - - id: ai.typescript.detect-promptfoo.detect-promptfoo - languages: - - js - - ts - message: 'Possibly found usage of AI tooling: promptfoo' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import "promptfoo" - - pattern: promptfoo.evaluate(...) - severity: INFO - - id: ai.typescript.detect-vercel-ai.detect-vercel-ai - languages: - - js - - ts - message: 'Possibly found usage of AI: VercelAI' - metadata: - category: maintainability - confidence: LOW - references: - - http://semgrep.dev/blog/2024/detecting-shadow-ai - technology: - - genAI - - LLMs - pattern-either: - - pattern: import "ai" - - pattern: import "@ai-sdk" - - pattern: generateText({model:...}) - - pattern: generateText({prompt:...}) - severity: INFO - id: bash.curl.security.curl-eval.curl-eval languages: - bash @@ -391,310 +28,6 @@ rules: - pattern: | `curl ...` severity: WARNING - - id: bash.curl.security.curl-pipe-bash.curl-pipe-bash - languages: - - bash - message: Data is being piped into `bash` from a `curl` command. An attacker with control of the server in the `curl` command could inject malicious code into the pipe, resulting in a system compromise. Avoid piping untrusted data into `bash` or any other shell if you can. If you must do this, consider checking the SHA sum of the content returned by the server to verify its integrity. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - bash - - curl - patterns: - - pattern-either: - - pattern: curl ... | ... bash ... - - pattern: curl ... | ... /bin/bash ... - - pattern: '... bash <(curl ...)' - - pattern: '... /bin/bash <(curl ...)' - - pattern: '... bash -c "$(curl ...)"' - - pattern: '... /bin/bash -c "$(curl ...)"' - severity: WARNING - - id: bash.lang.best-practice.iteration-over-ls-output.iteration-over-ls-output - languages: - - bash - message: Iterating over ls output is fragile. Use globs, e.g. 'dir/*' instead of '$(ls dir)'. - metadata: - category: best-practice - references: - - https://github.com/koalaman/shellcheck/wiki/SC2045 - technology: - - bash - patterns: - - pattern: | - for $VAR in $LIST; do - ... - done - - pattern: | - $(ls ...) - severity: WARNING - - id: bash.lang.best-practice.useless-cat.useless-cat - languages: - - bash - message: Useless call to 'cat' in a pipeline. Use '<' and '>' for any command to read from a file or write to a file. - metadata: - category: best-practice - references: - - https://github.com/koalaman/shellcheck/wiki/SC2002 - technology: - - bash - pattern-either: - - pattern: | - cat | ... - - patterns: - - pattern: | - cat $ARG | ... - - pattern-not: | - cat ${$SEVERAL_FILES} | ... - - pattern: | - ... | cat - - pattern: | - ... | cat | ... - severity: WARNING - - id: bash.lang.correctness.unquoted-expansion.unquoted-variable-expansion-in-command - languages: - - bash - message: Variable expansions must be double-quoted so as to prevent being split into multiple pieces according to whitespace or whichever separator is specified by the IFS variable. If you really wish to split the variable's contents, you may use a variable that starts with an underscore e.g. $_X instead of $X, and semgrep will ignore it. If what you need is an array, consider using a proper bash array. - metadata: - category: correctness - technology: - - bash - patterns: - - pattern-either: - - pattern: | - ... ${$VAR} ... - - pattern: | - ... ...${$VAR}... ... - - metavariable-regex: - metavariable: $VAR - regex: '[*@0-9]|[A-Za-z].*' - severity: INFO - - id: bash.lang.correctness.unquoted-expansion.unquoted-command-substitution-in-command - languages: - - bash - message: The result of command substitution $(...) or `...`, if unquoted, is split on whitespace or other separators specified by the IFS variable. You should surround it with double quotes to avoid splitting the result. - metadata: - category: correctness - technology: - - bash - patterns: - - pattern-either: - - pattern: | - ... $(...) ... - - pattern: | - ... ...$(...)... ... - - pattern-regex: | - .*(\$\([^\(]|`).+([^\)]\)|`).* - severity: INFO - - id: bash.lang.security.ifs-tampering.ifs-tampering - languages: - - bash - message: The special variable IFS affects how splitting takes place when expanding unquoted variables. Don't set it globally. Prefer a dedicated utility such as 'cut' or 'awk' if you need to split input data. If you must use 'read', set IFS locally using e.g. 'IFS="," read -a my_array'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-20: Improper Input Validation' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - bash - pattern: IFS=... - severity: WARNING - - fix: strcmp($X, $Y) == 0 - id: c.lang.correctness.c-string-equality.c-string-equality - languages: - - c - - cpp - message: Using == on char* performs pointer comparison, use strcmp instead - metadata: - category: correctness - technology: - - c - - cpp - patterns: - - pattern: (char *$X) == (char *$Y) - - metavariable-comparison: - comparison: $X != 0 - metavariable: $X - - metavariable-comparison: - comparison: $Y != 0 - metavariable: $Y - severity: ERROR - - id: c.lang.correctness.goto-fail.double_goto - languages: - - c - - cpp - message: The second goto statement will always be executed. - metadata: - category: correctness - technology: - - c - - cpp - pattern: | - if ($COND) - goto $FAIL; - goto $FAIL; - severity: WARNING - - id: c.lang.correctness.incorrect-use-ato-fn.incorrect-use-ato-fn - languages: - - c - - cpp - message: Avoid the 'ato*()' family of functions. Their use can lead to undefined behavior, integer overflows, and lack of appropriate error handling. Instead prefer the 'strtol*()' family of functions. - metadata: - category: correctness - references: - - https://stackoverflow.com/q/38393162 - - https://stackoverflow.com/q/14176123 - technology: - - c - - cpp - pattern-either: - - pattern: atoi(...) - - pattern: atol(...) - - pattern: atoll(...) - severity: WARNING - - id: c.lang.correctness.incorrect-use-sscanf-fn.incorrect-use-sscanf-fn - languages: - - c - - cpp - message: Avoid 'sscanf()' for number conversions. Its use can lead to undefined behavior, slow processing, and integer overflows. Instead prefer the 'strto*()' family of functions. - metadata: - category: correctness - references: - - https://stackoverflow.com/q/22865622 - - https://stackoverflow.com/q/7021725 - - https://www.mattkeeter.com/blog/2021-03-01-happen/ - technology: - - c - - cpp - patterns: - - pattern: sscanf($STR, $FMT, $PTR); - - metavariable-regex: - metavariable: $FMT - regex: '"%(l{0,2}|L)([fegEa]|[dDiouxX])"' - severity: WARNING - - id: c.lang.security.double-free.double-free - languages: - - c - - cpp - message: Variable '$VAR' was freed twice. This can lead to undefined behavior. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-415: Double Free' - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - - A01:2017 - Injection - references: - - https://cwe.mitre.org/data/definitions/415.html - - https://owasp.org/www-community/vulnerabilities/Doubly_freeing_memory - subcategory: - - vuln - technology: - - c - - cpp - patterns: - - pattern-not: | - free($VAR); - ... - $VAR = NULL; - ... - free($VAR); - - pattern-not: | - free($VAR); - ... - $VAR = malloc(...); - ... - free($VAR); - - pattern-inside: | - free($VAR); - ... - $FREE($VAR); - - metavariable-pattern: - metavariable: $FREE - pattern: free - - focus-metavariable: $FREE - severity: ERROR - - id: c.lang.security.function-use-after-free.function-use-after-free - languages: - - c - - cpp - message: Variable '$VAR' was passed to a function after being freed. This can lead to undefined behavior. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-416: Use After Free' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - references: - - https://cwe.mitre.org/data/definitions/416.html - - https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/use_after_free/ - subcategory: - - vuln - technology: - - c - - cpp - patterns: - - pattern-either: - - pattern: $FUNC(..., <... $VAR ...>, ...) - - pattern: $FUNC(..., <... $VAR->$ACCESSOR ...>, ...) - - pattern: $FUNC(..., <... (*$VAR).$ACCESSOR ...>, ...) - - pattern: $FUNC(..., <... $VAR[$NUM] ...>, ...) - - metavariable-regex: - metavariable: $FUNC - regex: (?!^free$) - - pattern-inside: free($VAR); ... - - pattern-not-inside: free($VAR); ... $VAR = NULL; ... - - pattern-not-inside: free($VAR); ... $VAR = malloc(...); ... - severity: WARNING - - id: c.lang.security.info-leak-on-non-formatted-string.info-leak-on-non-formated-string - languages: - - c - - cpp - message: Use %s, %d, %c... to format your variables, otherwise this could leak information. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-532: Insertion of Sensitive Information into Log File' - impact: MEDIUM - likelihood: LOW - owasp: - - A09:2021 - Security Logging and Monitoring Failures - references: - - http://nebelwelt.net/files/13PPREW.pdf - subcategory: - - audit - technology: - - c - - cpp - pattern: printf(argv[$NUM]); - severity: WARNING - id: c.lang.security.insecure-use-gets-fn.insecure-use-gets-fn languages: - c @@ -716,164 +49,6 @@ rules: - cpp pattern: gets(...) severity: ERROR - - fix: memset_s($...VARS) - id: c.lang.security.insecure-use-memset.insecure-use-memset - languages: - - c - - cpp - message: When handling sensitive information in a buffer, it's important to ensure that the data is securely erased before the buffer is deleted or reused. While `memset()` is commonly used for this purpose, it can leave sensitive information behind due to compiler optimizations or other factors. To avoid this potential vulnerability, it's recommended to use the `memset_s()` function instead. `memset_s()` is a standardized function that securely overwrites the memory with a specified value, making it more difficult for an attacker to recover any sensitive data that was stored in the buffer. By using `memset_s()` instead of `memset()`, you can help to ensure that your application is more secure and less vulnerable to exploits that rely on residual data in memory. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-14: Compiler Removal of Code to Clear Buffers' - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://cwe.mitre.org/data/definitions/14.html - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures/ - subcategory: - - audit - technology: - - c - - cpp - pattern: memset($...VARS) - severity: WARNING - - id: c.lang.security.insecure-use-printf-fn.insecure-use-printf-fn - languages: - - c - - cpp - message: Avoid using user-controlled format strings passed into 'sprintf', 'printf' and 'vsprintf'. These functions put you at risk of buffer overflow vulnerabilities through the use of format string exploits. Instead, use 'snprintf' and 'vsnprintf'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-134: Use of Externally-Controlled Format String' - impact: HIGH - likelihood: MEDIUM - references: - - https://doc.castsoftware.com/display/SBX/Never+use+sprintf%28%29+or+vsprintf%28%29+functions - - https://www.cvedetails.com/cwe-details/134/Uncontrolled-Format-String.html - subcategory: - - vuln - technology: - - c - - cpp - patterns: - - pattern-either: - - pattern: | - $FUNC($BUFFER, argv[$NUM], ...); - ... - vsprintf(..., $BUFFER, ...); - - pattern: vsprintf(..., argv[$NUM], ...) - - pattern: | - $FUNC($BUFFER, argv[$NUM], ...); - ... - sprintf(..., $BUFFER, ...); - - pattern: sprintf(...,argv[$NUM],...) - - pattern: | - $FUNC($BUFFER, argv[$NUM], ...); - ... - printf(..., $BUFFER, ...); - - pattern: printf(...,argv[$NUM],...) - - metavariable-comparison: - comparison: int($NUM) > 0 - metavariable: $NUM - severity: WARNING - - id: c.lang.security.insecure-use-scanf-fn.insecure-use-scanf-fn - languages: - - c - - cpp - message: Avoid using 'scanf()'. This function, when used improperly, does not consider buffer boundaries and can lead to buffer overflows. Use 'fgets()' instead for reading input. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-676: Use of Potentially Dangerous Function' - impact: HIGH - likelihood: LOW - references: - - http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html - subcategory: - - audit - technology: - - c - - cpp - pattern: scanf(...) - severity: WARNING - - id: c.lang.security.insecure-use-strcat-fn.insecure-use-strcat-fn - languages: - - c - - cpp - message: Finding triggers whenever there is a strcat or strncat used. This is an issue because strcat or strncat can lead to buffer overflow vulns. Fix this by using strcat_s instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-676: Use of Potentially Dangerous Function' - impact: HIGH - likelihood: LOW - references: - - https://nvd.nist.gov/vuln/detail/CVE-2019-12553 - - https://techblog.mediaservice.net/2020/04/cve-2020-2851-stack-based-buffer-overflow-in-cde-libdtsvc/ - subcategory: - - audit - technology: - - c - - cpp - pattern-either: - - pattern: strcat(...) - - pattern: strncat(...) - severity: WARNING - - id: c.lang.security.insecure-use-string-copy-fn.insecure-use-string-copy-fn - languages: - - c - - cpp - message: Finding triggers whenever there is a strcpy or strncpy used. This is an issue because strcpy does not affirm the size of the destination array and strncpy will not automatically NULL-terminate strings. This can lead to buffer overflows, which can cause program crashes and potentially let an attacker inject code in the program. Fix this by using strcpy_s instead (although note that strcpy_s is an optional part of the C11 standard, and so may not be available). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-676: Use of Potentially Dangerous Function' - impact: HIGH - likelihood: LOW - references: - - https://cwe.mitre.org/data/definitions/676 - - https://nvd.nist.gov/vuln/detail/CVE-2019-11365 - subcategory: - - audit - technology: - - c - - cpp - pattern-either: - - pattern: strcpy(...) - - pattern: strncpy(...) - severity: WARNING - - id: c.lang.security.insecure-use-strtok-fn.insecure-use-strtok-fn - languages: - - c - - cpp - message: Avoid using 'strtok()'. This function directly modifies the first argument buffer, permanently erasing the delimiter character. Use 'strtok_r()' instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-676: Use of Potentially Dangerous Function' - impact: HIGH - likelihood: LOW - references: - - https://wiki.sei.cmu.edu/confluence/display/c/STR06-C.+Do+not+assume+that+strtok%28%29+leaves+the+parse+string+unchanged - - https://man7.org/linux/man-pages/man3/strtok.3.html#BUGS - - https://stackoverflow.com/a/40335556 - subcategory: - - audit - technology: - - c - - cpp - pattern: strtok(...) - severity: WARNING - id: c.lang.security.random-fd-exhaustion.random-fd-exhaustion languages: - c @@ -913,72 +88,6 @@ rules: ... $BYTES_READ = read($FD, ...); severity: WARNING - - id: c.lang.security.use-after-free.use-after-free - languages: - - c - - cpp - message: Variable '$VAR' was used after being freed. This can lead to undefined behavior. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-416: Use After Free' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - references: - - https://cwe.mitre.org/data/definitions/416.html - - https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/use_after_free/ - subcategory: - - vuln - technology: - - c - - cpp - patterns: - - pattern-either: - - pattern: $VAR->$ACCESSOR - - pattern: (*$VAR).$ACCESSOR - - pattern: $VAR[$NUM] - - pattern-inside: free($VAR); ... - - pattern-not-inside: $VAR = NULL; ... - - pattern-not-inside: free($VAR); ... $VAR = malloc(...); ... - severity: WARNING - - id: clojure.lang.security.command-injection-shell-call.command-injection-shell-call - languages: - - clojure - message: A call to clojure.java.shell has been found, this could lead to an RCE if the inputs are user-controllable. Please ensure their origin is validated and sanitized. - metadata: - author: Gabriel Marquet - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://clojuredocs.org/clojure.java.shell/sh - subcategory: - - audit - technology: - - clojure - patterns: - - pattern-either: - - pattern-inside: "(ns ...\n...\n(:require \n... \n[clojure.java.shell ... [sh]]\n...\n))\n...\n" - - pattern-inside: "(ns ...\n...\n(:use \n... \n[clojure.java.shell ... [sh]]\n...\n))\n...\n" - - pattern-either: - - patterns: - - pattern: (sh $BASH ...) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern: (sh $ARG ...) - - pattern-not: (sh "..." ...) - severity: ERROR - id: clojure.lang.security.documentbuilderfactory-xxe.documentbuilderfactory-xxe languages: - clojure @@ -1101,51 +210,13 @@ rules: metavariable: $ALGO regex: (((org\.apache\.commons\.codec\.digest\.)?MessageDigestAlgorithms/)?"?(SHA-1|SHA1)"?) severity: WARNING - - id: clojure.security.clojure-read-string.read-string-unsafe.read-string-unsafe + - id: csharp.dotnet.security.audit.ldap-injection.ldap-injection languages: - - clojure - message: The default core Clojure read-string method is dangerous and can lead to deserialization vulnerabilities. Use the edn/read-string instead. + - csharp + message: LDAP queries are constructed dynamically on user-controlled input. This vulnerability in code could lead to an arbitrary LDAP query execution. metadata: - author: Gabriel Marquet category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2020-top25: true - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - http://www.learningclojure.com/2013/02/clojures-reader-is-unsafe.html#post-body-2898830171141471587 - - https://ericnormand.me/article/clojure-web-security - - https://github.com/jafingerhut/jafingerhut.github.com/blob/master/clojure-info/using-edn-safely.md#vulnerabilities-in-clojurecores-read-and-read-string - source-rule-url: https://github.com/clj-holmes/clj-holmes-rules/tree/main/security/clojure-read-string - subcategory: - - audit - technology: - - clojure - patterns: - - pattern-not-inside: | - (ns ... - (... :exclude [read read-string])) - ... - (defn $VAR [$X]...) - - pattern-inside: | - (defn $VAR [$X]...) - - pattern: | - (read-string $X) - severity: ERROR - - id: csharp.dotnet.security.audit.ldap-injection.ldap-injection - languages: - - csharp - message: LDAP queries are constructed dynamically on user-controlled input. This vulnerability in code could lead to an arbitrary LDAP query execution. - metadata: - category: security - confidence: MEDIUM + confidence: MEDIUM cwe: - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' impact: MEDIUM @@ -1227,37 +298,6 @@ rules: } - focus-metavariable: $ARG severity: WARNING - - id: csharp.dotnet.security.audit.misconfigured-lockout-option.misconfigured-lockout-option - languages: - - csharp - message: A misconfigured lockout mechanism allows an attacker to execute brute-force attacks. Account lockout must be correctly configured and enabled to prevent these attacks. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-307: Improper Restriction of Excessive Authentication Attempts' - impact: HIGH - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - - https://cwe.mitre.org/data/definitions/307.html - subcategory: - - audit - technology: - - dotnet - patterns: - - pattern-either: - - pattern: | - $SIGNIN.PasswordSignInAsync(...,lockoutOnFailure: false,...); - - pattern: | - $SIGNIN.CheckPasswordSignInAsync(...,lockoutOnFailure: false,...); - - pattern-inside: | - public async $TYPE $METHOD(...) { - ... - } - severity: WARNING - id: csharp.dotnet.security.audit.missing-or-broken-authorization.missing-or-broken-authorization languages: - csharp @@ -1344,39 +384,6 @@ rules: ... } severity: INFO - - id: csharp.dotnet.security.audit.razor-use-of-htmlstring.razor-use-of-htmlstring - languages: - - generic - message: ASP.NET Core MVC provides an HtmlString class which isn't automatically encoded upon output. This should never be used in combination with untrusted input as this will expose an XSS vulnerability. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-116: Improper Encoding or Escaping of Output' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://cwe.mitre.org/data/definitions/116.html - - https://owasp.org/Top10/A03_2021-Injection/ - - https://docs.microsoft.com/en-us/aspnet/core/security/cross-site-scripting?view=aspnetcore-6.0#html-encoding-using-razor - subcategory: - - audit - technology: - - .net - paths: - include: - - '*.cshtml' - patterns: - - pattern-either: - - pattern: new ...HtmlString(...) - - pattern: '@(new ...HtmlString(...))' - - pattern-not-inside: '@(new ...HtmlString(...HtmlEncode(...)))' - - pattern-not-inside: '@(new ...HtmlString(...Encode(...)))' - - pattern-not-inside: new ...HtmlString(...HtmlEncode(...)) - - pattern-not-inside: new ...HtmlString(...Encode(...)) - severity: WARNING - id: csharp.dotnet.security.audit.xpath-injection.xpath-injection languages: - csharp @@ -1415,113 +422,6 @@ rules: string $INPUT; } severity: ERROR - - id: csharp.dotnet.security.mvc-missing-antiforgery.mvc-missing-antiforgery - languages: - - csharp - message: $METHOD is a state-changing MVC method that does not validate the antiforgery token or do strict content-type checking. State-changing controller methods should either enforce antiforgery tokens or do strict content-type checking to prevent simple HTTP request types from bypassing CORS preflight controls. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://cheatsheetseries.owasp.org/cheatsheets/DotNet_Security_Cheat_Sheet.html#cross-site-request-forgery - - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests - subcategory: - - audit - technology: - - .net - - mvc - patterns: - - pattern: | - [$HTTPMETHOD] - public IActionResult $METHOD(...){ - ... - } - - pattern-inside: | - using Microsoft.AspNetCore.Mvc; - ... - - pattern-not: | - [ValidateAntiForgeryToken] - public IActionResult $METHOD(...){ - ... - } - - pattern-not: | - [Consumes(...)] - public IActionResult $METHOD(...){ - ... - } - - metavariable-regex: - metavariable: $HTTPMETHOD - regex: Http(Post|Put|Delete|Patch) - severity: WARNING - - id: csharp.dotnet.security.net-webconfig-debug.net-webconfig-debug - languages: - - generic - message: ASP.NET applications built with `debug` set to true in production may leak debug information to attackers. Debug mode also affects performance and reliability. Set `debug` to `false` or remove it from `` - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-11: ASP.NET Misconfiguration: Creating Debug Binary' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://web.archive.org/web/20190919105353/https://blogs.msdn.microsoft.com/prashant_upadhyay/2011/07/14/why-debugfalse-in-asp-net-applications-in-production-environment/ - - https://msdn.microsoft.com/en-us/library/e8z01xdh.aspx - subcategory: - - audit - technology: - - .net - paths: - include: - - '*web.config*' - patterns: - - pattern: | - - - pattern-inside: | - - ... - - severity: WARNING - - id: csharp.dotnet.security.net-webconfig-trace-enabled.net-webconfig-trace-enabled - languages: - - generic - message: OWASP guidance recommends disabling tracing for production applications to prevent accidental leakage of sensitive application information. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-1323: Improper Management of Sensitive Trace Data' - impact: MEDIUM - likelihood: LOW - owasp: A05:2021 - Security Misconfiguration - references: - - https://cheatsheetseries.owasp.org/cheatsheets/DotNet_Security_Cheat_Sheet.html#asp-net-web-forms-guidance - - https://msdn.microsoft.com/en-us/library/e8z01xdh.aspx - subcategory: - - audit - technology: - - .net - paths: - include: - - '*web.config*' - patterns: - - pattern: | - - - pattern-inside: | - - ... - - severity: WARNING - id: csharp.dotnet.security.razor-template-injection.razor-template-injection languages: - csharp @@ -1695,89 +595,6 @@ rules: - pattern: (RSAPKCS1KeyExchangeFormatter $FORMATER).CreateKeyExchange(...); - pattern: (RSAPKCS1KeyExchangeDeformatter $DEFORMATER).DecryptKeyExchange(...); severity: WARNING - - id: csharp.dotnet.security.web-config-insecure-cookie-settings.web-config-insecure-cookie-settings - languages: - - generic - message: Cookie Secure flag is explicitly disabled. You should enforce this value to avoid accidentally presenting sensitive cookie values over plaintext HTTP connections. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/http-cookies - - https://docs.microsoft.com/en-us/dotnet/api/system.web.security.formsauthentication.requiressl?redirectedfrom=MSDN&view=netframework-4.8#System_Web_Security_FormsAuthentication_RequireSSL - - https://docs.microsoft.com/en-us/dotnet/api/system.web.security.roles.cookierequiressl?redirectedfrom=MSDN&view=netframework-4.8#System_Web_Security_Roles_CookieRequireSSL - subcategory: - - audit - technology: - - .net - - asp - - webforms - paths: - include: - - '*web.config' - patterns: - - pattern-either: - - pattern: | - requireSSL="false" - - pattern: | - cookieRequireSSL="false" - - pattern-either: - - pattern-inside: | - - - pattern-inside: | - - - pattern-inside: | - - severity: WARNING - - id: csharp.lang.best-practice.structured-logging.structured-logging - languages: - - csharp - message: String interpolation in log message obscures the distinction between variables and the log message. Use structured logging instead, where the variables are passed as additional arguments and the interpolation is performed by the logging library. This reduces the possibility of log injection and makes it easier to search through logs. - metadata: - category: best-practice - confidence: LOW - cwe: - - 'CWE-117: Improper Output Neutralization for Logs' - impact: LOW - likelihood: LOW - owasp: - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://github.com/NLog/NLog/wiki/How-to-use-structured-logging - - https://softwareengineering.stackexchange.com/questions/312197/benefits-of-structured-logging-vs-basic-logging - subcategory: - - audit - technology: - - .net - - serilog - - nlog - patterns: - - pattern-either: - - pattern: $LOG.Debug($"...") - - pattern: $LOG.Error($"...") - - pattern: $LOG.Fatal($"...") - - pattern: $LOG.Information($"...") - - pattern: $LOG.Verbose($"...") - - pattern: $LOG.Warning($"...") - - pattern: $LOG.LogCritical($"...") - - pattern: $LOG.LogDebug($"...") - - pattern: $LOG.LogError($"...") - - pattern: $LOG.LogInformation($"...") - - pattern: $LOG.LogTrace($"...") - - pattern: $LOG.LogWarning($"...") - - pattern: $LOG.Info($"...") - - pattern: $LOG.Trace($"...") - - pattern: $LOG.Warn($"...") - - metavariable-regex: - metavariable: $LOG - regex: .*(log|LOG|Log) - severity: INFO - id: csharp.lang.correctness.double.double-epsilon-equality.correctness-double-epsilon-equality languages: - csharp @@ -1978,38 +795,6 @@ rules: - pattern: $CERT.SubjectName.Name - pattern: $CERT.GetNameInfo(...) severity: WARNING - - id: csharp.lang.security.cryptography.x509certificate2-privkey.x509certificate2-privkey - languages: - - C# - message: 'X509Certificate2.PrivateKey is obsolete. Use a method such as GetRSAPrivateKey() or GetECDsaPrivateKey(). Alternatively, use the CopyWithPrivateKey() method to create a new instance with a private key. Further, if you set X509Certificate2.PrivateKey to `null` or set it to another key without deleting it first, the private key will be left on disk. ' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-310: CWE CATEGORY: Cryptographic Issues' - impact: LOW - likelihood: LOW - owasp: - - A02:2021 - Cryptographic Failures - references: - - https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate2.privatekey - subcategory: - - audit - technology: - - .net - patterns: - - pattern-inside: | - using System.Security.Cryptography; - ... - - pattern-either: - - pattern-inside: | - X509Certificate2Collection $COLLECTION = ...; - ... - - pattern-inside: | - X509Certificate2 $CERT = ...; - ... - - pattern: $CERT.PrivateKey - severity: WARNING - fix: RequireSignedTokens = true id: csharp.lang.security.cryptography.unsigned-security-token.unsigned-security-token languages: @@ -2125,93 +910,6 @@ rules: metavariable: $PREFIX regex: (http|https)://(\*|\+)(.[a-zA-Z]{2,})?:[0-9]+ severity: WARNING - - id: csharp.lang.security.injections.os-command.os-command-injection - languages: - - csharp - message: The software constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/Command_Injection - subcategory: - - audit - technology: - - .net - patterns: - - pattern-inside: | - using System.Diagnostics; - ... - - pattern-inside: | - public $T $F(..., $ARG, ...) - { - ... - } - - pattern-either: - - patterns: - - pattern: | - Process.Start($ARG, ...); - - focus-metavariable: $ARG - - patterns: - - pattern-inside: | - Process $PROC = new Process(); - ... - - pattern-either: - - pattern-inside: | - $PROC.StartInfo.FileName = $ARG; - ... - - pattern-inside: | - $PROC.StartInfo.Arguments = <... $ARG ...>; - ... - - pattern: | - $PROC.Start(); - - patterns: - - patterns: - - pattern-inside: | - ProcessStartInfo $PSINFO = new ProcessStartInfo() - { - ... - }; - ... - - pattern-either: - - pattern-inside: | - FileName = $ARG; - ... - - pattern-inside: | - Arguments = <... $ARG ...>; - ... - - pattern: | - Process.Start($PSINFO); - - focus-metavariable: $PSINFO - - patterns: - - pattern-inside: | - Process $PROC = new Process() - { - StartInfo = new ProcessStartInfo() - { - ... - } - }; - ... - - pattern-either: - - pattern-inside: | - FileName = $ARG; - ... - - pattern-inside: | - Arguments = $ARG; - ... - - pattern: | - $PROC.Start(); - severity: ERROR - id: csharp.lang.security.insecure-deserialization.binary-formatter.insecure-binaryformatter-deserialization languages: - C# @@ -2241,64 +939,6 @@ rules: - pattern: | new BinaryFormatter(); severity: WARNING - - id: csharp.lang.security.insecure-deserialization.data-contract-resolver.data-contract-resolver - languages: - - C# - message: Only use DataContractResolver if you are completely sure of what information is being serialized. Malicious types can cause unexpected behavior. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide - subcategory: - - audit - technology: - - .net - patterns: - - pattern: | - class $MYDCR : DataContractResolver { ... } - severity: WARNING - - id: csharp.lang.security.insecure-deserialization.fast-json.insecure-fastjson-deserialization - languages: - - C# - message: $type extension has the potential to be unsafe, so use it with common sense and known json sources and not public facing ones to be safe - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://github.com/mgholam/fastJSON#security-warning-update - subcategory: - - audit - technology: - - .net - patterns: - - pattern-inside: | - using fastJSON; - ... - - pattern: | - new JSONParameters - { - BadListTypeChecking = false - } - severity: WARNING - id: csharp.lang.security.insecure-deserialization.fs-pickler.insecure-fspickler-deserialization languages: - C# @@ -2328,80 +968,6 @@ rules: - pattern: | FsPickler.CreateJsonSerializer(); severity: WARNING - - id: csharp.lang.security.insecure-deserialization.insecure-typefilterlevel-full.insecure-typefilterlevel-full - languages: - - C# - message: Using a .NET remoting service can lead to RCE, even if you try to configure TypeFilterLevel. Recommended to switch from .NET Remoting to WCF https://docs.microsoft.com/en-us/dotnet/framework/wcf/migrating-from-net-remoting-to-wcf - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.typefilterlevel?view=net-6.0 - - https://www.synacktiv.com/en/publications/izi-izi-pwn2own-ics-miami.html - subcategory: - - audit - technology: - - .net - pattern-either: - - patterns: - - pattern-either: - - pattern: new BinaryServerFormatterSinkProvider { TypeFilterLevel = $LEVEL } - - patterns: - - pattern-inside: | - $TYPE $SP = new BinaryServerFormatterSinkProvider(...); - ... - - pattern: | - $SP.TypeFilterLevel = $LEVEL - - metavariable-regex: - metavariable: $LEVEL - regex: (.*)TypeFilterLevel\.(Full|Low) - - patterns: - - pattern-inside: | - $DICT["typeFilterLevel"] = $VAL; - ... - - pattern: new BinaryServerFormatterSinkProvider(..., $DICT, ...) - - metavariable-regex: - metavariable: $VAL - regex: (\"Full\"|\"Low\") - severity: WARNING - - id: csharp.lang.security.insecure-deserialization.javascript-serializer.insecure-javascriptserializer-deserialization - languages: - - C# - message: The SimpleTypeResolver class is insecure and should not be used. Using SimpleTypeResolver to deserialize JSON could allow the remote client to execute malicious code within the app and take control of the web server. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.microsoft.com/en-us/dotnet/api/system.web.script.serialization.simpletyperesolver?view=netframework-4.8#remarks - subcategory: - - audit - technology: - - .net - patterns: - - pattern-inside: | - using System.Web.Script.Serialization; - ... - - pattern: | - new JavaScriptSerializer((SimpleTypeResolver $RESOLVER)) - severity: ERROR - id: csharp.lang.security.insecure-deserialization.los-formatter.insecure-losformatter-deserialization languages: - C# @@ -2460,48 +1026,6 @@ rules: - pattern: | new NetDataContractSerializer(); severity: WARNING - - id: csharp.lang.security.insecure-deserialization.newtonsoft.insecure-newtonsoft-deserialization - languages: - - csharp - message: TypeNameHandling $TYPEHANDLER is unsafe and can lead to arbitrary code execution in the context of the process. Use a custom SerializationBinder whenever using a setting other than TypeNameHandling.None. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_TypeNameHandling.htm#remarks - subcategory: - - audit - technology: - - .net - - newtonsoft - - json - patterns: - - pattern-either: - - pattern: TypeNameHandling = TypeNameHandling.$TYPEHANDLER - - pattern: | - $SETTINGS.TypeNameHandling = TypeNameHandling.$TYPEHANDLER; - ... - JsonConvert.DeserializeObject<$TYPE>(...,$SETTINGS); - - pattern: | - $SETTINGS.TypeNameHandling = TypeNameHandling.$TYPEHANDLER; - ... - JsonConvert.DeserializeObject(...,$SETTINGS); - - pattern-inside: | - using Newtonsoft.Json; - ... - - metavariable-regex: - metavariable: $TYPEHANDLER - regex: (All|Auto|Objects|Arrays) - severity: WARNING - id: csharp.lang.security.insecure-deserialization.soap-formatter.insecure-soapformatter-deserialization languages: - C# @@ -2531,115 +1055,6 @@ rules: - pattern: | new SoapFormatter(); severity: WARNING - - id: csharp.lang.security.memory.memory-marshal-create-span.memory-marshal-create-span - languages: - - C# - message: MemoryMarshal.CreateSpan and MemoryMarshal.CreateReadOnlySpan should be used with caution, as the length argument is not checked. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-125: Out-of-bounds Read' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.memorymarshal.createspan?view=net-6.0 - - https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.memorymarshal.createreadonlyspan?view=net-6.0 - subcategory: - - audit - technology: - - .net - pattern-either: - - pattern: MemoryMarshal.CreateSpan(...) - - pattern: MemoryMarshal.CreateReadOnlySpan(...) - severity: WARNING - - id: csharp.lang.security.missing-hsts-header.missing-hsts-header - languages: - - csharp - message: The HSTS HTTP response security header is missing, allowing interaction and communication to be sent over the insecure HTTP protocol. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-346: Origin Validation Error' - impact: LOW - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cwe.mitre.org/data/definitions/346.html - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures/ - subcategory: - - audit - technology: - - dotnet - pattern-either: - - patterns: - - pattern-inside: | - public void Configure(...) { - ... - (IApplicationBuilder $APP). ...; - ... - } - - focus-metavariable: $APP - - pattern-not-inside: | - public void Configure(...) { - ... - (IApplicationBuilder $APP).UseHsts(...); - ... - } - - patterns: - - pattern-inside: | - public void ConfigureServices(...) { - ... - (IServiceCollection $SERVICES). ...; - ... - } - - focus-metavariable: $SERVICES - - pattern-not-inside: | - public void ConfigureServices(...) { - ... - (IServiceCollection $SERVICES).AddHsts(...); - ... - } - severity: WARNING - - id: csharp.lang.security.open-redirect.open-redirect - languages: - - csharp - message: A query string parameter may contain a URL value that could cause the web application to redirect the request to a malicious website controlled by an attacker. Make sure to sanitize this parameter sufficiently. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://cwe.mitre.org/data/definitions/601.html - subcategory: - - vuln - technology: - - csharp - mode: taint - pattern-sinks: - - patterns: - - pattern: Redirect(...) - - pattern-not-inside: "if (IsLocalUrl(...)) { \n ... \n Redirect(...); \n ...\n}\n" - - pattern-not-inside: "if ($URL.IsLocalUrl(...)) { \n ... \n Redirect(...); \n ...\n}\n" - pattern-sources: - - patterns: - - focus-metavariable: $PARAM - - pattern-inside: | - public $TYPE $FUNCNAME (..., string $PARAM, ...) { - ... - } - severity: ERROR - id: csharp.lang.security.regular-expression-dos.regular-expression-dos-infinite-timeout.regular-expression-dos-infinite-timeout languages: - C# @@ -2776,243 +1191,6 @@ rules: - pattern-not: | "..." severity: ERROR - - id: csharp.lang.security.ssrf.http-client.ssrf - languages: - - csharp - message: SSRF is an attack vector that abuses an application to interact with the internal/external network or the machine itself. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - .net - patterns: - - pattern-inside: | - using System.Net.Http; - ... - - pattern-either: - - pattern: | - $T $F(..., $X, ...) - { - ... - HttpClient $Y = new HttpClient(); - ... - ... $Y.GetAsync(<... $X ...>, ...); - } - - pattern: | - $T $F(..., $X, ...) - { - ... - $A $B = <... $X ...>; - ... - HttpClient $Y = new HttpClient(); - ... - ... $Y.GetAsync($B, ...); - } - - pattern: | - $T $F(..., $X, ...) - { - ... - HttpClient $Y = new HttpClient(); - ... - ... $Y.GetStringAsync(<... $X ...>); - } - - pattern: | - $T $F(..., $X, ...) - { - ... - $A $B = <... $X ...>; - ... - HttpClient $Y = new HttpClient(); - ... - ... $Y.GetStringAsync($B); - } - severity: ERROR - - id: csharp.lang.security.ssrf.rest-client.ssrf - languages: - - csharp - message: SSRF is an attack vector that abuses an application to interact with the internal/external network or the machine itself. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - .net - patterns: - - pattern-inside: | - using RestSharp; - ... - - pattern-either: - - pattern: | - $T $F(..., $X, ...) - { - ... - ... new RestClient(<... $X ...>); - } - - pattern: | - $T $F(..., $X, ...) - { - ... - $A $B = <... $X ...>; - ... - ... new RestClient($B); - } - severity: ERROR - - id: csharp.lang.security.ssrf.web-client.ssrf - languages: - - csharp - message: SSRF is an attack vector that abuses an application to interact with the internal/external network or the machine itself. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - .net - patterns: - - pattern-inside: | - using System.Net; - ... - - pattern-either: - - pattern: | - $T $F(..., $X, ...) - { - ... - WebClient $Y = new WebClient(); - ... - ... $Y.OpenRead(<... $X ...>); - } - - pattern: | - $T $F(..., $X, ...) - { - ... - $A $B = <... $X ...>; - ... - WebClient $Y = new WebClient(); - ... - ... $Y.OpenRead($B); - } - - pattern: | - $T $F(..., $X, ...) - { - ... - WebClient $Y = new WebClient(); - ... - ... $Y.OpenReadAsync(<... $X ...>, ...); - } - - pattern: | - $T $F(..., $X, ...) - { - ... - $A $B = <... $X ...>; - ... - WebClient $Y = new WebClient(); - ... - ... $Y.OpenReadAsync($B, ...); - } - - pattern: | - $T $F(..., $X, ...) - { - ... - WebClient $Y = new WebClient(); - ... - ... $Y.DownloadString(<... $X ...>); - } - - pattern: | - $T $F(..., $X, ...) - { - ... - $A $B = <... $X ...>; - ... - WebClient $Y = new WebClient(); - ... - ... $Y.DownloadString($B); - } - severity: ERROR - - id: csharp.lang.security.ssrf.web-request.ssrf - languages: - - csharp - message: The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. Many different options exist to fix this issue depending the use case (Application can send request only to identified and trusted applications, Application can send requests to ANY external IP address or domain name). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cwe.mitre.org/data/definitions/918.html - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - .net - patterns: - - pattern-inside: | - using System.Net; - ... - - pattern-either: - - pattern: | - $T $F(..., $X, ...) - { - ... - ... WebRequest.Create(<... $X ...>); - } - - pattern: | - $T $F($X) - { - ... - $A $B = <... $X ...>; - ... - ... WebRequest.Create($B); - } - - pattern: | - $T $F($X) - { - ... - $A $B = <... $X ...>; - ... - $C $D = <... $B ...>; - ... - ... WebRequest.Create($D); - } - severity: ERROR - id: csharp.lang.security.stacktrace-disclosure.stacktrace-disclosure languages: - csharp @@ -3151,1662 +1329,2211 @@ rules: - pattern-inside: | public $T $M(...,string $ARG,...){...} severity: WARNING - - id: csharp.razor.security.html-raw-json.html-raw-json + - id: dockerfile.security.last-user-is-root.last-user-is-root languages: - - generic - message: Unencoded JSON in HTML context is vulnerable to cross-site scripting, because `` is not properly encoded. + - dockerfile + message: The last user in the container is 'root'. This is a security hazard because if an attacker gains control of the container they will have root access. Switch back to another user after running commands as 'root'. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-269: Improper Privilege Management' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A04:2021 - Insecure Design references: - - https://owasp.org/Top10/A03_2021-Injection + - https://github.com/hadolint/hadolint/wiki/DL3002 + source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3002 subcategory: - audit technology: - - razor - paths: - include: - - '*.cshtml' + - dockerfile patterns: - - pattern-either: - - pattern: '@Html.Raw(Json.Encode(...))' - - pattern: '@Html.Raw(JsonConvert.SerializeObject(...))' - - pattern: '@Html.Raw(...ToJson(...))' + - pattern: USER root + - pattern-not-inside: + patterns: + - pattern: | + USER root + ... + USER $X + - metavariable-pattern: + metavariable: $X + patterns: + - pattern-not: root severity: ERROR - - id: dockerfile.audit.dockerfile-source-not-pinned.dockerfile-source-not-pinned + - fix: | + USER non-root + ENTRYPOINT $...VARS + id: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint languages: - dockerfile - message: To ensure reproducible builds, pin Dockerfile `FROM` commands to a specific hash. You can find the hash by running `docker pull $IMAGE` and then specify it with `$IMAGE:$VERSION@sha256:` + message: By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-269: Improper Privilege Management' + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2021 - Insecure Design references: - - https://stackoverflow.com/a/33511811/4965 + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit technology: - - docker + - dockerfile patterns: - - pattern-either: - - patterns: - - pattern: FROM $IMAGE:$VERSION@$HASH - - metavariable-regex: - metavariable: $HASH - regex: (?!sha256:) - - patterns: - - pattern: FROM $IMAGE - - pattern: FROM $IMAGE:$VERSION - - pattern-not-inside: FROM $IMAGE:$VERSION@$HASH - severity: INFO - - id: dockerfile.best-practice.avoid-apk-upgrade.avoid-apk-upgrade + - pattern: | + ENTRYPOINT $...VARS + - pattern-not-inside: | + USER $USER + ... + severity: ERROR + - fix: | + USER non-root + CMD $...VARS + id: dockerfile.security.missing-user.missing-user languages: - dockerfile - message: Packages in base images should be up-to-date, removing the need for 'apk upgrade'. If packages are out-of-date, consider contacting the base image maintainer. + message: By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-269: Improper Privilege Management' + impact: MEDIUM + likelihood: LOW + owasp: + - A04:2021 - Insecure Design references: - - https://github.com/hadolint/hadolint/wiki/DL3017 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3017 + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - audit technology: - dockerfile - pattern: RUN ... apk upgrade ... - severity: INFO - - id: dockerfile.best-practice.avoid-apt-get-upgrade.avoid-apt-get-upgrade + patterns: + - pattern: | + CMD $...VARS + - pattern-not-inside: | + USER $USER + ... + severity: ERROR + - id: dockerfile.security.no-sudo-in-dockerfile.no-sudo-in-dockerfile languages: - dockerfile - message: Packages in base containers should be up-to-date, removing the need to upgrade or dist-upgrade. If a package is out of date, contact the maintainers. + message: Avoid using sudo in Dockerfiles. Running processes as a non-root user can help reduce the potential impact of configuration errors and security vulnerabilities. metadata: - category: best-practice + category: security + confidence: HIGH + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration references: - - https://github.com/hadolint/hadolint/wiki/DL3005 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3005 + - https://cwe.mitre.org/data/definitions/250.html + - https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user + subcategory: + - audit technology: - dockerfile - pattern-either: - - pattern: RUN ... apt-get upgrade ... - - pattern: RUN ... apt-get dist-upgrade ... + patterns: + - pattern: | + RUN sudo ... severity: WARNING - - id: dockerfile.best-practice.avoid-dnf-update.avoid-dnf-update + - id: generic.secrets.security.detected-stripe-restricted-api-key.detected-stripe-restricted-api-key languages: - - dockerfile - message: Packages in base images should be up-to-date, removing the need for 'dnf update'. If packages are out-of-date, consider contacting the base image maintainer. + - regex + message: Stripe Restricted API Key detected metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/hadolint/hadolint/wiki/DL3039 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3039 + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + subcategory: + - audit technology: - - dockerfile - pattern: dnf update - severity: INFO - - id: dockerfile.best-practice.avoid-latest-version.avoid-latest-version + - secrets + - stripe + pattern-regex: rk_live_[0-9a-zA-Z]{24} + severity: ERROR + - id: generic.secrets.security.detected-username-and-password-in-uri.detected-username-and-password-in-uri languages: - - dockerfile - message: Images should be tagged with an explicit version to produce deterministic container images. The 'latest' tag may change the base container without warning. + - generic + message: Username and password in URI detected metadata: - category: best-practice - references: - - https://github.com/hadolint/hadolint/wiki/DL3007 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3007 - technology: - - dockerfile - pattern: FROM $FROM:latest - severity: WARNING - - fix: FROM $IMAGE - id: dockerfile.best-practice.avoid-platform-with-from.avoid-platform-with-from - languages: - - dockerfile - message: Using '--platform' with FROM restricts the image to build on a single platform. Further, this must be the same as the build platform. If you intended to specify the target platform, use the utility 'docker buildx --platform=' instead. - metadata: - category: best-practice - references: - - https://github.com/hadolint/hadolint/wiki/DL3029 - - https://docs.docker.com/buildx/working-with-buildx/ - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3029 - technology: - - dockerfile - pattern: FROM --platform=$PLATFORM $IMAGE - severity: INFO - - id: dockerfile.best-practice.avoid-yum-update.avoid-yum-update - languages: - - dockerfile - message: Packages in base images should be up-to-date, removing the need for 'yum update'. If packages are out-of-date, consider contacting the base image maintainer. - metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/hadolint/hadolint/wiki/DL3031 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3031 + - https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + subcategory: + - vuln technology: - - dockerfile - pattern: yum update - severity: INFO - - id: dockerfile.best-practice.avoid-zypper-update.avoid-zypper-update + - secrets + patterns: + - pattern: $PROTOCOL://$...USERNAME:$...PASSWORD@$END + - metavariable-regex: + metavariable: $...USERNAME + regex: \A({?)([A-Za-z])([A-Za-z0-9_-]){5,31}(}?)\Z + - metavariable-regex: + metavariable: $...PASSWORD + regex: (?!.*[\s])(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]){6,32} + - metavariable-regex: + metavariable: $PROTOCOL + regex: (.*http.*)|(.*sql.*)|(.*ftp.*)|(.*smtp.*) + severity: ERROR + - id: generic.secrets.security.google-maps-apikeyleak.google-maps-apikeyleak languages: - - dockerfile - message: Packages in base images should be up-to-date, removing the need for 'zypper update'. If packages are out-of-date, consider contacting the base image maintainer. + - generic + message: Detects potential Google Maps API keys in code metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-538: Insertion of Sensitive Information into Externally-Accessible File or Directory' + description: Detects potential Google Maps API keys in code + impact: HIGH + likelihood: MEDIUM + owasp: + - A3:2017 Sensitive Data Exposure references: - - https://github.com/hadolint/hadolint/wiki/DL3035 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3035 + - https://ozguralp.medium.com/unauthorized-google-maps-api-key-usage-cases-and-why-you-need-to-care-1ccb28bf21e + severity: MEDIUM + subcategory: + - audit technology: - - dockerfile - pattern: zypper update ... - severity: INFO - - fix: '# MAINTAINER $NAME' - id: dockerfile.best-practice.maintainer-is-deprecated.maintainer-is-deprecated + - Google Maps + patterns: + - pattern-regex: ^(AIza[0-9A-Za-z_-]{35}(?!\S))$ + severity: WARNING + - id: generic.visualforce.security.ncino.html.usesriforcdns.use-sri-for-cdns languages: - - dockerfile - message: MAINTAINER has been deprecated. + - generic + message: 'Consuming CDNs without including a SubResource Integrity (SRI) can expose your application and its users to compromised code. SRIs allow you to consume specific versions of content where if even a single byte is compromised, the resource will not be loaded. Add an integrity attribute to your + - pattern-not: + severity: ERROR + - id: generic.visualforce.security.ncino.xml.cspheaderattribute.csp-header-attribute languages: - - dockerfile - message: This 'dnf install' is missing the '-y' switch. This might stall builds because it requires human intervention. Add the '-y' switch. + - generic + message: Visualforce Pages must have the cspHeader attribute set to true. This attribute is available in API version 55 or higher. metadata: - category: best-practice + category: security + confidence: HIGH + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://github.com/hadolint/hadolint/wiki/DL3038 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3038 + - https://help.salesforce.com/s/articleView?id=sf.csp_trusted_sites.htm&type=5 + subcategory: + - vuln technology: - - dockerfile + - salesforce + - visualforce + paths: + include: + - '*.page' patterns: - - pattern: | - RUN ... dnf install ... - - pattern-not-inside: | - RUN ... dnf install ... -y ... - - pattern-not-inside: | - RUN ... dnf ... --assumeyes ... - severity: WARNING - - id: dockerfile.best-practice.missing-dnf-clean-all.missing-dnf-clean-all + - pattern: ... + - pattern-not: ... + - pattern-not: ...... + - pattern-not: ...... + severity: INFO + - id: generic.visualforce.security.ncino.xml.visualforceapiversion.visualforce-page-api-version languages: - - dockerfile - message: This dnf command does not end with '&& dnf clean all'. Running 'dnf clean all' will remove cached data and reduce package size. (This must be performed in the same RUN step.) + - generic + message: Visualforce Pages must use API version 55 or higher for required use of the cspHeader attribute set to true. metadata: - category: best-practice + category: security + confidence: HIGH + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://github.com/hadolint/hadolint/wiki/DL3038 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3038 + - https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_pages.htm + subcategory: + - vuln technology: - - dockerfile + - salesforce + - visualforce + paths: + include: + - '*.page-meta.xml' patterns: - - pattern: RUN ... dnf ... - - pattern-not-inside: RUN ... && dnf clean all - - pattern-not-inside: RUN ... && \ dnf clean all + - pattern-inside: + - pattern-either: + - pattern-regex: '[>][0-9].[0-9][<]' + - pattern-regex: '[>][1-4][0-9].[0-9][<]' + - pattern-regex: '[>][5][0-4].[0-9][<]' severity: WARNING - - id: dockerfile.best-practice.missing-image-version.missing-image-version + - id: go.aws-lambda.security.database-sqli.database-sqli languages: - - dockerfile - message: Detected docker image with no explicit version attached. Images should be tagged with an explicit version to produce deterministic container images -- attach a version when using `FROM `. + - go + message: Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use prepared statements with the 'Prepare' and 'PrepareContext' calls. metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://github.com/hadolint/hadolint/wiki/DL3006 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3006 + - https://pkg.go.dev/database/sql#DB.Query + subcategory: + - vuln technology: - - dockerfile - patterns: - - pattern-either: - - pattern: FROM $IMAGE - - pattern-not: FROM $IMAGE:$VERSION - - pattern-not: FROM $IMAGE@$DIGEST - - pattern-not: FROM $IMAGE:$VERSION@$DIGEST - - pattern-not: FROM scratch + - aws-lambda + - database + - sql + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern: $DB.Exec($QUERY,...) + - pattern: $DB.ExecContent($QUERY,...) + - pattern: $DB.Query($QUERY,...) + - pattern: $DB.QueryContext($QUERY,...) + - pattern: $DB.QueryRow($QUERY,...) + - pattern: $DB.QueryRowContext($QUERY,...) + - pattern-inside: | + import "database/sql" + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...} + ... + lambda.Start($HANDLER, ...) + - patterns: + - pattern-inside: | + func $HANDLER($EVENT $TYPE) {...} + ... + lambda.Start($HANDLER, ...) + - pattern-not-inside: | + func $HANDLER($EVENT context.Context) {...} + ... + lambda.Start($HANDLER, ...) + - focus-metavariable: $EVENT severity: WARNING - - id: dockerfile.best-practice.missing-no-install-recommends.missing-no-install-recommends + - id: go.aws-lambda.security.tainted-sql-string.tainted-sql-string languages: - - dockerfile - message: This 'apt-get install' is missing '--no-install-recommends'. This prevents unnecessary packages from being installed, thereby reducing image size. Add '--no-install-recommends'. + - go + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://github.com/hadolint/hadolint/wiki/DL3015 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3015 + - https://owasp.org/www-community/attacks/SQL_Injection + subcategory: + - vuln technology: - - dockerfile - patterns: - - pattern: | - RUN apt-get install ... - - pattern-not: RUN apt-get install ... --no-install-recommends ... - severity: INFO - - id: dockerfile.best-practice.missing-pip-no-cache-dir.missing-pip-no-cache-dir + - aws-lambda + mode: taint + pattern-sanitizers: + - pattern: strconv.Atoi(...) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: | + "$SQLSTR" + ... + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(\s*select|\s*delete|\s*insert|\s*create|\s*update|\s*alter|\s*drop).* + - patterns: + - pattern-either: + - pattern: fmt.Fprintf($F, "$SQLSTR", ...) + - pattern: fmt.Sprintf("$SQLSTR", ...) + - pattern: fmt.Printf("$SQLSTR", ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).* + - pattern-not-inside: | + log.$PRINT(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...} + ... + lambda.Start($HANDLER, ...) + - patterns: + - pattern-inside: | + func $HANDLER($EVENT $TYPE) {...} + ... + lambda.Start($HANDLER, ...) + - pattern-not-inside: | + func $HANDLER($EVENT context.Context) {...} + ... + lambda.Start($HANDLER, ...) + - focus-metavariable: $EVENT + severity: ERROR + - id: go.gorilla.security.audit.handler-assignment-from-multiple-sources.handler-assignment-from-multiple-sources languages: - - dockerfile - message: This '$PIP install' is missing '--no-cache-dir'. This flag prevents package archives from being kept around, thereby reducing image size. Add '--no-cache-dir'. + - go + message: 'Variable $VAR is assigned from two different sources: ''$Y'' and ''$R''. Make sure this is intended, as this could cause logic bugs if they are treated as they are the same object.' metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-289: Authentication Bypass by Alternate Name' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW references: - - https://github.com/hadolint/hadolint/wiki/DL3042 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3042 + - https://cwe.mitre.org/data/definitions/289.html + subcategory: + - audit technology: - - dockerfile - patterns: + - gorilla + mode: taint + pattern-sinks: - patterns: - pattern: | - RUN ... $PIP install ... - - pattern-not-inside: | - RUN ... $PIP install ... --no-cache-dir ... - - pattern-not-inside: | - RUN ... $PIP install . ... - - pattern-not-inside: | - ENV ... PIP_NO_CACHE_DIR=$BOOL ... + $Y, err := store.Get(...) ... - RUN ... $PIP install ... - - pattern-not-inside: | - ENV ... PIP_NO_CACHE_DIR ... + $VAR := $Y.Values[...] ... - RUN ... $PIP install ... - - metavariable-regex: - metavariable: $PIP - regex: (pip|pip2|pip3|python -m pip|python3 -m pip) - severity: INFO - - id: dockerfile.best-practice.missing-yum-assume-yes-switch.missing-yum-assume-yes-switch + $VAR = $R + - focus-metavariable: $R + - patterns: + - pattern: | + $Y, err := store.Get(...) + ... + var $VAR $INT = $Y.Values["..."].($INT) + ... + $VAR = $R + - focus-metavariable: $R + pattern-sources: + - patterns: + - pattern-inside: | + func $HANDLER(..., $R *http.Request, ...) { + ... + } + - focus-metavariable: $R + - pattern-either: + - pattern: $R.query + severity: WARNING + - fix-regex: + regex: (HttpOnly\s*:\s+)false + replacement: \1true + id: go.gorilla.security.audit.session-cookie-missing-httponly.session-cookie-missing-httponly languages: - - dockerfile - message: This 'yum install' is missing the '-y' switch. This might stall builds because it requires human intervention. Add the '-y' switch. + - go + message: A session cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie which mitigates XSS attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' in the Options struct. metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration references: - - https://github.com/hadolint/hadolint/wiki/DL3030 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3030 + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 + subcategory: + - audit technology: - - dockerfile + - gorilla patterns: + - pattern-not-inside: | + &sessions.Options{ + ..., + HttpOnly: true, + ..., + } - pattern: | - RUN ... yum install ... - - pattern-not: | - RUN ... yum install ... -y ... - - pattern-not: | - RUN ... yum ... --assumeyes ... + &sessions.Options{ + ..., + } severity: WARNING - - id: dockerfile.best-practice.missing-zypper-clean.missing-zypper-clean + - fix-regex: + regex: (Secure\s*:\s+)false + replacement: \1true + id: go.gorilla.security.audit.session-cookie-missing-secure.session-cookie-missing-secure languages: - - dockerfile - message: This zypper command does not end with '&& zypper clean'. Running 'zypper clean' will remove cached data and reduce package size. (This must be performed in the same RUN step.) + - go + message: A session cookie was detected without setting the 'Secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'Secure' flag by setting 'Secure' to 'true' in the Options struct. metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration references: - - https://github.com/hadolint/hadolint/wiki/DL3036 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3036 + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 + subcategory: + - audit technology: - - dockerfile + - gorilla patterns: - - pattern: RUN ... zypper $COMMAND ... - - pattern-not-inside: RUN ... zypper clean - - pattern-not-inside: RUN ... zypper clean + - pattern-not-inside: | + &sessions.Options{ + ..., + Secure: true, + ..., + } + - pattern: | + &sessions.Options{ + ..., + } severity: WARNING - - id: dockerfile.best-practice.nonsensical-command.nonsensical-command + - fix-regex: + regex: (SameSite\s*:\s+)http.SameSiteNoneMode + replacement: \1http.SameSiteDefaultMode + id: go.gorilla.security.audit.session-cookie-samesitenone.session-cookie-samesitenone languages: - - dockerfile - message: Some commands such as `$CMD` do not make sense in a container. Do not use these. + - go + message: Found SameSiteNoneMode setting in Gorilla session options. Consider setting SameSite to Lax, Strict or Default for enhanced security. metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration references: - - https://github.com/hadolint/hadolint/wiki/DL3001 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3001 + - https://pkg.go.dev/github.com/gorilla/sessions#Options + subcategory: + - audit technology: - - dockerfile + - gorilla patterns: - - pattern: RUN $CMD ... - - metavariable-regex: - metavariable: $CMD - regex: (shutdown|service|ps|free|top|kill|mount|ifconfig|nano|vim) + - pattern-inside: | + &sessions.Options{ + ..., + SameSite: http.SameSiteNoneMode, + ..., + } + - pattern: | + &sessions.Options{ + ..., + } severity: WARNING - - id: dockerfile.best-practice.prefer-apt-get.prefer-apt-get + - id: go.gorilla.security.audit.websocket-missing-origin-check.websocket-missing-origin-check languages: - - dockerfile - message: '''apt-get'' is preferred as an unattended tool for stability. ''apt'' is discouraged.' + - go + message: 'The Origin header in the HTTP WebSocket handshake is used to guarantee that the connection accepted by the WebSocket is from a trusted origin domain. Failure to enforce can lead to Cross Site Request Forgery (CSRF). As per "gorilla/websocket" documentation: "A CheckOrigin function should carefully validate the request origin to prevent cross-site request forgery."' metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control references: - - https://github.com/hadolint/hadolint/wiki/DL3027 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3027 + - https://pkg.go.dev/github.com/gorilla/websocket#Upgrader + subcategory: + - audit technology: - - dockerfile + - gorilla patterns: - - pattern: RUN apt ... - - pattern-not: RUN apt-get ... - severity: INFO - - id: dockerfile.best-practice.prefer-copy-over-add.prefer-copy-over-add + - pattern-inside: | + import ("github.com/gorilla/websocket") + ... + - patterns: + - pattern-not-inside: | + $UPGRADER = websocket.Upgrader{..., CheckOrigin: $FN ,...} + ... + - pattern-not-inside: | + $UPGRADER.CheckOrigin = $FN2 + ... + - pattern: | + $UPGRADER.Upgrade(...) + severity: WARNING + - id: go.gorm.security.audit.gorm-dangerous-methods-usage.gorm-dangerous-method-usage languages: - - dockerfile - message: The ADD command will accept and include files from a URL and automatically extract archives. This potentially exposes the container to a man-in-the-middle attack or other attacks if a malicious actor can tamper with the source archive. Since ADD can have this and other unexpected side effects, the use of the more explicit COPY command is preferred. + - go + message: Detected usage of dangerous method $METHOD which does not escape inputs (see link in references). If the argument is user-controlled, this can lead to SQL injection. When using $METHOD function, do not trust user-submitted data and only allow approved list of input (possibly, use an allowlist approach). metadata: - category: best-practice + category: security + confidence: HIGH + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html + - https://gorm.io/docs/security.html#SQL-injection-Methods + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + subcategory: + - vuln technology: - - dockerfile - patterns: - - pattern: | - ADD $FROM $TO - - metavariable-regex: - metavariable: $FROM - regex: (^[A-Za-z]+:\/\/|.*[.](gz|bz2|zip|tar)$) - - focus-metavariable: $FROM - severity: INFO - - id: dockerfile.best-practice.prefer-json-notation.prefer-json-notation - languages: - - dockerfile - message: Prefer JSON notation when using CMD or ENTRYPOINT. This allows signals to be passed from the OS. - metadata: - category: best-practice - references: - - https://github.com/hadolint/hadolint/wiki/DL3025 - - https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#cmd - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3025 - technology: - - dockerfile - pattern-either: + - gorm + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern-either: + - pattern: strconv.Atoi(...) + - pattern: | + ($X: bool) + pattern-sinks: - patterns: - - pattern: CMD $WORD ... - - pattern-not-inside: CMD [...] + - pattern-inside: | + import ("gorm.io/gorm") + ... + - patterns: + - pattern-inside: | + func $VAL(..., $GORM *gorm.DB,... ) { + ... + } + - pattern-either: + - pattern: | + $GORM. ... .$METHOD($VALUE) + - pattern: | + $DB := $GORM. ... .$ANYTHING(...) + ... + $DB. ... .$METHOD($VALUE) + - focus-metavariable: $VALUE + - metavariable-regex: + metavariable: $METHOD + regex: ^(Order|Exec|Raw|Group|Having|Distinct|Select|Pluck)$ + pattern-sources: - patterns: - - pattern: ENTRYPOINT $WORD ... - - pattern-not-inside: ENTRYPOINT [...] - severity: INFO - - id: dockerfile.best-practice.remove-package-cache.remove-package-cache - languages: - - dockerfile - message: The package cache was not deleted after running 'apt-get update', which increases the size of the image. Remove the package cache by appending '&& apt-get clean' at the end of apt-get command chain. - metadata: - category: best-practice - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://github.com/hadolint/hadolint/wiki/DL3009 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3009 - technology: - - dockerfile - patterns: - - pattern-not-inside: RUN ... && apt-get clean ... - - pattern: RUN ... apt-get update ... - - pattern: apt-get update + - pattern-either: + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ severity: WARNING - - id: dockerfile.best-practice.remove-package-lists.remove-package-lists + - fix-regex: + regex: (.*)WithInsecure\(.*?\) + replacement: \1WithTransportCredentials(credentials.NewTLS()) + id: go.grpc.security.grpc-client-insecure-connection.grpc-client-insecure-connection languages: - - dockerfile - message: The package lists were not deleted after running 'apt-get update', which increases the size of the image. Remove the package lists by appending '&& rm -rf /var/lib/apt/lists/*' at the end of apt-get command chain. + - go + message: 'Found an insecure gRPC connection using ''grpc.WithInsecure()''. This creates a connection without encryption to a gRPC server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. Instead, establish a secure connection with an SSL certificate using the ''grpc.WithTransportCredentials()'' function. You can create a create credentials using a ''tls.Config{}'' struct with ''credentials.NewTLS()''. The final fix looks like this: ''grpc.WithTransportCredentials(credentials.NewTLS())''.' metadata: - category: best-practice + category: security + confidence: HIGH + cwe: + - 'CWE-300: Channel Accessible by Non-Endpoint' + impact: LOW + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/hadolint/hadolint/wiki/DL3009 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3009 + - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption + subcategory: + - audit technology: - - dockerfile - patterns: - - pattern-not-inside: RUN ... rm -rf /var/lib/apt/lists/* - - pattern: RUN apt-get update ... - - pattern: apt-get update - severity: WARNING - - id: dockerfile.best-practice.set-pipefail.set-pipefail + - grpc + pattern: $GRPC.Dial($ADDR, ..., $GRPC.WithInsecure(...), ...) + severity: ERROR + - id: go.grpc.security.grpc-server-insecure-connection.grpc-server-insecure-connection languages: - - dockerfile - message: Only the exit code from the final command in this RUN instruction will be evaluated unless 'pipefail' is set. If you want to fail the command at any stage in the pipe, set 'pipefail' by including 'SHELL ["/bin/bash", "-o", "pipefail", "-c"] before the command. If you're using alpine and don't have bash installed, communicate this explicitly with `SHELL ["/bin/ash"]`. + - go + message: Found an insecure gRPC server without 'grpc.Creds()' or options with credentials. This allows for a connection without encryption to this server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. Include credentials derived from an SSL certificate in order to create a secure gRPC connection. You can create credentials using 'credentials.NewServerTLSFromFile("cert.pem", "cert.key")'. metadata: - category: best-practice + category: security + confidence: HIGH + cwe: + - 'CWE-300: Channel Accessible by Non-Endpoint' + impact: LOW + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/hadolint/hadolint/wiki/DL4006 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4006 + - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption + subcategory: + - audit technology: - - dockerfile - patterns: - - pattern-either: - - pattern: RUN ... | ... - - pattern: RUN ... || ... - - pattern-not-inside: | - SHELL [..., "pipefail", ...] - ... - RUN ... | ... - - pattern-not-inside: | - SHELL ["/bin/ash", ...] - ... - RUN ... | ... - severity: WARNING - - id: dockerfile.best-practice.use-either-wget-or-curl.use-either-wget-or-curl + - grpc + mode: taint + pattern-sinks: + - pattern: grpc.NewServer($OPT, ...) + requires: OPTIONS and not CREDS + - pattern: grpc.NewServer() + requires: EMPTY_CONSTRUCTOR + pattern-sources: + - label: OPTIONS + pattern: grpc.ServerOption{ ... } + - label: CREDS + pattern: grpc.Creds(...) + - label: EMPTY_CONSTRUCTOR + pattern: grpc.NewServer() + severity: ERROR + - id: go.jwt-go.security.audit.jwt-parse-unverified.jwt-go-parse-unverified languages: - - dockerfile - message: '''wget'' and ''curl'' are similar tools. Choose one and do not install the other to decrease image size.' + - go + message: Detected the decoding of a JWT token without a verify step. Don't use `ParseUnverified` unless you know what you're doing This method parses the token but doesn't validate the signature. It's only ever useful in cases where you know the signature is valid (because it has been checked previously in the stack) and you want to extract values from it. metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-345: Insufficient Verification of Data Authenticity' + impact: LOW + likelihood: LOW + owasp: + - A08:2021 - Software and Data Integrity Failures references: - - https://github.com/hadolint/hadolint/wiki/DL4001 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4001 + - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit technology: - - dockerfile - pattern-either: - - pattern: | - RUN wget ... + - jwt + patterns: + - pattern-inside: | + import "github.com/dgrijalva/jwt-go" ... - RUN curl ... - pattern: | - RUN curl ... - ... - RUN wget ... - severity: INFO - - fix: SHELL ["$SHELL", "-c"] - id: dockerfile.best-practice.use-shell-instruction.use-shell-instruction - languages: - - dockerfile - message: Use the SHELL instruction to set the default shell instead of overwriting '/bin/sh'. - metadata: - category: best-practice - references: - - https://github.com/hadolint/hadolint/wiki/DL4005 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4005 - technology: - - dockerfile - pattern: | - RUN ln ... $SHELL /bin/sh + $JWT.ParseUnverified(...) severity: WARNING - - id: dockerfile.best-practice.use-workdir.use-workdir + - id: go.jwt-go.security.jwt-none-alg.jwt-go-none-algorithm languages: - - dockerfile - message: As recommended by Docker's documentation, it is best to use 'WORKDIR' instead of 'RUN cd ...' for improved clarity and reliability. Also, 'RUN cd ...' may not work as expected in a container. + - go + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. metadata: - category: best-practice + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: LOW + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://github.com/hadolint/hadolint/wiki/DL3003 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3003 + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit technology: - - dockerfile - options: - implicit_deep_exprstmt: false + - jwt patterns: - pattern-either: - pattern-inside: | - RUN $ CMD ... + import "github.com/golang-jwt/jwt" + ... - pattern-inside: | - RUN $CMD ... && ... - - metavariable-pattern: - metavariable: $CMD - pattern: cd - - focus-metavariable: $CMD - severity: WARNING - - id: dockerfile.correctness.invalid-port.invalid-port - languages: - - dockerfile - message: Detected an invalid port number. Valid ports are 0 through 65535. - metadata: - category: correctness - references: - - https://github.com/hadolint/hadolint/wiki/DL3011 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3011 - technology: - - dockerfile - pattern-either: - - patterns: - - pattern: EXPOSE $PORT - - metavariable-comparison: - comparison: int($PORT) > 65535 - metavariable: $PORT + import "github.com/dgrijalva/jwt-go" + ... + - pattern-either: + - pattern: | + jwt.SigningMethodNone + - pattern: jwt.UnsafeAllowNoneSignatureType severity: ERROR - - id: dockerfile.correctness.missing-assume-yes-switch.missing-assume-yes-switch + - id: go.jwt-go.security.jwt.hardcoded-jwt-key languages: - - dockerfile - message: This 'apt-get install' is missing the '-y' switch. This might stall builds because it requires human intervention. Add the '-y' switch. + - go + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: - category: correctness + category: security + confidence: MEDIUM + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + likelihood: HIGH + owasp: + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/hadolint/hadolint/wiki/DL3014 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3014 + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + subcategory: + - vuln technology: - - dockerfile - patterns: - - pattern: "RUN ... apt-get install ... $MULTIFLAG ... \n" - - pattern-not: | - RUN ... apt-get install ... --assume-yes ... - - pattern-not: | - RUN ... apt-get install ... --yes ... - - pattern-not: | - RUN ... apt-get install ... -y ... - - metavariable-regex: - metavariable: $MULTIFLAG - regex: (^([^-])|(-[^y]+)$) + - jwt + - secrets + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $TOKEN.SignedString($F) + - focus-metavariable: $F + pattern-sources: + - patterns: + - pattern-inside: | + []byte("$F") severity: WARNING - - id: dockerfile.correctness.multiple-entrypoint-instructions.multiple-entrypoint-instructions - languages: - - dockerfile - message: Multiple ENTRYPOINT instructions were found. Only the last one will take effect. - metadata: - category: correctness - references: - - https://github.com/hadolint/hadolint/wiki/DL4004 - - https://kapeli.com/cheat_sheets/Dockerfile.docset/Contents/Resources/Documents/index#//dash_ref_Instructions/Entry/ENTRYPOINT/0 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4004 - technology: - - dockerfile - patterns: - - pattern: | - ENTRYPOINT ... - ... - $ENTRYPOINT_INSTR - - metavariable-pattern: - metavariable: $ENTRYPOINT_INSTR - pattern: | - ENTRYPOINT ... - - focus-metavariable: $ENTRYPOINT_INSTR - severity: ERROR - - id: dockerfile.security.last-user-is-root.last-user-is-root + - id: go.lang.security.audit.crypto.bad_imports.insecure-module-used languages: - - dockerfile - message: The last user in the container is 'root'. This is a security hazard because if an attacker gains control of the container they will have root access. Switch back to another user after running commands as 'root'. + - go + message: The package `net/http/cgi` is on the import blocklist. The package is vulnerable to httpoxy attacks (CVE-2015-5386). It is recommended to use `net/http` or a web framework to build a web application instead. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-269: Improper Privilege Management' + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM likelihood: MEDIUM owasp: - - A04:2021 - Insecure Design + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://github.com/hadolint/hadolint/wiki/DL3002 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3002 + - https://godoc.org/golang.org/x/crypto/sha3 + source-rule-url: https://github.com/securego/gosec subcategory: - audit technology: - - dockerfile - patterns: - - pattern: USER root - - pattern-not-inside: - patterns: - - pattern: | - USER root - ... - USER $X - - metavariable-pattern: - metavariable: $X - patterns: - - pattern-not: root - severity: ERROR - - fix: | - USER non-root - ENTRYPOINT $...VARS - id: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint + - go + pattern-either: + - patterns: + - pattern-inside: | + import "net/http/cgi" + ... + - pattern: | + cgi.$FUNC(...) + severity: WARNING + - id: go.lang.security.audit.crypto.insecure_ssh.avoid-ssh-insecure-ignore-host-key languages: - - dockerfile - message: By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. + - go + message: Disabled host key verification detected. This allows man-in-the-middle attacks. Use the 'golang.org/x/crypto/ssh/knownhosts' package to do host key verification. See https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ to learn more about the problem and how to fix it. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-269: Improper Privilege Management' - impact: MEDIUM + - 'CWE-322: Key Exchange without Entity Authentication' + impact: LOW likelihood: LOW owasp: - - A04:2021 - Insecure Design + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A04_2021-Insecure_Design + - https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ + - https://gist.github.com/Skarlso/34321a230cf0245018288686c9e70b2d + source-rule-url: https://github.com/securego/gosec subcategory: - audit technology: - - dockerfile - patterns: - - pattern: | - ENTRYPOINT $...VARS - - pattern-not-inside: | - USER $USER - ... - severity: ERROR + - go + pattern: ssh.InsecureIgnoreHostKey() + severity: WARNING - fix: | - USER non-root - CMD $...VARS - id: dockerfile.security.missing-user.missing-user + crypto/rand + id: go.lang.security.audit.crypto.math_random.math-random-used languages: - - dockerfile - message: By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. + - go + message: Do not use `math/rand`. Use `crypto/rand` instead. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-269: Improper Privilege Management' + - 'CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A04:2021 - Insecure Design + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A04_2021-Insecure_Design + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#secure-random-number-generation subcategory: - - audit + - vuln technology: - - dockerfile + - go patterns: - - pattern: | - CMD $...VARS - - pattern-not-inside: | - USER $USER - ... - severity: ERROR - - id: dockerfile.security.no-sudo-in-dockerfile.no-sudo-in-dockerfile + - pattern-either: + - pattern: | + import $RAND "$MATH" + - pattern: | + import "$MATH" + - metavariable-regex: + metavariable: $MATH + regex: ^(math/rand(\/v[0-9]+)*)$ + - pattern-either: + - pattern-inside: | + ... + rand.$FUNC(...) + - pattern-inside: | + ... + $RAND.$FUNC(...) + - focus-metavariable: + - $MATH + severity: WARNING + - fix: | + tls.Config{ $...CONF, MinVersion: tls.VersionTLS13 } + id: go.lang.security.audit.crypto.missing-ssl-minversion.missing-ssl-minversion languages: - - dockerfile - message: Avoid using sudo in Dockerfiles. Running processes as a non-root user can help reduce the potential impact of configuration errors and security vulnerabilities. + - go + message: '`MinVersion` is missing from this TLS configuration. By default, TLS 1.2 is currently used as the minimum when acting as a client, and TLS 1.0 when acting as a server. General purpose web applications should default to TLS 1.3 with all other protocols disabled. Only where it is known that a web server must support legacy clients with unsupported an insecure browsers (such as Internet Explorer 10), it may be necessary to enable TLS 1.0 to provide support. Add `MinVersion: tls.VersionTLS13'' to the TLS configuration to bump the minimum version to TLS 1.3.' metadata: category: security confidence: HIGH cwe: - - 'CWE-250: Execution with Unnecessary Privileges' + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: LOW - likelihood: LOW + likelihood: MEDIUM owasp: - - A05:2021 - Security Misconfiguration + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cwe.mitre.org/data/definitions/250.html - - https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user + - https://golang.org/doc/go1.14#crypto/tls + - https://golang.org/pkg/crypto/tls/#:~:text=MinVersion + - https://www.us-cert.gov/ncas/alerts/TA14-290A + source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go subcategory: - - audit + - guardrail technology: - - dockerfile + - go patterns: - pattern: | - RUN sudo ... + tls.Config{ $...CONF } + - pattern-not: | + tls.Config{..., MinVersion: ..., ...} severity: WARNING - - id: dockerfile.security.secret-in-build-arg.secret-in-build-arg + - fix-regex: + regex: VersionSSL30 + replacement: VersionTLS13 + id: go.lang.security.audit.crypto.ssl.ssl-v3-is-insecure languages: - - dockerfile - message: Docker build time arguments are not suited for secrets, because the argument values are saved with the image. Running `docker image history` on the image will show information on how the image was built, including arguments. If these contain plain text secrets, anyone with access to the docker image can access those secrets and exploit them. + - go + message: SSLv3 is insecure because it has known vulnerabilities. Starting with go1.14, SSLv3 will be removed. Instead, use 'tls.VersionTLS13'. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-538: Insertion of Sensitive Information into Externally-Accessible File or Directory' - impact: HIGH - likelihood: LOW + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: LOW + likelihood: MEDIUM owasp: - - A01:2021 - Broken Access Control + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cwe.mitre.org/data/definitions/538.html - - https://docs.docker.com/engine/reference/builder/#arg + - https://golang.org/doc/go1.14#crypto/tls + - https://www.us-cert.gov/ncas/alerts/TA14-290A + source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go subcategory: - - audit - technology: - - dockerfile - patterns: - - pattern-either: - - pattern: ARG $ARG - - pattern: ARG $ARG=... - - metavariable-regex: - metavariable: $ARG - regex: (?i).*(password|secret|token|key|cert|api|auth) - severity: WARNING - - fix: Bitwise.bnot($VAL) - id: elixir.lang.best-practice.deprecated-bnot-operator.deprecated_bnot_operator - languages: - - elixir - message: The bitwise operator (`^^^`) is already deprecated. Please use `Bitwise.bnot($VAL)` instead. - metadata: - category: best-practice - references: - - https://github.com/elixir-lang/elixir/commit/f1b9d3e818e5bebd44540f87be85979f24b9abfc - technology: - - elixir - pattern: ~~~$VAL - severity: WARNING - - fix: Bitwise.bxor($LEFT, $RIGHT) - id: elixir.lang.best-practice.deprecated-bxor-operator.deprecated_bxor_operator - languages: - - elixir - message: The bitwise operator (`^^^`) is already deprecated. Please use `Bitwise.bxor($LEFT, $RIGHT)` instead. - metadata: - category: best-practice - references: - - https://github.com/elixir-lang/elixir/commit/c9a171da5b25e0eb5d1da3b04c622f8b79a8aff4 - technology: - - elixir - pattern: $LEFT ^^^ $RIGHT - severity: WARNING - - fix: | - {$VAR, _, _} = Calendar.ISO.day_of_week($YEAR, $MONTH, $DAY, :default) - id: elixir.lang.best-practice.deprecated-calendar-iso-day-of-week-3.deprecated_calendar_iso_day_of_week_3 - languages: - - elixir - message: '`Calendar.ISO.day_of_week/3` is already deprecated. Please use `Calendar.ISO.day_of_week/4` instead.' - metadata: - category: best-practice - references: - - https://github.com/elixir-lang/elixir/releases/tag/v1.15.0 - technology: - - elixir - pattern: $VAR = Calendar.ISO.day_of_week($YEAR, $MONTH, $DAY) - severity: WARNING - - fix: import Bitwise - id: elixir.lang.best-practice.deprecated-use-bitwise.deprecated_use_bitwise - languages: - - elixir - message: The syntax `use Bitwise` is already deprecated. Please use `import Bitwise` instead. - metadata: - category: best-practice - references: - - https://github.com/elixir-lang/elixir/commit/f1b9d3e818e5bebd44540f87be85979f24b9abfc + - vuln technology: - - elixir - pattern: use Bitwise + - go + pattern: 'tls.Config{..., MinVersion: $TLS.VersionSSL30, ...}' severity: WARNING - - fix: | - $E - |> Enum.into($INTO, $FUN end) - id: elixir.lang.best-practice.enum-map-into.enum_map_into + - id: go.lang.security.audit.crypto.tls.tls-with-insecure-cipher languages: - - elixir - message: Using `Enum.into/3` is more efficient than using `Enum.map/2 |> Enum.into/2`. + - go + message: Detected an insecure CipherSuite via the 'tls' module. This suite is considered weak. Use the function 'tls.CipherSuites()' to get a list of good cipher suites. See https://golang.org/pkg/crypto/tls/#InsecureCipherSuites for why and what other cipher suites to use. metadata: - category: best-practice + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: LOW + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://github.com/rrrene/credo/blob/master/lib/credo/check/refactor/map_into.ex + - https://golang.org/pkg/crypto/tls/#InsecureCipherSuites + source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls.go + subcategory: + - vuln technology: - - elixir + - go pattern-either: - pattern: | - Enum.into(Enum.map($E, $FUN), $INTO) + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_RC4_128_SHA, ...}} - pattern: | - Enum.map($E, $FUN) - |> Enum.into($INTO) + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, ...}} - pattern: | - $E - |> Enum.map($FUN) - |> Enum.into($INTO) - severity: WARNING - - fix: | - $E - |> Enum.map_join($JOINER, $FUN end) - id: elixir.lang.best-practice.enum-map-join.enum_map_join - languages: - - elixir - message: Using `Enum.map_join/3` is more efficient than using `Enum.map/2 |> Enum.join/2`. - metadata: - category: best-practice - references: - - https://github.com/rrrene/credo/blob/master/lib/credo/check/refactor/map_join.ex - technology: - - elixir - pattern-either: + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_AES_128_CBC_SHA256, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ...}} + - pattern: | + tls.CipherSuite{..., TLS_RSA_WITH_RC4_128_SHA, ...} + - pattern: | + tls.CipherSuite{..., TLS_RSA_WITH_3DES_EDE_CBC_SHA, ...} + - pattern: | + tls.CipherSuite{..., TLS_RSA_WITH_AES_128_CBC_SHA256, ...} + - pattern: | + tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, ...} + - pattern: | + tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_RC4_128_SHA, ...} - pattern: | - Enum.join(Enum.map($E, $FUN), $JOINER) + tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, ...} - pattern: | - Enum.map($E, $FUN) - |> Enum.join($JOINER) + tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ...} - pattern: | - $E - |> Enum.map($FUN) - |> Enum.join($JOINER) + tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ...} severity: WARNING - - fix: $MODULE.to_existing_atom($STRING) - id: elixir.lang.correctness.atom-exhaustion.atom_exhaustion + - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-md5 languages: - - elixir - message: Atom values are appended to a global table but never removed. If input is user-controlled, dynamic instantiations such as `String.to_atom` or `List.to_atom` can lead to possible memory leaks. Instead, use `String.to_existing_atom` or `List.to_existing_atom`. + - go + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: - category: correctness + category: security + confidence: MEDIUM + cwe: + - 'CWE-328: Use of Weak Hash' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://erlef.github.io/security-wg/secure_coding_and_deployment_hardening/atom_exhaustion.html + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://github.com/securego/gosec#available-rules + subcategory: + - vuln technology: - - elixir + - go patterns: - - pattern: $MODULE.to_atom($STRING) - - metavariable-regex: - metavariable: $MODULE - regex: ^(String|List)$ - severity: ERROR - - id: generic.dockerfile.best-practice.missing-yum-clean-all.missing-yum-clean-all - languages: - - generic - message: This yum command does not end with '&& yum clean all'. Running 'yum clean all' will remove cached data and reduce package size. (This must be performed in the same RUN step.) - metadata: - category: best-practice - references: - - https://github.com/hadolint/hadolint/wiki/DL3032 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3032 - technology: - - dockerfile - paths: - include: - - '*dockerfile*' - - '*Dockerfile*' - patterns: - - pattern: yum $COMMAND - - pattern-not-inside: RUN ... && yum clean all - - pattern-not-inside: RUN ... && \ yum clean all - severity: WARNING - - id: generic.dockerfile.best-practice.use-absolute-workdir.use-absolute-workdir - languages: - - generic - message: Detected a relative WORKDIR. Use absolute paths. This prevents issues based on assumptions about the WORKDIR of previous containers. - metadata: - category: best-practice - references: - - https://github.com/hadolint/hadolint/wiki/DL3000 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3000 - technology: - - dockerfile - paths: - include: - - '*dockerfile*' - - '*Dockerfile*' - pattern-either: - - patterns: - - pattern: WORKDIR $VALUE - - metavariable-pattern: - metavariable: $VALUE - patterns: - - pattern-not-regex: (\/.*) - - patterns: - - pattern: ENV $VAR=$VALUE ... $CMD ${$VAR} - - metavariable-pattern: - metavariable: $VALUE - patterns: - - pattern-not-regex: (\/.*) - - metavariable-pattern: - metavariable: $CMD - pattern: WORKDIR - - focus-metavariable: $CMD - severity: WARNING - - id: generic.dockerfile.correctness.alias-must-be-unique.alias-must-be-unique - languages: - - generic - message: Image aliases must have a unique name, and '$REF' is used twice. Use another name for '$REF'. - metadata: - category: correctness - references: - - https://github.com/hadolint/hadolint/wiki/DL3024 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3024 - technology: - - dockerfile - paths: - include: - - '*dockerfile*' - - '*Dockerfile*' - patterns: - - pattern-either: - - pattern: | - FROM ... as $REF - ... - ... - FROM ... as $REF - - pattern: | - FROM ... AS $REF - ... - ... - FROM ... AS $REF - - pattern-not-inside: | - FROM ... as $REF - ... - ... - FROM ... as $REF- - - pattern-not-inside: | - FROM ... AS $REF - ... - ... - FROM ... AS $REF- - severity: ERROR - - id: generic.dockerfile.correctness.copy-from-own-alias.copy-from-own-alias - languages: - - generic - message: COPY instructions cannot copy from its own alias. The '$REF' alias is used before switching to a new image. If you meant to switch to a new image, include a new 'FROM' statement. Otherwise, remove the '--from=$REF' from the COPY statement. - metadata: - category: correctness - references: - - https://github.com/hadolint/hadolint/wiki/DL3023 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3023 - technology: - - dockerfile - paths: - include: - - '*dockerfile*' - - '*Dockerfile*' - pattern-either: - - pattern: | - FROM $IMAGE:$TAG as $REF - ... - COPY --from=$REF - ... - FROM - - pattern: | - FROM $IMAGE:$TAG AS $REF - ... - COPY --from=$REF + - pattern-inside: | + import "crypto/md5" ... - FROM - severity: ERROR - - id: generic.dockerfile.correctness.multiple-cmd-instructions.multiple-cmd-instructions - languages: - - dockerfile - message: Multiple CMD instructions were found. Only the last one will take effect. - metadata: - category: correctness - references: - - https://github.com/hadolint/hadolint/wiki/DL4003 - - https://kapeli.com/cheat_sheets/Dockerfile.docset/Contents/Resources/Documents/index#//dash_ref_Instructions/Entry/CMD/0 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL4003 - technology: - - dockerfile - patterns: - pattern-either: - pattern: | - CMD ... - ... - CMD ... - - pattern: | - CMD [...] - ... - CMD [...] - - pattern: | - CMD [...] - ... - CMD ... + md5.New() - pattern: | - CMD ... - ... - CMD [...] - - pattern-not-inside: | - CMD ... - ... - FROM $IMAGE - ... - CMD ... - - pattern-not: | - HEALTHCHECK $CMD - ... - CMD ... - - pattern-not: | - HEALTHCHECK $CMD - ... - CMD [...] - - pattern-not: | - CMD ... - ... - HEALTHCHECK $CMD - - pattern-not: | - CMD [...] - ... - HEALTHCHECK $CMD - severity: ERROR - - id: generic.dockerfile.missing-zypper-no-confirm-switch.missing-zypper-no-confirm-switch - languages: - - dockerfile - message: This 'zypper install' is missing the '-y' switch. This might stall builds because it requires human intervention. Add the '-y' switch. - metadata: - category: best-practice - references: - - https://github.com/hadolint/hadolint/wiki/DL3034 - source-rule-url: https://github.com/hadolint/hadolint/wiki/DL3034 - technology: - - dockerfile - paths: - include: - - '*dockerfile*' - - '*Dockerfile*' - patterns: - - pattern: | - RUN ... zypper install ... - - pattern-not: | - RUN ... zypper install ... -y ... - - pattern-not: | - RUN ... zypper install ... --no-confirm ... + md5.Sum(...) severity: WARNING - - id: generic.secrets.gitleaks.adafruit-api-key.adafruit-api-key + - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-sha1 languages: - - regex - message: A gitleaks adafruit-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-328: Use of Weak Hash' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://github.com/securego/gosec#available-rules subcategory: - vuln technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)(?:adafruit)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.adobe-client-id.adobe-client-id + - pattern-inside: | + import "crypto/sha1" + ... + - pattern-either: + - pattern: | + sha1.New() + - pattern: | + sha1.Sum(...) + severity: WARNING + - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-des languages: - - regex - message: A gitleaks adobe-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Detected DES cipher algorithm which is insecure. The algorithm is considered weak and has been deprecated. Use AES instead. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://github.com/securego/gosec#available-rules subcategory: - vuln technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)(?:adobe)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.adobe-client-secret.adobe-client-secret + - pattern-inside: | + import "crypto/des" + ... + - pattern-either: + - pattern: | + des.NewTripleDESCipher(...) + - pattern: | + des.NewCipher(...) + severity: WARNING + - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-rc4 languages: - - regex - message: A gitleaks adobe-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Detected RC4 cipher algorithm which is insecure. The algorithm has many known vulnerabilities. Use AES instead. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://github.com/securego/gosec#available-rules subcategory: - vuln technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)\b((p8e-)(?i)[a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.age-secret-key.age-secret-key + - pattern-inside: | + import "crypto/rc4" + ... + - pattern: rc4.NewCipher(...) + severity: WARNING + - fix: | + 2048 + id: go.lang.security.audit.crypto.use_of_weak_rsa_key.use-of-weak-rsa-key languages: - - regex - message: A gitleaks age-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: RSA keys should be at least 2048 bits metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-326: Inadequate Encryption Strength' impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms + source-rule-url: https://github.com/securego/gosec/blob/master/rules/rsa.go subcategory: - - vuln + - audit technology: - - gitleaks + - go patterns: - - pattern-regex: AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58} - severity: INFO - - id: generic.secrets.gitleaks.airtable-api-key.airtable-api-key + - pattern-either: + - pattern: | + rsa.GenerateKey(..., $BITS) + - pattern: | + rsa.GenerateMultiPrimeKey(..., $BITS) + - metavariable-comparison: + comparison: $BITS < 2048 + metavariable: $BITS + - focus-metavariable: + - $BITS + severity: WARNING + - id: go.lang.security.audit.dangerous-exec-cmd.dangerous-exec-cmd languages: - - regex - message: A gitleaks airtable-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Detected non-static command inside exec.Cmd. Audit the input to 'exec.Cmd'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' cwe2022-top25: true - impact: MEDIUM + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - - vuln + - audit technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)(?:airtable)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{17})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.algolia-api-key.algolia-api-key + - pattern-either: + - patterns: + - pattern: | + exec.Cmd {...,Path: $CMD,...} + - pattern-not: | + exec.Cmd {...,Path: "...",...} + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + - pattern-not-inside: | + $CMD = "..."; + ... + - patterns: + - pattern: | + exec.Cmd {...,Args: $ARGS,...} + - pattern-not: | + exec.Cmd {...,Args: []string{...},...} + - pattern-not-inside: | + $ARGS = []string{"...",...}; + ... + - pattern-not-inside: | + $CMD = "..."; + ... + $ARGS = []string{$CMD,...}; + ... + - pattern-not-inside: | + $CMD = exec.LookPath("..."); + ... + $ARGS = []string{$CMD,...}; + ... + - patterns: + - pattern: | + exec.Cmd {...,Args: []string{$CMD,...},...} + - pattern-not: | + exec.Cmd {...,Args: []string{"...",...},...} + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + - pattern-not-inside: | + $CMD = "..."; + ... + - patterns: + - pattern-either: + - pattern: | + exec.Cmd {...,Args: []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...} + - patterns: + - pattern: | + exec.Cmd {...,Args: []string{$CMD,"-c",$EXE,...},...} + - pattern-inside: | + $CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/"); + ... + - pattern-not: | + exec.Cmd {...,Args: []string{"...","...","...",...},...} + - pattern-not-inside: | + $EXE = "..."; + ... + - pattern-inside: | + import "os/exec" + ... + severity: ERROR + - id: go.lang.security.audit.md5-used-as-password.md5-used-as-password languages: - - regex - message: A gitleaks algolia-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as bcrypt. You can use the `golang.org/x/crypto/bcrypt` package. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html + - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords + - https://github.com/returntocorp/semgrep-rules/issues/1609 + - https://pkg.go.dev/golang.org/x/crypto/bcrypt subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:algolia)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.alibaba-access-key-id.alibaba-access-key-id + - md5 + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern: $FUNCTION(...) + - metavariable-regex: + metavariable: $FUNCTION + regex: (?i)(.*password.*) + pattern-sources: + - patterns: + - pattern-either: + - pattern: md5.New + - pattern: md5.Sum + severity: WARNING + - id: go.lang.security.audit.net.bind_all.avoid-bind-to-all-interfaces languages: - - regex - message: A gitleaks alibaba-access-key-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Detected a network listener listening on 0.0.0.0 or an empty string. This could unexpectedly expose the server publicly as it binds to all available interfaces. Instead, specify another IP address that is not 0.0.0.0 nor the empty string. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' cwe2021-top25: true - cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://github.com/securego/gosec subcategory: - - vuln + - audit technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b((LTAI)(?i)[a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.alibaba-secret-key.alibaba-secret-key + - go + pattern-either: + - pattern: tls.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) + - pattern: net.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) + - pattern: tls.Listen($NETWORK, "=~/^:.*$/", ...) + - pattern: net.Listen($NETWORK, "=~/^:.*$/", ...) + severity: WARNING + - fix-regex: + regex: (HttpOnly\s*:\s+)false + replacement: \1true + id: go.lang.security.audit.net.cookie-missing-httponly.cookie-missing-httponly languages: - - regex - message: A gitleaks alibaba-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: A session cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie which mitigates XSS attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' in the Cookie. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go + - https://golang.org/src/net/http/cookie.go subcategory: - vuln technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)(?:alibaba)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.asana-client-id.asana-client-id + - pattern-not-inside: | + http.Cookie{ + ..., + HttpOnly: true, + ..., + } + - pattern: | + http.Cookie{ + ..., + } + severity: WARNING + - fix-regex: + regex: (Secure\s*:\s+)false + replacement: \1true + id: go.lang.security.audit.net.cookie-missing-secure.cookie-missing-secure languages: - - regex - message: A gitleaks asana-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: A session cookie was detected without setting the 'Secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'Secure' flag by setting 'Secure' to 'true' in the Options struct. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go + - https://golang.org/src/net/http/cookie.go subcategory: - vuln technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.asana-client-secret.asana-client-secret + - pattern-not-inside: | + http.Cookie{ + ..., + Secure: true, + ..., + } + - pattern: | + http.Cookie{ + ..., + } + severity: WARNING + - id: go.lang.security.audit.net.dynamic-httptrace-clienttrace.dynamic-httptrace-clienttrace languages: - - regex - message: A gitleaks asana-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Detected a potentially dynamic ClientTrace. This occurred because semgrep could not find a static definition for '$TRACE'. Dynamic ClientTraces are dangerous because they deserialize function code to run when certain Request events occur, which could lead to code being run without your knowledge. Ensure that your ClientTrace is statically defined. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM + - 'CWE-913: Improper Control of Dynamically-Managed Code Resources' + impact: LOW likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://github.com/returntocorp/semgrep-rules/issues/518 subcategory: - vuln technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.atlassian-api-token.atlassian-api-token + - pattern-not-inside: | + package $PACKAGE + ... + &httptrace.ClientTrace { ... } + ... + - pattern: httptrace.WithClientTrace($ANY, $TRACE) + severity: WARNING + - id: go.lang.security.audit.net.formatted-template-string.formatted-template-string languages: - - regex - message: A gitleaks atlassian-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Found a formatted template string passed to 'template.HTML()'. 'template.HTML()' does not escape contents. Be absolutely sure there is no user-controlled data in this template. If user data can reach this template, you may have a XSS vulnerability. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://golang.org/pkg/html/template/#HTML subcategory: - - vuln + - audit technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)(?:atlassian|confluence|jira)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.authress-service-client-access-key.authress-service-client-access-key + - pattern-not: template.HTML("..." + "...") + - pattern-either: + - pattern: template.HTML($T + $X, ...) + - pattern: template.HTML(fmt.$P("...", ...), ...) + - pattern: | + $T = "..." + ... + $T = $FXN(..., $T, ...) + ... + template.HTML($T, ...) + - pattern: | + $T = fmt.$P("...", ...) + ... + template.HTML($T, ...) + - pattern: | + $T, $ERR = fmt.$P("...", ...) + ... + template.HTML($T, ...) + - pattern: | + $T = $X + $Y + ... + template.HTML($T, ...) + - pattern: |- + $T = "..." + ... + $OTHER, $ERR = fmt.$P(..., $T, ...) + ... + template.HTML($OTHER, ...) + severity: WARNING + - id: go.lang.security.audit.net.fs-directory-listing.fs-directory-listing languages: - - regex - message: A gitleaks authress-service-client-access-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: 'Detected usage of ''http.FileServer'' as handler: this allows directory listing and an attacker could navigate through directories looking for sensitive files. Be sure to disable directory listing or restrict access to specific directories/files.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-548: Exposure of Information Through Directory Listing' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A06:2017 - Security Misconfiguration + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://github.com/OWASP/Go-SCP + - https://cwe.mitre.org/data/definitions/548.html subcategory: - vuln technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)\b((?:sc|ext|scauth|authress)_[a-z0-9]{5,30}\.[a-z0-9]{4,6}\.acc[_-][a-z0-9-]{10,32}\.[a-z0-9+/_=-]{30,120})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.aws-access-token.aws-access-token - languages: - - regex - message: A gitleaks aws-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?:A3T[A-Z0-9]|AKIA|ASIA|ABIA|ACCA)[A-Z0-9]{16} - severity: INFO - - id: generic.secrets.gitleaks.beamer-api-token.beamer-api-token + - pattern-either: + - patterns: + - pattern-inside: | + $FS := http.FileServer(...) + ... + - pattern-either: + - pattern: | + http.ListenAndServe(..., $FS) + - pattern: | + http.ListenAndServeTLS(..., $FS) + - pattern: | + http.Handle(..., $FS) + - pattern: | + http.HandleFunc(..., $FS) + - patterns: + - pattern: | + http.$FN(..., http.FileServer(...)) + - metavariable-regex: + metavariable: $FN + regex: (ListenAndServe|ListenAndServeTLS|Handle|HandleFunc) + severity: WARNING + - fix: http.ListenAndServeTLS($ADDR, certFile, keyFile, $HANDLER) + id: go.lang.security.audit.net.use-tls.use-tls languages: - - regex - message: A gitleaks beamer-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Found an HTTP server without TLS. Use 'http.ListenAndServeTLS' instead. See https://golang.org/pkg/net/http/#ListenAndServeTLS for more information. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://golang.org/pkg/net/http/#ListenAndServeTLS subcategory: - - vuln + - audit technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:beamer)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(b_[a-z0-9=_\-]{44})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.bitbucket-client-id.bitbucket-client-id + - go + pattern: http.ListenAndServe($ADDR, $HANDLER) + severity: WARNING + - id: go.lang.security.audit.net.wip-xss-using-responsewriter-and-printf.wip-xss-using-responsewriter-and-printf languages: - - regex - message: A gitleaks bitbucket-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Found data going from url query parameters into formatted data written to ResponseWriter. This could be XSS and should not be done. If you must do this, ensure your data is sanitized or escaped. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.bitbucket-client-secret.bitbucket-client-secret + - pattern-inside: | + func $FUNC(..., $W http.ResponseWriter, ...) { + ... + var $TEMPLATE = "..." + ... + $W.Write([]byte(fmt.$PRINTF($TEMPLATE, ...)), ...) + ... + } + - pattern-either: + - pattern: | + $PARAMS = r.URL.Query() + ... + $DATA, $ERR := $PARAMS[...] + ... + $INTERM = $ANYTHING(..., $DATA, ...) + ... + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + - pattern: | + $PARAMS = r.URL.Query() + ... + $DATA, $ERR := $PARAMS[...] + ... + $INTERM = $DATA[...] + ... + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + - pattern: | + $DATA, $ERR := r.URL.Query()[...] + ... + $INTERM = $DATA[...] + ... + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + - pattern: | + $DATA, $ERR := r.URL.Query()[...] + ... + $INTERM = $ANYTHING(..., $DATA, ...) + ... + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + - pattern: | + $PARAMS = r.URL.Query() + ... + $DATA, $ERR := $PARAMS[...] + ... + $W.Write([]byte(fmt.$PRINTF(..., $DATA, ...))) + severity: WARNING + - fix: filepath.FromSlash(filepath.Clean("/"+strings.Trim($...INNER, "/"))) + id: go.lang.security.filepath-clean-misuse.filepath-clean-misuse languages: - - regex - message: A gitleaks bitbucket-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: '`Clean` is not intended to sanitize against path traversal attacks. This function is for finding the shortest path name equivalent to the given input. Using `Clean` to sanitize file reads may expose this application to path traversal attacks, where an attacker could access arbitrary files on the server. To fix this easily, write this: `filepath.FromSlash(path.Clean("/"+strings.Trim(req.URL.Path, "/")))` However, a better solution is using the `SecureJoin` function in the package `filepath-securejoin`. See https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://pkg.go.dev/path#Clean + - http://technosophos.com/2016/03/31/go-quickly-cleaning-filepaths.html + - https://labs.detectify.com/2021/12/15/zero-day-path-traversal-grafana/ + - https://dzx.cz/2021/04/02/go_path_traversal/ + - https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.bittrex-access-key.bittrex-access-key + - go + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern-either: + - pattern: | + "/" + ... + pattern-sinks: + - patterns: + - pattern-either: + - pattern: filepath.Clean($...INNER) + - pattern: path.Clean($...INNER) + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + severity: ERROR + - id: go.lang.security.injection.open-redirect.open-redirect languages: - - regex - message: A gitleaks bittrex-access-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: An HTTP redirect was found to be crafted from user-input `$REQUEST`. This can lead to open redirect vulnerabilities, potentially allowing attackers to redirect users to malicious web sites. It is recommend where possible to not allow user-input to craft the redirect URL. When user-input is necessary to craft the request, it is recommended to follow OWASP best practices to restrict the URL to domains in an allowlist. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + description: An HTTP redirect was found to be crafted from user-input leading to an open redirect vulnerability impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + interfile: true + likelihood: MEDIUM references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://knowledge-base.secureflag.com/vulnerabilities/unvalidated_redirects___forwards/open_redirect_go_lang.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.bittrex-secret-key.bittrex-secret-key + - go + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern: http.Redirect($W, $REQ, $URL, ...) + - focus-metavariable: $URL + requires: INPUT and not CLEAN + pattern-sources: + - label: INPUT + patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + - label: CLEAN + patterns: + - pattern-either: + - pattern: | + "$URLSTR" + $INPUT + - patterns: + - pattern-either: + - pattern: fmt.Fprintf($F, "$URLSTR", $INPUT, ...) + - pattern: fmt.Sprintf("$URLSTR", $INPUT, ...) + - pattern: fmt.Printf("$URLSTR", $INPUT, ...) + - metavariable-regex: + metavariable: $URLSTR + regex: .*//[a-zA-Z0-10]+\..* + requires: INPUT + severity: WARNING + - id: go.lang.security.injection.raw-html-format.raw-html-format languages: - - regex - message: A gitleaks bittrex-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. Use the `html/template` package which will safely render HTML instead, or inspect that the HTML is rendered safely. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.clojars-api-token.clojars-api-token + - go + mode: taint + pattern-sanitizers: + - pattern: html.EscapeString(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: fmt.Printf("$HTMLSTR", ...) + - pattern: fmt.Sprintf("$HTMLSTR", ...) + - pattern: fmt.Fprintf($W, "$HTMLSTR", ...) + - pattern: '"$HTMLSTR" + ...' + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + severity: WARNING + - id: go.lang.security.injection.tainted-sql-string.tainted-sql-string languages: - - regex - message: A gitleaks clojars-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`db.Query("SELECT * FROM t WHERE id = ?", id)`) or a safe library. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://golang.org/doc/database/sql-injection + - https://www.stackhawk.com/blog/golang-sql-injection-guide-examples-and-prevention/ subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(CLOJARS_)[a-z0-9]{60} - severity: INFO - - id: generic.secrets.gitleaks.cloudflare-api-key.cloudflare-api-key + - go + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern-either: + - pattern: strconv.Atoi(...) + - pattern: | + ($X: bool) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - patterns: + - pattern-inside: | + $VAR = "$SQLSTR"; + ... + - pattern: $VAR += ... + - patterns: + - pattern-inside: | + var $SB strings.Builder + ... + - pattern-inside: | + $SB.WriteString("$SQLSTR") + ... + $SB.String(...) + - pattern: | + $SB.WriteString(...) + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop).* + - patterns: + - pattern-either: + - pattern: fmt.Fprintf($F, "$SQLSTR", ...) + - pattern: fmt.Sprintf("$SQLSTR", ...) + - pattern: fmt.Printf("$SQLSTR", ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).* + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + severity: ERROR + - id: go.lang.security.injection.tainted-url-host.tainted-url-host languages: - - regex - message: A gitleaks cloudflare-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: A request was found to be crafted from user-input `$REQUEST`. This can lead to Server-Side Request Forgery (SSRF) vulnerabilities, potentially exposing sensitive data. It is recommend where possible to not allow user-input to craft the base request, but to be treated as part of the path or query parameter. When user-input is necessary to craft the request, it is recommended to follow OWASP best practices to prevent abuse, including using an allowlist. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-918: Server-Side Request Forgery (SSRF)' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A10:2021 - Server-Side Request Forgery (SSRF) references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://goteleport.com/blog/ssrf-attacks/ subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:cloudflare)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.cloudflare-global-api-key.cloudflare-global-api-key + - go + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $CLIENT := &http.Client{...} + ... + - pattern: $CLIENT.$METHOD($URL, ...) + - pattern: http.$METHOD($URL, ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Get|Head|Post|PostForm)$ + - patterns: + - pattern: | + http.NewRequest("$METHOD", $URL, ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(GET|HEAD|POST|POSTFORM)$ + - focus-metavariable: $URL + requires: INPUT and not CLEAN + pattern-sources: + - label: INPUT + patterns: + - pattern-either: + - pattern: | + ($REQUEST : *http.Request).$ANYTHING + - pattern: | + ($REQUEST : http.Request).$ANYTHING + - metavariable-regex: + metavariable: $ANYTHING + regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ + - label: CLEAN + patterns: + - pattern-either: + - pattern: | + "$URLSTR" + $INPUT + - patterns: + - pattern-either: + - pattern: fmt.Fprintf($F, "$URLSTR", $INPUT, ...) + - pattern: fmt.Sprintf("$URLSTR", $INPUT, ...) + - pattern: fmt.Printf("$URLSTR", $INPUT, ...) + - metavariable-regex: + metavariable: $URLSTR + regex: .*//[a-zA-Z0-10]+\..* + requires: INPUT + severity: WARNING + - id: go.template.security.ssti.go-ssti languages: - - regex - message: A gitleaks cloudflare-global-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - go + message: A server-side template injection occurs when an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side. When using "html/template" always check that user inputs are validated and sanitized before included within the template. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM + - 'CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine' + impact: HIGH likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.onsecurity.io/blog/go-ssti-method-research/ + - http://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html subcategory: - vuln technology: - - gitleaks + - go patterns: - - pattern-regex: (?i)(?:cloudflare)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{37})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.cloudflare-origin-ca-key.cloudflare-origin-ca-key + - pattern-inside: | + import ("html/template") + ... + - pattern: $TEMPLATE = fmt.Sprintf("...", $ARG, ...) + - patterns: + - pattern-either: + - pattern-inside: | + func $FN(..., $REQ *http.Request, ...){ + ... + } + - pattern-inside: | + func $FN(..., $REQ http.Request, ...){ + ... + } + - pattern-inside: | + func(..., $REQ *http.Request, ...){ + ... + } + - patterns: + - pattern-either: + - pattern-inside: | + $ARG := $REQ.URL.Query().Get(...) + ... + $T, $ERR := $TMPL.Parse($TEMPLATE) + - pattern-inside: | + $ARG := $REQ.Form.Get(...) + ... + $T, $ERR := $TMPL.Parse($TEMPLATE) + - pattern-inside: | + $ARG := $REQ.PostForm.Get(...) + ... + $T, $ERR := $TMPL.Parse($TEMPLATE) + severity: ERROR + - id: java.android.security.exported_activity.exported_activity languages: - - regex - message: A gitleaks cloudflare-origin-ca-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - generic + message: The application exports an activity. Any application on the device can launch the exported activity which may compromise the integrity of your application or its data. Ensure that any exported activities do not have privileged access to your application's control plane. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-926: Improper Export of Android Application Components' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A5:2021 Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cwe.mitre.org/data/definitions/926.html subcategory: - vuln technology: - - gitleaks + - Android + paths: + exclude: + - sources/ + - classes3.dex + - '*.so' + include: + - '*AndroidManifest.xml' patterns: - - pattern-regex: \b(v1\.0-[a-f0-9]{24}-[a-f0-9]{146})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.codecov-access-token.codecov-access-token + - pattern-not-inside: + - pattern-inside: " \n" + - pattern-either: + - pattern: | + + - pattern: | + ... /> + severity: WARNING + - id: java.aws-lambda.security.tainted-sql-string.tainted-sql-string languages: - - regex - message: A gitleaks codecov-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/www-community/attacks/SQL_Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:codecov)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.coinbase-access-token.coinbase-access-token - languages: - - regex - message: A gitleaks coinbase-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true + - aws-lambda + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR".concat(...) + - patterns: + - pattern-inside: | + StringBuilder $SB = new StringBuilder("$SQLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$SQLSTR"; + ... + - pattern: $VAR += ... + - pattern: String.format("$SQLSTR", ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b + - pattern-not-inside: | + System.out.$PRINTLN(...) + pattern-sources: + - patterns: + - focus-metavariable: $EVENT + - pattern-either: + - pattern: | + $HANDLERTYPE $HANDLER($TYPE $EVENT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { + ... + } + - pattern: | + $HANDLERTYPE $HANDLER(InputStream $EVENT, OutputStream $OUT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { + ... + } + severity: ERROR + - id: java.aws-lambda.security.tainted-sqli.tainted-sqli + languages: + - java + message: Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use parameterized SQL queries or properly sanitize user input instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:coinbase)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.confluent-access-token.confluent-access-token + - sql + - java + - aws-lambda + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: "(java.sql.CallableStatement $STMT) = ...; \n" + - pattern: | + (java.sql.Statement $STMT) = ...; + - pattern: | + (java.sql.PreparedStatement $STMT) = ...; + - pattern: | + $VAR = $CONN.prepareStatement(...) + - pattern: | + $PATH.queryForObject(...); + - pattern: | + (java.util.Map $STMT) = $PATH.queryForMap(...); + - pattern: | + (org.springframework.jdbc.support.rowset.SqlRowSet $STMT) = ...; + - patterns: + - pattern-inside: | + (String $SQL) = "$SQLSTR" + ...; + ... + - pattern: $PATH.$SQLCMD(..., $SQL, ...); + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(^SELECT.* | ^INSERT.* | ^UPDATE.*) + - metavariable-regex: + metavariable: $SQLCMD + regex: (execute|query|executeUpdate|batchUpdate) + pattern-sources: + - patterns: + - focus-metavariable: $EVENT + - pattern-either: + - pattern: | + $HANDLERTYPE $HANDLER($TYPE $EVENT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { + ... + } + - pattern: | + $HANDLERTYPE $HANDLER(InputStream $EVENT, OutputStream $OUT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { + ... + } + severity: WARNING + - id: java.java-jwt.security.audit.jwt-decode-without-verify.java-jwt-decode-without-verify languages: - - regex - message: A gitleaks confluent-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM + - 'CWE-345: Insufficient Verification of Data Authenticity' + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A08:2021 - Software and Data Integrity Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ subcategory: - vuln technology: - - gitleaks + - jwt patterns: - - pattern-regex: (?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.confluent-secret-key.confluent-secret-key + - pattern: | + com.auth0.jwt.JWT.decode(...); + - pattern-not-inside: |- + class $CLASS { + ... + $RETURNTYPE $FUNC (...) { + ... + $VERIFIER.verify(...); + ... + } + } + severity: WARNING + - id: java.java-jwt.security.jwt-hardcode.java-jwt-hardcoded-secret languages: - - regex - message: A gitleaks confluent-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: LOW + confidence: HIGH cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true @@ -4817,87566 +3544,21886 @@ rules: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - gitleaks + - java + - secrets + - jwt patterns: - - pattern-regex: (?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.contentful-delivery-api-token.contentful-delivery-api-token + - pattern-either: + - pattern: | + (Algorithm $ALG) = $ALGO.$HMAC("$Y"); + - pattern: | + $SECRET = "$Y"; + ... + (Algorithm $ALG) = $ALGO.$HMAC($SECRET); + - pattern: | + class $CLASS { + ... + $TYPE $SECRET = "$Y"; + ... + $RETURNTYPE $FUNC (...) { + ... + (Algorithm $ALG) = $ALGO.$HMAC($SECRET); + ... + } + ... + } + - focus-metavariable: $Y + - metavariable-regex: + metavariable: $HMAC + regex: (HMAC384|HMAC256|HMAC512) + severity: WARNING + - id: java.java-jwt.security.jwt-none-alg.java-jwt-none-alg languages: - - regex - message: A gitleaks contentful-delivery-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:contentful)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{43})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.databricks-api-token.databricks-api-token + - jwt + pattern-either: + - pattern: | + $JWT.sign(com.auth0.jwt.algorithms.Algorithm.none()); + - pattern: | + $NONE = com.auth0.jwt.algorithms.Algorithm.none(); + ... + $JWT.sign($NONE); + - pattern: |- + class $CLASS { + ... + $TYPE $NONE = com.auth0.jwt.algorithms.Algorithm.none(); + ... + $RETURNTYPE $FUNC (...) { + ... + $JWT.sign($NONE); + ... + } + ... + } + severity: ERROR + - id: java.jax-rs.security.jax-rs-path-traversal.jax-rs-path-traversal languages: - - regex - message: A gitleaks databricks-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected a potential path traversal. A malicious actor could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM + impact: LOW likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.owasp.org/index.php/Path_Traversal + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(dapi[a-h0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.datadog-access-token.datadog-access-token + - jax-rs + pattern-either: + - pattern: | + $RETURNTYPE $FUNC (..., @PathParam(...) $TYPE $VAR, ...) { + ... + new File(..., $VAR, ...); + ... + } + - pattern: |- + $RETURNTYPE $FUNC (..., @javax.ws.rs.PathParam(...) $TYPE $VAR, ...) { + ... + new File(..., $VAR, ...); + ... + } + severity: WARNING + - id: java.jboss.security.session_sqli.find-sql-string-concatenation languages: - - regex - message: A gitleaks datadog-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: In $METHOD, $X is used to construct a SQL query via string concatenation. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:datadog)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.defined-networking-api-token.defined-networking-api-token + - jboss + pattern-either: + - pattern: | + $RETURN $METHOD(...,String $X,...){ + ... + Session $SESSION = ...; + ... + String $QUERY = ... + $X + ...; + ... + PreparedStatement $PS = $SESSION.connection().prepareStatement($QUERY); + ... + ResultSet $RESULT = $PS.executeQuery(); + ... + } + - pattern: | + $RETURN $METHOD(...,String $X,...){ + ... + String $QUERY = ... + $X + ...; + ... + Session $SESSION = ...; + ... + PreparedStatement $PS = $SESSION.connection().prepareStatement($QUERY); + ... + ResultSet $RESULT = $PS.executeQuery(); + ... + } + severity: ERROR + - id: java.lang.security.audit.blowfish-insufficient-key-size.blowfish-insufficient-key-size languages: - - regex - message: A gitleaks defined-networking-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Using less than 128 bits for Blowfish is considered insecure. Use 128 bits or more, or switch to use AES instead. metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-326: Inadequate Encryption Strength' impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#BLOWFISH_KEY_SIZE subcategory: - - vuln + - audit technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)(?:dnkey)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(dnkey-[a-z0-9=_\-]{26}-[a-z0-9=_\-]{52})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.digitalocean-access-token.digitalocean-access-token + - pattern: | + $KEYGEN = KeyGenerator.getInstance("Blowfish"); + ... + $KEYGEN.init($SIZE); + - metavariable-comparison: + comparison: $SIZE < 128 + metavariable: $SIZE + severity: WARNING + - fix: | + "AES/GCM/NoPadding" + id: java.lang.security.audit.cbc-padding-oracle.cbc-padding-oracle languages: - - regex - message: A gitleaks digitalocean-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Using CBC with PKCS5Padding is susceptible to padding oracle attacks. A malicious actor could discern the difference between plaintext with valid or invalid padding. Further, CBC mode does not include any integrity checks. Use 'AES/GCM/NoPadding' instead. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://capec.mitre.org/data/definitions/463.html + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#cipher-modes + - https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PADDING_ORACLE subcategory: - - vuln + - audit technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)\b(doo_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.digitalocean-pat.digitalocean-pat + - pattern-inside: Cipher.getInstance("=~/.*\/CBC\/PKCS5Padding/") + - pattern: | + "=~/.*\/CBC\/PKCS5Padding/" + severity: WARNING + - id: java.lang.security.audit.crlf-injection-logs.crlf-injection-logs languages: - - regex - message: A gitleaks digitalocean-pat was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: When data from an untrusted source is put into a logger and not neutralized correctly, an attacker could forge log entries or include malicious content. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-93: Improper Neutralization of CRLF Sequences (''CRLF Injection'')' impact: MEDIUM likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#CRLF_INJECTION_LOGS subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)\b(dop_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.digitalocean-refresh-token.digitalocean-refresh-token + - pattern-either: + - patterns: + - pattern-inside: | + class $CLASS { + ... + Logger $LOG = ...; + ... + } + - pattern-either: + - pattern-inside: | + $X $METHOD(...,HttpServletRequest $REQ,...) { + ... + } + - pattern-inside: | + $X $METHOD(...,ServletRequest $REQ,...) { + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + HttpServletRequest $REQ = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + ServletRequest $REQ = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + Logger $LOG = ...; + ... + HttpServletRequest $REQ = ...; + ... + } + - pattern-inside: | + $X $METHOD(...) { + ... + Logger $LOG = ...; + ... + ServletRequest $REQ = ...; + ... + } + - pattern-either: + - pattern: | + String $VAL = $REQ.getParameter(...); + ... + $LOG.$LEVEL(<... $VAL ...>); + - pattern: | + String $VAL = $REQ.getParameter(...); + ... + $LOG.log($LEVEL,<... $VAL ...>); + - pattern: | + $LOG.$LEVEL(<... $REQ.getParameter(...) ...>); + - pattern: | + $LOG.log($LEVEL,<... $REQ.getParameter(...) ...>); + severity: WARNING + - fix: | + "AES/GCM/NoPadding" + id: java.lang.security.audit.crypto.des-is-deprecated.des-is-deprecated languages: - - regex - message: A gitleaks digitalocean-refresh-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + - kt + message: DES is considered deprecated. AES is the recommended cipher. Upgrade to use AES. See https://www.nist.gov/news-events/news/2005/06/nist-withdraws-outdated-data-encryption-standard for more information. metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::symmetric-algorithm::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.nist.gov/news-events/news/2005/06/nist-withdraws-outdated-data-encryption-standard + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#DES_USAGE subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)\b(dor_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.discord-api-token.discord-api-token + - pattern-either: + - pattern-inside: $CIPHER.getInstance("=~/DES/.*/") + - pattern-inside: $CIPHER.getInstance("DES") + - pattern-either: + - pattern: | + "=~/DES/.*/" + - pattern: | + "DES" + severity: WARNING + - id: java.lang.security.audit.crypto.desede-is-deprecated.desede-is-deprecated languages: - - regex - message: A gitleaks discord-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + - kt + message: Triple DES (3DES or DESede) is considered deprecated. AES is the recommended cipher. Upgrade to use AES. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::symmetric-algorithm::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#TDES_USAGE subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.discord-client-id.discord-client-id + - pattern-either: + - pattern: | + $CIPHER.getInstance("=~/DESede.*/") + - pattern: | + $CRYPTO.KeyGenerator.getInstance("DES") + severity: WARNING + - id: java.lang.security.audit.crypto.ecb-cipher.ecb-cipher languages: - - regex - message: A gitleaks discord-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Cipher in ECB mode is detected. ECB mode produces the same output for the same input each time which allows an attacker to intercept and replay the data. Further, ECB mode does not provide any integrity checking. See https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::mode::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#ECB_MODE subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{18})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.discord-client-secret.discord-client-secret - languages: - - regex - message: A gitleaks discord-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.doppler-api-token.doppler-api-token - languages: - - regex - message: A gitleaks doppler-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (dp\.pt\.)(?i)[a-z0-9]{43} - severity: INFO - - id: generic.secrets.gitleaks.droneci-access-token.droneci-access-token + - pattern: | + Cipher $VAR = $CIPHER.getInstance($MODE); + - metavariable-regex: + metavariable: $MODE + regex: .*ECB.* + severity: WARNING + - id: java.lang.security.audit.crypto.gcm-nonce-reuse.gcm-nonce-reuse languages: - - regex - message: A gitleaks droneci-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: 'GCM IV/nonce is reused: encryption can be totally useless' metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-323: Reusing a Nonce, Key Pair in Encryption' + functional-categories: + - crypto::search::randomness::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://www.youtube.com/watch?v=r1awgAl90wM subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)(?:droneci)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.dropbox-api-token.dropbox-api-token + - pattern-either: + - pattern: new GCMParameterSpec(..., "...".getBytes(...), ...); + - pattern: byte[] $NONCE = "...".getBytes(...); ... new GCMParameterSpec(..., $NONCE, ...); + severity: ERROR + - id: java.lang.security.audit.crypto.no-null-cipher.no-null-cipher languages: - - regex - message: A gitleaks dropbox-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: 'NullCipher was detected. This will not encrypt anything; the cipher text will be the same as the plain text. Use a valid, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#NULL_CIPHER subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{15})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.dropbox-long-lived-api-token.dropbox-long-lived-api-token + - pattern-either: + - pattern: new NullCipher(...); + - pattern: new javax.crypto.NullCipher(...); + severity: WARNING + - id: java.lang.security.audit.crypto.no-static-initialization-vector.no-static-initialization-vector languages: - - regex - message: A gitleaks dropbox-long-lived-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Initialization Vectors (IVs) for block ciphers should be randomly generated each time they are used. Using a static IV means the same plaintext encrypts to the same ciphertext every time, weakening the strength of the encryption. metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-329: Generation of Predictable IV with CBC Mode' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cwe.mitre.org/data/definitions/329.html + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#STATIC_IV subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.dropbox-short-lived-api-token.dropbox-short-lived-api-token + - java + pattern-either: + - pattern: | + byte[] $IV = { + ... + }; + ... + new IvParameterSpec($IV, ...); + - pattern: | + class $CLASS { + byte[] $IV = { + ... + }; + ... + $METHOD(...) { + ... + new IvParameterSpec($IV, ...); + ... + } + } + severity: WARNING + - id: java.lang.security.audit.crypto.rsa-no-padding.rsa-no-padding languages: - - regex - message: A gitleaks dropbox-short-lived-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + - kt + message: Using RSA without OAEP mode weakens the encryption. metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::mode::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://rdist.root.org/2009/10/06/why-rsa-encryption-padding-is-critical/ + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#RSA_NO_PADDING subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(sl\.[a-z0-9\-=_]{135})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.duffel-api-token.duffel-api-token + - java + - kotlin + pattern: $CIPHER.getInstance("=~/RSA/[Nn][Oo][Nn][Ee]/NoPadding/") + severity: WARNING + - id: java.lang.security.audit.crypto.unencrypted-socket.unencrypted-socket languages: - - regex - message: A gitleaks duffel-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected use of a Java socket that is not encrypted. As a result, the traffic could be read by an attacker intercepting the network traffic. Use an SSLSocket created by 'SSLSocketFactory' or 'SSLServerSocketFactory' instead. metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-319: Cleartext Transmission of Sensitive Information' + functional-categories: + - net::search::crypto-config::java.net impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNENCRYPTED_SOCKET subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: duffel_(test|live)_(?i)[a-z0-9_\-=]{43} - severity: INFO - - id: generic.secrets.gitleaks.dynatrace-api-token.dynatrace-api-token + - java + pattern-either: + - pattern: new ServerSocket(...) + - pattern: new Socket(...) + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-aes-ecb.use-of-aes-ecb languages: - - regex - message: A gitleaks dynatrace-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: 'Use of AES with ECB mode detected. ECB doesn''t provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::mode::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64} - severity: INFO - - id: generic.secrets.gitleaks.easypost-api-token.easypost-api-token + - java + pattern: $CIPHER.getInstance("=~/AES/ECB.*/") + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-blowfish.use-of-blowfish languages: - - regex - message: A gitleaks easypost-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: 'Use of Blowfish was detected. Blowfish uses a 64-bit block size that makes it vulnerable to birthday attacks, and is therefore considered non-compliant. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: \bEZAK(?i)[a-z0-9]{54} - severity: INFO - - id: generic.secrets.gitleaks.easypost-test-api-token.easypost-test-api-token + - java + pattern: $CIPHER.getInstance("Blowfish") + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-default-aes.use-of-default-aes languages: - - regex - message: A gitleaks easypost-test-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: 'Use of AES with no settings detected. By default, java.crypto.Cipher uses ECB mode. ECB doesn''t provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: java.crypto.Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::mode::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: \bEZTK(?i)[a-z0-9]{54} - severity: INFO - - id: generic.secrets.gitleaks.etsy-access-token.etsy-access-token + - java + pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + import javax; + ... + - pattern-either: + - pattern: javax.crypto.Cipher.getInstance("AES") + - pattern: (javax.crypto.Cipher $CIPHER).getInstance("AES") + - patterns: + - pattern-either: + - pattern-inside: | + import javax.*; + ... + - pattern-inside: | + import javax.crypto; + ... + - pattern-either: + - pattern: crypto.Cipher.getInstance("AES") + - pattern: (crypto.Cipher $CIPHER).getInstance("AES") + - patterns: + - pattern-either: + - pattern-inside: | + import javax.crypto.*; + ... + - pattern-inside: | + import javax.crypto.Cipher; + ... + - pattern-either: + - pattern: Cipher.getInstance("AES") + - pattern: (Cipher $CIPHER).getInstance("AES") + severity: WARNING + - fix: | + getSha512Digest + id: java.lang.security.audit.crypto.use-of-md5-digest-utils.use-of-md5-digest-utils languages: - - regex - message: A gitleaks etsy-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use HMAC instead. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-328: Use of Weak Hash' + functional-categories: + - crypto::search::hash-algorithm::org.apache.commons impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_MD5 subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)(?:etsy)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.facebook-access-token.facebook-access-token + - pattern: | + $DU.$GET_ALGO().digest(...) + - metavariable-pattern: + metavariable: $GET_ALGO + pattern: getMd5Digest + - metavariable-pattern: + metavariable: $DU + pattern: DigestUtils + - focus-metavariable: $GET_ALGO + severity: WARNING + - fix: | + "SHA-512" + id: java.lang.security.audit.crypto.use-of-md5.use-of-md5 languages: - - regex - message: A gitleaks facebook-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use HMAC instead. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-328: Use of Weak Hash' + functional-categories: + - crypto::search::hash-algorithm::java.security impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_MD5 subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)\b(\d{15,16}(\||%)[0-9a-z\-_]{27,40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.facebook-page-access-token.facebook-page-access-token + - pattern: | + java.security.MessageDigest.getInstance($ALGO, ...); + - metavariable-regex: + metavariable: $ALGO + regex: (.MD5.) + - focus-metavariable: $ALGO + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-rc2.use-of-rc2 languages: - - regex - message: A gitleaks facebook-page-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: 'Use of RC2 was detected. RC2 is vulnerable to related-key attacks, and is therefore considered non-compliant. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(EAA[MC][a-z0-9]{20,})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.facebook-secret.facebook-secret + - java + pattern: $CIPHER.getInstance("RC2") + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-rc4.use-of-rc4 languages: - - regex - message: A gitleaks facebook-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: 'Use of RC4 was detected. RC4 is vulnerable to several attacks, including stream cipher attacks and bit flipping attacks. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:facebook)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.facebook.facebook + - java + pattern: $CIPHER.getInstance("RC4") + severity: WARNING + - id: java.lang.security.audit.crypto.use-of-sha1.use-of-sha1 languages: - - regex - message: A gitleaks facebook was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Instead, use PBKDF2 for password hashing or SHA256 or SHA512 for other hash function applications. metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-328: Use of Weak Hash' + functional-categories: + - crypto::search::hash-algorithm::javax.crypto impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_SHA1 subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:facebook)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.fastly-api-token.fastly-api-token + - java + pattern-either: + - patterns: + - pattern: | + java.security.MessageDigest.getInstance("$ALGO", ...); + - metavariable-regex: + metavariable: $ALGO + regex: (SHA1|SHA-1) + - pattern: | + $DU.getSha1Digest().digest(...) + severity: WARNING + - id: java.lang.security.audit.crypto.weak-rsa.use-of-weak-rsa-key languages: - - regex - message: A gitleaks fastly-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: RSA keys should be at least 2048 bits based on NIST recommendation. metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::key-length::java.security impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#RSA_KEY_SIZE subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)(?:fastly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.finicity-api-token.finicity-api-token + - pattern: | + KeyPairGenerator $KEY = $G.getInstance("RSA"); + ... + $KEY.initialize($BITS); + - metavariable-comparison: + comparison: $BITS < 2048 + metavariable: $BITS + severity: WARNING + - id: java.lang.security.audit.formatted-sql-string.formatted-sql-string languages: - - regex - message: A gitleaks finicity-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. metadata: + asvs: + control_id: 5.3.5 Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + - https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html#create_ps + - https://software-security.sans.org/developer-how-to/fix-sql-injection-in-java-using-prepared-callable-statement + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SQL_INJECTION subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.finicity-client-secret.finicity-client-secret - languages: - - regex - message: A gitleaks finicity-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.finnhub-access-token.finnhub-access-token - languages: - - regex - message: A gitleaks finnhub-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:finnhub)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.flickr-access-token.flickr-access-token + - java + mode: taint + options: + taint_assume_safe_booleans: true + taint_assume_safe_numbers: true + pattern-propagators: + - from: $X + pattern: (StringBuffer $S).append($X) + to: $S + - from: $X + pattern: (StringBuilder $S).append($X) + to: $S + pattern-sanitizers: + - patterns: + - pattern: (CriteriaBuilder $CB).$ANY(...) + pattern-sinks: + - patterns: + - pattern-not: $S.$SQLFUNC(<... "=~/.*TABLE *$/" ...>) + - pattern-not: $S.$SQLFUNC(<... "=~/.*TABLE %s$/" ...>) + - pattern-either: + - pattern: (Statement $S).$SQLFUNC(...) + - pattern: (PreparedStatement $P).$SQLFUNC(...) + - pattern: (Connection $C).createStatement(...).$SQLFUNC(...) + - pattern: (Connection $C).prepareStatement(...).$SQLFUNC(...) + - pattern: (EntityManager $EM).$SQLFUNC(...) + - metavariable-regex: + metavariable: $SQLFUNC + regex: execute|executeQuery|createQuery|query|addBatch|nativeSQL|create|prepare + requires: CONCAT + pattern-sources: + - label: INPUT + patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + $ANNOT $FUNC (..., $INPUT, ...) { + ... + } + - pattern: (String $INPUT) + - focus-metavariable: $INPUT + - label: CONCAT + patterns: + - pattern-either: + - pattern: $X + $INPUT + - pattern: $X += $INPUT + - pattern: $STRB.append($INPUT) + - pattern: String.format(..., $INPUT, ...) + - pattern: String.join(..., $INPUT, ...) + - pattern: (String $STR).concat($INPUT) + - pattern: $INPUT.concat(...) + - pattern: new $STRB(..., $INPUT, ...) + requires: INPUT + severity: ERROR + - id: java.lang.security.audit.http-response-splitting.http-response-splitting languages: - - regex - message: A gitleaks flickr-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Older Java application servers are vulnerable to HTTP response splitting, which may occur if an HTTP request can be injected with CRLF characters. This finding is reported for completeness; it is recommended to ensure your environment is not affected by testing this yourself. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers (''HTTP Request/Response Splitting'')' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.owasp.org/index.php/HTTP_Response_Splitting + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#HTTP_RESPONSE_SPLITTING subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:flickr)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) + - java + pattern-either: + - pattern: | + $VAR = $REQ.getParameter(...); + ... + $COOKIE = new Cookie(..., $VAR, ...); + ... + $RESP.addCookie($COOKIE, ...); + - patterns: + - pattern-inside: | + $RETTYPE $FUNC(...,@PathVariable $TYPE $VAR, ...) { + ... + } + - pattern: | + $COOKIE = new Cookie(..., $VAR, ...); + ... + $RESP.addCookie($COOKIE, ...); severity: INFO - - id: generic.secrets.gitleaks.flutterwave-encryption-key.flutterwave-encryption-key + - id: java.lang.security.audit.insecure-smtp-connection.insecure-smtp-connection languages: - - regex - message: A gitleaks flutterwave-encryption-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Insecure SMTP connection detected. This connection will trust any SSL certificate. Enable certificate verification by setting 'email.setSSLCheckServerIdentity(true)'. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-297: Improper Validation of Certificate with Host Mismatch' impact: MEDIUM likelihood: LOW owasp: - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#INSECURE_SMTP_SSL subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: FLWSECK_TEST-(?i)[a-h0-9]{12} - severity: INFO - - id: generic.secrets.gitleaks.flutterwave-public-key.flutterwave-public-key + - pattern-not-inside: | + $EMAIL.setSSLCheckServerIdentity(true); + ... + - pattern-inside: | + $EMAIL = new SimpleEmail(...); + ... + - pattern: $EMAIL.send(...); + severity: WARNING + - id: java.lang.security.audit.md5-used-as-password.md5-used-as-password languages: - - regex - message: A gitleaks flutterwave-public-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as PBKDF2 or bcrypt. You can use `javax.crypto.SecretKeyFactory` with `SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")` or, if using Spring, `org.springframework.security.crypto.bcrypt`. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html + - https://github.com/returntocorp/semgrep-rules/issues/1609 + - https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory + - https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: FLWPUBK_TEST-(?i)[a-h0-9]{32}-X - severity: INFO - - id: generic.secrets.gitleaks.flutterwave-secret-key.flutterwave-secret-key + - java + - md5 + mode: taint + pattern-sinks: + - patterns: + - pattern: $MODEL.$METHOD(...); + - metavariable-regex: + metavariable: $METHOD + regex: (?i)(.*password.*) + pattern-sources: + - patterns: + - pattern-inside: | + $TYPE $MD = MessageDigest.getInstance("MD5"); + ... + - pattern: $MD.digest(...); + severity: WARNING + - id: java.lang.security.audit.sqli.tainted-sql-from-http-request.tainted-sql-from-http-request languages: - - regex - message: A gitleaks flutterwave-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected input from a HTTPServletRequest going into a SQL sink or statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use parameterized SQL queries or properly sanitize user input instead. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + - https://owasp.org/www-community/attacks/SQL_Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: FLWSECK_TEST-(?i)[a-h0-9]{32}-X - severity: INFO - - id: generic.secrets.gitleaks.frameio-api-token.frameio-api-token + - sql + - java + - servlets + - spring + mode: taint + options: + taint_assume_safe_booleans: true + taint_assume_safe_numbers: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: "(java.sql.CallableStatement $STMT) = ...; \n" + - pattern: | + (java.sql.Statement $STMT) = ...; + ... + $OUTPUT = $STMT.$FUNC(...); + - pattern: | + (java.sql.PreparedStatement $STMT) = ...; + - pattern: | + $VAR = $CONN.prepareStatement(...) + - pattern: | + $PATH.queryForObject(...); + - pattern: | + (java.util.Map $STMT) = $PATH.queryForMap(...); + - pattern: | + (org.springframework.jdbc.support.rowset.SqlRowSet $STMT) = ...; + - pattern: | + (org.springframework.jdbc.core.JdbcTemplate $TEMPL).batchUpdate(...) + - patterns: + - pattern-inside: | + (String $SQL) = "$SQLSTR" + ...; + ... + - pattern: $PATH.$SQLCMD(..., $SQL, ...); + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(^SELECT.* | ^INSERT.* | ^UPDATE.*) + - metavariable-regex: + metavariable: $SQLCMD + regex: (execute|query|executeUpdate|batchUpdate) + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ).$REQFUNC(...) + - pattern: "(ServletRequest $REQ).$REQFUNC(...) \n" + - metavariable-regex: + metavariable: $REQFUNC + regex: (getInputStream|getParameter|getParameterMap|getParameterValues|getReader|getCookies|getHeader|getHeaderNames|getHeaders|getPart|getParts|getQueryString) + severity: WARNING + - id: java.lang.security.audit.tainted-cmd-from-http-request.tainted-cmd-from-http-request languages: - - regex - message: A gitleaks frameio-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected input from a HTTPServletRequest going into a 'ProcessBuilder' or 'exec' command. This could lead to command injection if variables passed into the exec commands are not properly sanitized. Instead, avoid using these OS commands with user-supplied input, or, if you must use these commands, use a whitelist of specific values. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: fio-u-(?i)[a-z0-9\-_=]{64} - severity: INFO - - id: generic.secrets.gitleaks.gcp-api-key.gcp-api-key + - java + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (ProcessBuilder $PB) = ...; + - patterns: + - pattern: | + (Process $P) = ...; + - pattern-not: | + (Process $P) = (java.lang.Runtime $R).exec(...); + - patterns: + - pattern: (java.lang.Runtime $R).exec($CMD, ...); + - focus-metavariable: $CMD + - patterns: + - pattern-either: + - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(ProcessBuilder $PB) = ...;\n...\n$PB.command($ARGLIST);\n" + - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(ProcessBuilder $PB) = ...;\n" + - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(Process $P) = ...;\n" + - pattern: | + $ARGLIST.add(...); + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); + ... + for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { + ... + } + - pattern: | + $COOKIE.getValue(...) + severity: ERROR + - id: java.lang.security.audit.tainted-env-from-http-request.tainted-env-from-http-request languages: - - regex - message: A gitleaks gcp-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected input from a HTTPServletRequest going into the environment variables of an 'exec' command. Instead, call the command with user-supplied arguments by using the overloaded method with one String array as the argument. `exec({"command", "arg1", "arg2"})`. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-454: External Initialization of Trusted Variables or Data Stores' + cwe2021-top25: false + cwe2022-top25: false impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(AIza[0-9A-Za-z\\-_]{35})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.generic-api-key.generic-api-key + - java + mode: taint + pattern-sinks: + - patterns: + - pattern: (java.lang.Runtime $R).exec($CMD, $ENV_ARGS, ...); + - focus-metavariable: $ENV_ARGS + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); + ... + for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { + ... + } + - pattern: | + $COOKIE.getValue(...) + severity: ERROR + - id: java.lang.security.audit.tainted-ldapi-from-http-request.tainted-ldapi-from-http-request languages: - - regex - message: A gitleaks generic-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). This rule can introduce a lot of false positives, it is not recommended to be used in PR comments. + - java + message: Detected input from a HTTPServletRequest going into an LDAP query. This could lead to LDAP injection if the input is not properly sanitized, which could result in attackers modifying objects in the LDAP tree structure. Ensure data passed to an LDAP query is not controllable or properly sanitize the data. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://sensei.securecodewarrior.com/recipes/scw%3Ajava%3ALDAP-injection subcategory: - vuln technology: - - gitleaks - paths: - exclude: - - '*.svg' - - '*go.sum' - - '*cargo.lock' - - '*package.json' - - '*package-lock.json' - - '*bundle.js' - - '*pnpm-lock*' - - '*Podfile.lock' - - '*/openssl/*.h' - - '*.xcscmblueprint' - patterns: - - pattern-regex: (?i)(?:key|api|token|secret|client|passwd|password|auth|access)(?:[0-9a-z\-_\t.]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:=|\|\|:|<=|=>|:)(?:'|@\"|\"|\s|=|\x60){0,5}(?!([a-z]+\.[a-zA-Z]+)|.*(\d{4}-\d{2}-\d{2}|[a-z]+-[a-z]+.*)|:*(?!("|'))[0-9A-Za-z]+\.[0-9A-Za-z]+,|[A-Z]+_[A-Z]+_)(?P[0-9a-z\-_.=\~]{10,150})(?:['|\"|\n|\r|\s|\x60|;]|$) - - metavariable-analysis: - analyzer: entropy - metavariable: $CONTENT - - focus-metavariable: $CONTENT - - pattern-not-regex: .*((?i)omitted|arn:aws|(?i)(pub.*key|public.*key)|(?i)clientToken|symbol|cache|author\.).* - - pattern-not-regex: (\d\.\d\.\d-}|([\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})|(\w)\1{5}|(?i)keywords|xxxx|eeeeeeee|0000|\*\*\*|example|test|author=|author("|')|preview|[A-Z]+_KEY|[.]value|[.]key|-\d\.\d\.) - - metavariable-regex: - metavariable: $CONTENT - regex: (?!(^0x0*|^pub)|.*\.(bin|json|exe)$|.*(?i)(Client|Factory)$|(^__[A-Za-z]+__$)|^(12345|abcd)|^\d+(\.\d+)?$) - - pattern-not-regex: (\w|\.)\1{5} - - metavariable-regex: - metavariable: $CONTENT - regex: (?!(?i).*(client|endpoint|vpn|_ec2_|aws_|authorize|author|define|config|credential|setting|sample|xxxxxx|000000|buffer|delete|aaaaaa|fewfwef|getenv|env_|system|example|ecdsa|sha256|sha1|sha2|md5|alert|wizard|target|onboard|welcome|page|exploit|experiment|expire|rabbitmq|scraper|widget|music|dns_|dns-|yahoo|want|json|action|script|fix_|fix-|develop|compas|stripe|service|master|metric|tech|gitignore|rich|open|stack|irc_|irc-|sublime|kohana|has_|has-|fabric|wordpres|role|osx_|osx-|boost|addres|queue|working|sandbox|internet|print|vision|tracking|being|generator|traffic|world|pull|rust|watcher|small|auth|full|hash|more|install|auto|complete|learn|paper|installer|research|acces|last|binding|spine|into|chat|algorithm|resource|uploader|video|maker|next|proc|lock|robot|snake|patch|matrix|drill|terminal|term|stuff|genetic|generic|identity|audit|pattern|audio|web_|web-|crud|problem|statu|cms-|cms_|arch|coffee|workflow|changelog|another|uiview|content|kitchen|gnu_|gnu-|gnu\.|conf|couchdb|client|opencv|rendering|update|concept|varnish|gui_|gui-|gui\.|version|shared|extra|product|still|not_|not-|not\.|drop|ring|png_|png-|png\.|actively|import|output|backup|start|embedded|registry|pool|semantic|instagram|bash|system|ninja|drupal|jquery|polyfill|physic|league|guide|pack|synopsi|sketch|injection|svg_|svg-|svg\.|friendly|wave|convert|manage|camera|link|slide|timer|wrapper|gallery|url_|url-|url\.|todomvc|requirej|party|http|payment|async|library|home|coco|gaia|display|universal|func|metadata|hipchat|under|room|config|personal|realtime|resume|database|testing|tiny|basic|forum|meetup|yet_|yet-|yet\.|cento|dead|fluentd|editor|utilitie|run_|run-|run\.|box_|box-|box\.|bot_|bot-|bot\.|making|sample|group|monitor|ajax|parallel|cassandra|ultimate|site|get_|get-|get\.|gen_|gen-|gen\.|gem_|gem-|gem\.|extended|image|knife|asset|nested|zero|plugin|bracket|mule|mozilla|number|act_|act-|act\.|map_|map-|map\.|micro|debug|openshift|chart|expres|backend|task|source|translate|jbos|composer|sqlite|profile|mustache|mqtt|yeoman|have|builder|smart|like|oauth|school|guideline|captcha|filter|bitcoin|bridge|color|toolbox|discovery|new_|new-|new\.|dashboard|when|setting|level|post|standard|port|platform|yui_|yui-|yui\.|grunt|animation|haskell|icon|latex|cheat|lua_|lua-|lua\.|gulp|case|author|without|simulator|wifi|directory|lisp|list|flat|adventure|story|storm|gpu_|gpu-|gpu\.|store|caching|attention|solr|logger|demo|shortener|hadoop|finder|phone|pipeline|range|textmate|showcase|app_|app-|app\.|idiomatic|edit|our_|our-|our\.|out_|out-|out\.|sentiment|linked|why_|why-|why\.|local|cube|gmail|job_|job-|job\.|rpc_|rpc-|rpc\.|contest|tcp_|tcp-|tcp\.|usage|buildout|weather|transfer|automated|sphinx|issue|sas_|sas-|sas\.|parallax|jasmine|addon|machine|solution|dsl_|dsl-|dsl\.|episode|menu|theme|best|adapter|debugger|chrome|tutorial|life|step|people|joomla|paypal|developer|solver|team|current|love|visual|date|data|canva|container|future|xml_|xml-|xml\.|twig|nagio|spatial|original|sync|archived|refinery|science|mapping|gitlab|play|ext_|ext-|ext\.|session|impact|set_|set-|set\.|see_|see-|see\.|migration|commit|community|shopify|what'|cucumber|statamic|mysql|location|tower|line|code|amqp|hello|send|index|high|notebook|alloy|python|field|document|soap|edition|email|php_|php-|php\.|command|transport|official|upload|study|secure|angularj|akka|scalable|package|request|con_|con-|con\.|flexible|security|comment|module|flask|graph|flash|apache|change|window|space|lambda|sheet|bookmark|carousel|friend|objective|jekyll|bootstrap|first|article|gwt_|gwt-|gwt\.|classic|media|websocket|touch|desktop|real|read|recorder|moved|storage|validator|add-on|pusher|scs_|scs-|scs\.|inline|asp_|asp-|asp\.|timeline|base|encoding|ffmpeg|kindle|tinymce|pretty|jpa_|jpa-|jpa\.|used|user|required|webhook|download|resque|espresso|cloud|mongo|benchmark|pure|cakephp|modx|mode|reactive|fuel|written|flickr|mail|brunch|meteor|dynamic|neo_|neo-|neo\.|new_|new-|new\.|net_|net-|net\.|typo|type|keyboard|erlang|adobe|logging|ckeditor|message|iso_|iso-|iso\.|hook|ldap|folder|reference|railscast|www_|www-|www\.|tracker|azure|fork|form|digital|exporter|skin|string|template|designer|gollum|fluent|entity|language|alfred|summary|wiki|kernel|calendar|plupload|symfony|foundry|remote|talk|search|dev_|dev-|dev\.|del_|del-|del\.|token|idea|sencha|selector|interface|create|fun_|fun-|fun\.|groovy|query|grail|red_|red-|red\.|laravel|monkey|slack|supported|instant|value|center|latest|work|but_|but-|but\.|bug_|bug-|bug\.|virtual|tweet|statsd|studio|path|real-time|frontend|notifier|coding|tool|firmware|flow|random|mediawiki|bosh|been|beer|lightbox|theory|origin|redmine|hub_|hub-|hub\.|require|pro_|pro-|pro\.|ant_|ant-|ant\.|any_|any-|any\.|recipe|closure|mapper|event|todo|model|redi|provider|rvm_|rvm-|rvm\.|program|memcached|rail|silex|foreman|activity|license|strategy|batch|streaming|fast|use_|use-|use\.|usb_|usb-|usb\.|impres|academy|slider|please|layer|cros|now_|now-|now\.|miner|extension|own_|own-|own\.|app_|app-|app\.|debian|symphony|example|feature|serie|tree|project|runner|entry|leetcode|layout|webrtc|logic|login|worker|toolkit|mocha|support|back|inside|device|jenkin|contact|fake|awesome|ocaml|bit_|bit-|bit\.|drive|screen|prototype|gist|binary|nosql|rest|overview|dart|dark|emac|mongoid|solarized|homepage|emulator|commander|django|yandex|gradle|xcode|writer|crm_|crm-|crm\.|jade|startup|error|using|format|name|spring|parser|scratch|magic|try_|try-|try\.|rack|directive|challenge|slim|counter|element|chosen|doc_|doc-|doc\.|meta|should|button|packet|stream|hardware|android|infinite|password|software|ghost|xamarin|spec|chef|interview|hubot|mvc_|mvc-|mvc\.|exercise|leaflet|launcher|air_|air-|air\.|photo|board|boxen|way_|way-|way\.|computing|welcome|notepad|portfolio|cat_|cat-|cat\.|can_|can-|can\.|magento|yaml|domain|card|yii_|yii-|yii\.|checker|browser|upgrade|only|progres|aura|ruby_|ruby-|ruby\.|polymer|util|lite|hackathon|rule|log_|log-|log\.|opengl|stanford|skeleton|history|inspector|help|soon|selenium|lab_|lab-|lab\.|scheme|schema|look|ready|leveldb|docker|game|minimal|logstash|messaging|within|heroku|mongodb|kata|suite|picker|win_|win-|win\.|wip_|wip-|wip\.|panel|started|starter|front-end|detector|deploy|editing|based|admin|capture|spree|page|bundle|goal|rpg_|rpg-|rpg\.|setup|side|mean|reader|cookbook|mini|modern|seed|dom_|dom-|dom\.|doc_|doc-|doc\.|dot_|dot-|dot\.|syntax|sugar|loader|website|make|kit_|kit-|kit\.|protocol|human|daemon|golang|manager|countdown|connector|swagger|map_|map-|map\.|mac_|mac-|mac\.|man_|man-|man\.|orm_|orm-|orm\.|org_|org-|org\.|little|zsh_|zsh-|zsh\.|shop|show|workshop|money|grid|server|octopres|svn_|svn-|svn\.|ember|embed|general|file|important|dropbox|portable|public|docpad|fish|sbt_|sbt-|sbt\.|done|para|network|common|readme|popup|simple|purpose|mirror|single|cordova|exchange|object|design|gateway|account|lamp|intellij|math|mit_|mit-|mit\.|control|enhanced|emitter|multi|add_|add-|add\.|about|socket|preview|vagrant|cli_|cli-|cli\.|powerful|top_|top-|top\.|radio|watch|fluid|amazon|report|couchbase|automatic|detection|sprite|pyramid|portal|advanced|plu_|plu-|plu\.|runtime|git_|git-|git\.|uri_|uri-|uri\.|haml|node|sql_|sql-|sql\.|cool|core|obsolete|handler|iphone|extractor|array|copy|nlp_|nlp-|nlp\.|reveal|pop_|pop-|pop\.|engine|parse|check|html|nest|all_|all-|all\.|chinese|buildpack|what|tag_|tag-|tag\.|proxy|style|cookie|feed|restful|compiler|creating|prelude|context|java|rspec|mock|backbone|light|spotify|flex|related|shell|which|clas|webapp|swift|ansible|unity|console|tumblr|export|campfire|conway'|made|riak|hero|here|unix|unit|glas|smtp|how_|how-|how\.|hot_|hot-|hot\.|debug|release|diff|player|easy|right|old_|old-|old\.|animate|time|push|explorer|course|training|nette|router|draft|structure|note|salt|where|spark|trello|power|method|social|via_|via-|via\.|vim_|vim-|vim\.|select|webkit|github|ftp_|ftp-|ftp\.|creator|mongoose|led_|led-|led\.|movie|currently|pdf_|pdf-|pdf\.|load|markdown|phalcon|input|custom|atom|oracle|phonegap|ubuntu|great|rdf_|rdf-|rdf\.|popcorn|firefox|zip_|zip-|zip\.|cuda|dotfile|static|openwrt|viewer|powered|graphic|les_|les-|les\.|doe_|doe-|doe\.|maven|word|eclipse|lab_|lab-|lab\.|hacking|steam|analytic|option|abstract|archive|reality|switcher|club|write|kafka|arduino|angular|online|title|don't|contao|notice|analyzer|learning|zend|external|staging|busines|tdd_|tdd-|tdd\.|scanner|building|snippet|modular|bower|stm_|stm-|stm\.|lib_|lib-|lib\.|alpha|mobile|clean|linux|nginx|manifest|some|raspberry|gnome|ide_|ide-|ide\.|block|statistic|info|drag|youtube|koan|facebook|paperclip|art_|art-|art\.|quality|tab_|tab-|tab\.|need|dojo|shield|computer|stat|state|twitter|utility|converter|hosting|devise|liferay|updated|force|tip_|tip-|tip\.|behavior|active|call|answer|deck|better|principle|ches|bar_|bar-|bar\.|reddit|three|haxe|just|plug-in|agile|manual|tetri|super|beta|parsing|doctrine|minecraft|useful|perl|sharing|agent|switch|view|dash|channel|repo|pebble|profiler|warning|cluster|running|markup|evented|mod_|mod-|mod\.|share|csv_|csv-|csv\.|response|good|house|connect|built|build|find|ipython|webgl|big_|big-|big\.|google|scala|sdl_|sdl-|sdl\.|sdk_|sdk-|sdk\.|native|day_|day-|day\.|puppet|text|routing|helper|linkedin|crawler|host|guard|merchant|poker|over|writing|free|classe|component|craft|nodej|phoenix|longer|quick|lazy|memory|clone|hacker|middleman|factory|motion|multiple|tornado|hack|ssh_|ssh-|ssh\.|review|vimrc|driver|driven|blog|particle|table|intro|importer|thrift|xmpp|framework|refresh|react|font|librarie|variou|formatter|analysi|karma|scroll|tut_|tut-|tut\.|apple|tag_|tag-|tag\.|tab_|tab-|tab\.|category|ionic|cache|homebrew|reverse|english|getting|shipping|clojure|boot|book|branch|combination|combo)) - severity: INFO - - id: generic.secrets.gitleaks.github-app-token.github-app-token + - java + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (javax.naming.directory.InitialDirContext $IDC).search(...) + - pattern: | + (javax.naming.directory.DirContext $CTX).search(...) + - pattern-not: | + (javax.naming.directory.InitialDirContext $IDC).search($Y, "...", ...) + - pattern-not: | + (javax.naming.directory.DirContext $CTX).search($Y, "...", ...) + pattern-sources: + - patterns: + - pattern: (HttpServletRequest $REQ) + severity: WARNING + - id: java.lang.security.audit.tainted-session-from-http-request.tainted-session-from-http-request languages: - - regex - message: A gitleaks github-app-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected input from a HTTPServletRequest going into a session command, like `setAttribute`. User input into such a command could lead to an attacker inputting malicious code into your session parameters, blurring the line between what's trusted and untrusted, and therefore leading to a trust boundary violation. This could lead to programmers trusting unvalidated data. Instead, thoroughly sanitize user input before passing it into such function calls. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-501: Trust Boundary Violation' impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A04_2021-Insecure_Design subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (ghu|ghs)_[0-9a-zA-Z]{36} - severity: INFO - - id: generic.secrets.gitleaks.github-fine-grained-pat.github-fine-grained-pat + - java + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern: (HttpServletRequest $REQ).getSession().$FUNC($NAME, $VALUE); + - metavariable-regex: + metavariable: $FUNC + regex: ^(putValue|setAttribute)$ + - focus-metavariable: $VALUE + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern: | + (HttpServletRequest $REQ).$FUNC(...) + - pattern-not: | + (HttpServletRequest $REQ).getSession() + - patterns: + - pattern-inside: | + (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); + ... + for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { + ... + } + - pattern: | + $COOKIE.getValue(...) + - patterns: + - pattern-inside: | + $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(... ); + ... + - pattern: | + $PARAM = $VALS[$INDEX]; + - patterns: + - pattern-inside: | + $HEADERS = (HttpServletRequest $REQ).getHeaders(...); + ... + $PARAM = $HEADERS.$FUNC(...); + ... + - pattern: | + java.net.URLDecoder.decode($PARAM, ...) + severity: WARNING + - id: java.lang.security.audit.tainted-xpath-from-http-request.tainted-xpath-from-http-request languages: - - regex - message: A gitleaks github-fine-grained-pat was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected input from a HTTPServletRequest going into a XPath evaluate or compile command. This could lead to xpath injection if variables passed into the evaluate or compile commands are not properly sanitized. Xpath injection could lead to unauthorized access to sensitive information in XML documents. Instead, thoroughly sanitize user input or use parameterized xpath queries if you can. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-643: Improper Neutralization of Data within XPath Expressions (''XPath Injection'')' impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: github_pat_[0-9a-zA-Z_]{82} - severity: INFO - - id: generic.secrets.gitleaks.github-oauth.github-oauth + - java + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (javax.xml.xpath.XPath $XP).evaluate(...) + - pattern: | + (javax.xml.xpath.XPath $XP).compile(...).evaluate(...) + pattern-sources: + - patterns: + - pattern: | + (HttpServletRequest $REQ).$FUNC(...) + severity: WARNING + - id: java.lang.security.audit.unvalidated-redirect.unvalidated-redirect languages: - - regex - message: A gitleaks github-oauth was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Application redirects to a destination URL specified by a user-supplied parameter that is not validated. This could direct users to malicious locations. Consider using an allowlist to validate URLs. metadata: + asvs: + control_id: 5.1.5 Open Redirect + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNVALIDATED_REDIRECT subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: gho_[0-9a-zA-Z]{36} - severity: INFO - - id: generic.secrets.gitleaks.github-pat.github-pat - languages: - - regex - message: A gitleaks github-pat was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: ghp_[0-9a-zA-Z]{36} - severity: INFO - - id: generic.secrets.gitleaks.github-refresh-token.github-refresh-token - languages: - - regex - message: A gitleaks github-refresh-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: ghr_[0-9a-zA-Z]{36} - severity: INFO - - id: generic.secrets.gitleaks.gitlab-pat.gitlab-pat + - java + pattern-either: + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...,String $URL,...) { + ... + $RES.sendRedirect($URL); + ... + } + - pattern: | + $X $METHOD(...,String $URL,...,HttpServletResponse $RES,...) { + ... + $RES.sendRedirect($URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { + ... + String $URL = $REQ.getParameter(...); + ... + $RES.sendRedirect($URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { + ... + String $URL = $REQ.getParameter(...); + ... + $RES.sendRedirect($URL); + ... + } + - pattern: | + $X $METHOD(...,String $URL,...) { + ... + HttpServletResponse $RES = ...; + ... + $RES.sendRedirect($URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { + ... + $RES.sendRedirect($REQ.getParameter(...)); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { + ... + $RES.sendRedirect($REQ.getParameter(...)); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...,String $URL,...) { + ... + $RES.addHeader("Location",$URL); + ... + } + - pattern: | + $X $METHOD(...,String $URL,...,HttpServletResponse $RES,...) { + ... + $RES.addHeader("Location",$URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { + ... + String $URL = $REQ.getParameter(...); + ... + $RES.addHeader("Location",$URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { + ... + String $URL = $REQ.getParameter(...); + ... + $RES.addHeader("Location",$URL); + ... + } + - pattern: | + $X $METHOD(...,String $URL,...) { + ... + HttpServletResponse $RES = ...; + ... + $RES.addHeader("Location",$URL); + ... + } + - pattern: | + $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { + ... + $RES.addHeader("Location",$REQ.getParameter(...)); + ... + } + - pattern: |- + $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { + ... + $RES.addHeader("Location",$REQ.getParameter(...)); + ... + } + severity: WARNING + - fix-regex: + regex: (.*?)\.getInstance\(.*?\) + replacement: \1.getInstance("TLSv1.2") + id: java.lang.security.audit.weak-ssl-context.weak-ssl-context languages: - - regex - message: A gitleaks gitlab-pat was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: An insecure SSL context was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use SSLContext.getInstance("TLSv1.2") for the best security. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-326: Inadequate Encryption Strength' impact: MEDIUM likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://tools.ietf.org/html/rfc7568 + - https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html + source_rule_url: https://find-sec-bugs.github.io/bugs.htm#SSL_CONTEXT subcategory: - - vuln + - audit technology: - - gitleaks + - java patterns: - - pattern-regex: glpat-[0-9a-zA-Z\-\_]{20} - severity: INFO - - id: generic.secrets.gitleaks.gitlab-ptt.gitlab-ptt + - pattern-not: SSLContext.getInstance("TLSv1.3") + - pattern-not: SSLContext.getInstance("TLSv1.2") + - pattern: SSLContext.getInstance("...") + severity: WARNING + - id: java.lang.security.audit.xss.no-direct-response-writer.no-direct-response-writer languages: - - regex - message: A gitleaks gitlab-ptt was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected a request with potential user-input going into a OutputStream or Writer object. This bypasses any view or template environments, including HTML escaping, which may expose this application to cross-site scripting (XSS) vulnerabilities. Consider using a view technology such as JavaServer Faces (JSFs) which automatically escapes HTML views. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + license: proprietary license - copyright © Semgrep, Inc. + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaServerFaces.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: glptt-[0-9a-f]{40} - severity: INFO - - id: generic.secrets.gitleaks.gitlab-rrt.gitlab-rrt + - java + - servlets + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern-either: + - pattern: Encode.forHtml(...) + - pattern: (PolicyFactory $POLICY).sanitize(...) + - pattern: (AntiSamy $AS).scan(...) + - pattern: JSoup.clean(...) + - pattern: org.apache.commons.lang.StringEscapeUtils.escapeHtml(...) + - pattern: org.springframework.web.util.HtmlUtils.htmlEscape(...) + - pattern: org.owasp.esapi.ESAPI.encoder().encodeForHTML(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (HttpServletResponse $RESPONSE).getWriter(...).$WRITE(...) + - pattern: | + (HttpServletResponse $RESPONSE).getOutputStream(...).$WRITE(...) + - pattern: | + (java.io.PrintWriter $WRITER).$WRITE(...) + - pattern: | + (PrintWriter $WRITER).$WRITE(...) + - pattern: | + (javax.servlet.ServletOutputStream $WRITER).$WRITE(...) + - pattern: | + (ServletOutputStream $WRITER).$WRITE(...) + - pattern: | + (java.io.OutputStream $WRITER).$WRITE(...) + - pattern: | + (OutputStream $WRITER).$WRITE(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ).$REQFUNC(...) + - pattern: "(ServletRequest $REQ).$REQFUNC(...) \n" + - metavariable-regex: + metavariable: $REQFUNC + regex: (getInputStream|getParameter|getParameterMap|getParameterValues|getReader|getCookies|getHeader|getHeaderNames|getHeaders|getPart|getParts|getQueryString) + severity: WARNING + - id: java.lang.security.audit.xxe.documentbuilderfactory-disallow-doctype-decl-false.documentbuilderfactory-disallow-doctype-decl-false languages: - - regex - message: A gitleaks gitlab-rrt was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: DOCTYPE declarations are enabled for $DBFACTORY. Without prohibiting external entity declarations, this is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false. metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html subcategory: - vuln technology: - - gitleaks + - java + - xml patterns: - - pattern-regex: GR1348941[0-9a-zA-Z\-\_]{20} - severity: INFO - - id: generic.secrets.gitleaks.gitter-access-token.gitter-access-token + - pattern: $DBFACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false); + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + } + severity: ERROR + - fix: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + $FACTORY.newDocumentBuilder(); + id: java.lang.security.audit.xxe.documentbuilderfactory-disallow-doctype-decl-missing.documentbuilderfactory-disallow-doctype-decl-missing languages: - - regex - message: A gitleaks gitter-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: DOCTYPE declarations are enabled for this DocumentBuilderFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false. metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:gitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.gocardless-api-token.gocardless-api-token + - java + - xml + mode: taint + pattern-sanitizers: + - by-side-effect: true + pattern-either: + - patterns: + - pattern-either: + - pattern: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + - focus-metavariable: $FACTORY + - patterns: + - pattern-either: + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", + true); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); + ... + } + ... + } + - pattern: $M($X) + - focus-metavariable: $X + pattern-sinks: + - patterns: + - pattern: $FACTORY.newDocumentBuilder(); + pattern-sources: + - by-side-effect: true + patterns: + - pattern-either: + - pattern: | + $FACTORY = DocumentBuilderFactory.newInstance(); + - patterns: + - pattern: $FACTORY + - pattern-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + severity: ERROR + - fix: $DBFACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + id: java.lang.security.audit.xxe.documentbuilderfactory-external-general-entities-true.documentbuilderfactory-external-general-entities-true languages: - - regex - message: A gitleaks gocardless-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: External entities are allowed for $DBFACTORY. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://xml.org/sax/features/external-general-entities" to false. metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:gocardless)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(live_(?i)[a-z0-9\-_=]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.grafana-api-key.grafana-api-key + - java + - xml + pattern: $DBFACTORY.setFeature("http://xml.org/sax/features/external-general-entities", true); + severity: ERROR + - fix: $DBFACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + id: java.lang.security.audit.xxe.documentbuilderfactory-external-parameter-entities-true.documentbuilderfactory-external-parameter-entities-true languages: - - regex - message: A gitleaks grafana-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: External entities are allowed for $DBFACTORY. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://xml.org/sax/features/external-parameter-entities" to false. metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(eyJrIjoi[A-Za-z0-9]{70,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.grafana-cloud-api-token.grafana-cloud-api-token + - java + - xml + pattern: $DBFACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", true); + severity: ERROR + - fix: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + $FACTORY.newSAXParser(); + id: java.lang.security.audit.xxe.saxparserfactory-disallow-doctype-decl-missing.saxparserfactory-disallow-doctype-decl-missing languages: - - regex - message: A gitleaks grafana-cloud-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: DOCTYPE declarations are enabled for this SAXParserFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature `http://apache.org/xml/features/disallow-doctype-decl` to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features `http://xml.org/sax/features/external-general-entities` and `http://xml.org/sax/features/external-parameter-entities` to false. NOTE - The previous links are not meant to be clicked. They are the literal config key values that are supposed to be used to disable these features. For more information, see https://semgrep.dev/docs/cheat-sheets/java-xxe/#3a-documentbuilderfactory. metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(glc_[A-Za-z0-9+/]{32,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.grafana-service-account-token.grafana-service-account-token - languages: - - regex - message: A gitleaks grafana-service-account-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.harness-api-key.harness-api-key + - java + - xml + mode: taint + pattern-sanitizers: + - by-side-effect: true + pattern-either: + - patterns: + - pattern-either: + - pattern: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + - focus-metavariable: $FACTORY + - patterns: + - pattern-either: + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", + true); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); + ... + } + ... + } + - pattern: $M($X) + - focus-metavariable: $X + pattern-sinks: + - patterns: + - pattern: $FACTORY.newSAXParser(); + pattern-sources: + - by-side-effect: true + patterns: + - pattern-either: + - pattern: | + $FACTORY = SAXParserFactory.newInstance(); + - patterns: + - pattern: $FACTORY + - pattern-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = SAXParserFactory.newInstance(); + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + severity: ERROR + - fix: | + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + $FACTORY.newTransformer(...); + id: java.lang.security.audit.xxe.transformerfactory-dtds-not-disabled.transformerfactory-dtds-not-disabled languages: - - regex - message: A gitleaks harness-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: DOCTYPE declarations are enabled for this TransformerFactory. This is vulnerable to XML external entity attacks. Disable this by setting the attributes "accessExternalDTD" and "accessExternalStylesheet" to "". metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: ((?:pat|sat)\.[a-zA-Z0-9]{22}\.[a-zA-Z0-9]{24}\.[a-zA-Z0-9]{20}) - severity: INFO - - id: generic.secrets.gitleaks.hashicorp-tf-api-token.hashicorp-tf-api-token + - java + - xml + mode: taint + pattern-sanitizers: + - by-side-effect: true + pattern-either: + - patterns: + - pattern-either: + - pattern: | + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + - pattern: | + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + - pattern: | + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + - pattern: | + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + - focus-metavariable: $FACTORY + - patterns: + - pattern-either: + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + } + ... + } + - pattern: $M($X) + - focus-metavariable: $X + pattern-sinks: + - patterns: + - pattern: $FACTORY.newTransformer(...); + pattern-sources: + - by-side-effect: true + patterns: + - pattern-either: + - pattern: | + $FACTORY = TransformerFactory.newInstance(); + - patterns: + - pattern: $FACTORY + - pattern-inside: | + class $C { + ... + $V $FACTORY = TransformerFactory.newInstance(); + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + ... + $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + } + ... + } + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = TransformerFactory.newInstance(); + static { + ... + $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); + ... + $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); + ... + } + ... + } + severity: ERROR + - id: java.lang.security.httpservlet-path-traversal.httpservlet-path-traversal languages: - - regex - message: A gitleaks hashicorp-tf-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected a potential path traversal. A malicious actor could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.owasp.org/index.php/Path_Traversal + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70} - severity: INFO - - id: generic.secrets.gitleaks.hashicorp-tf-password.hashicorp-tf-password + - java + mode: taint + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (java.io.File $FILE) = ... + - pattern: | + (java.io.FileOutputStream $FOS) = ... + - pattern: | + new java.io.FileInputStream(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); + ... + for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { + ... + } + - pattern: | + $COOKIE.getValue(...) + - patterns: + - pattern-inside: | + $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(...); + ... + - pattern: | + $PARAM = $VALS[$INDEX]; + severity: ERROR + - id: java.lang.security.insecure-jms-deserialization.insecure-jms-deserialization languages: - - regex - message: A gitleaks hashicorp-tf-password was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: JMS Object messages depend on Java Serialization for marshalling/unmarshalling of the message payload when ObjectMessage.getObject() is called. Deserialization of untrusted data can lead to security flaws; a remote attacker could via a crafted JMS ObjectMessage to execute arbitrary code with the permissions of the application listening/consuming JMS Messages. In this case, the JMS MessageListener consume an ObjectMessage type received inside the onMessage method, which may lead to arbitrary code execution when calling the $Y.getObject method. metadata: + asvs: + control_id: 5.5.3 Insecue Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-502: Deserialization of Untrusted Data' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities-wp.pdf subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)(?:administrator_login_password|password)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}("[a-z0-9=_\-]{8,20}")(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.heroku-api-key.heroku-api-key + - pattern-inside: | + public class $JMS_LISTENER implements MessageListener { + ... + public void onMessage(Message $JMS_MSG) { + ... + } + } + - pattern-either: + - pattern-inside: $X = $Y.getObject(...); + - pattern-inside: $X = ($Z) $Y.getObject(...); + severity: WARNING + - id: java.lang.security.jackson-unsafe-deserialization.jackson-unsafe-deserialization languages: - - regex - message: A gitleaks heroku-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: When using Jackson to marshall/unmarshall JSON to Java objects, enabling default typing is dangerous and can lead to RCE. If an attacker can control `$JSON` it might be possible to provide a malicious JSON which can be used to exploit unsecure deserialization. In order to prevent this issue, avoid to enable default typing (globally or by using "Per-class" annotations) and avoid using `Object` and other dangerous types for member variable declaration which creating classes for Jackson based deserialization. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM + - 'CWE-502: Deserialization of Untrusted Data' + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A8:2017 Insecure Deserialization + - A8:2021 Software and Data Integrity Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://swapneildash.medium.com/understanding-insecure-implementation-of-jackson-deserialization-7b3d409d2038 + - https://cowtowncoder.medium.com/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062 + - https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/ subcategory: - - vuln + - audit technology: - - gitleaks + - jackson patterns: - - pattern-regex: (?i)(?:heroku)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.hubspot-api-key.hubspot-api-key + - pattern-either: + - patterns: + - pattern-inside: | + ObjectMapper $OM = new ObjectMapper(...); + ... + - pattern-inside: | + $OM.enableDefaultTyping(); + ... + - pattern: $OM.readValue($JSON, ...); + - patterns: + - pattern-inside: | + class $CLASS { + ... + @JsonTypeInfo(use = Id.CLASS,...) + $TYPE $VAR; + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: (Object|Serializable|Comparable) + - pattern: $OM.readValue($JSON, $CLASS.class); + - patterns: + - pattern-inside: | + class $CLASS { + ... + ObjectMapper $OM; + ... + $INITMETHODTYPE $INITMETHOD(...) { + ... + $OM = new ObjectMapper(); + ... + $OM.enableDefaultTyping(); + ... + } + ... + } + - pattern-inside: "$METHODTYPE $METHOD(...) {\n ... \n}\n" + - pattern: $OM.readValue($JSON, ...); + severity: WARNING + - id: java.lang.security.servletresponse-writer-xss.servletresponse-writer-xss languages: - - regex - message: A gitleaks hubspot-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: 'Cross-site scripting detected in HttpServletResponse writer with variable ''$VAR''. User input was detected going directly from the HttpServletRequest into output. Ensure your data is properly encoded using org.owasp.encoder.Encode.forHtml: ''Encode.forHtml($VAR)''.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#XSS_SERVLET subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?i)(?:hubspot)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.huggingface-access-token.huggingface-access-token + - pattern-inside: $TYPE $FUNC(..., HttpServletResponse $RESP, ...) { ... } + - pattern-inside: $VAR = $REQ.getParameter(...); ... + - pattern-either: + - pattern: $RESP.getWriter(...).write(..., $VAR, ...); + - pattern: | + $WRITER = $RESP.getWriter(...); + ... + $WRITER.write(..., $VAR, ...); + severity: ERROR + - id: java.lang.security.xmlinputfactory-possible-xxe.xmlinputfactory-possible-xxe languages: - - regex - message: A gitleaks huggingface-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: XML external entities are not explicitly disabled for this XMLInputFactory. This could be vulnerable to XML external entity vulnerabilities. Explicitly disable external entities by setting "javax.xml.stream.isSupportingExternalEntities" to false. metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#xmlinputfactory-a-stax-parser subcategory: - vuln technology: - - gitleaks + - java patterns: - - pattern-regex: (?:^|[\\'"` >=:])(hf_[a-zA-Z]{34})(?:$|[\\'"` <]) - severity: INFO - - id: generic.secrets.gitleaks.huggingface-organization-api-token.huggingface-organization-api-token + - pattern-not-inside: | + $METHOD(...) { + ... + $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", false); + ... + } + - pattern-not-inside: | + $METHOD(...) { + ... + $XMLFACTORY.setProperty(javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); + ... + } + - pattern-not-inside: | + $METHOD(...) { + ... + $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", Boolean.FALSE); + ... + } + - pattern-not-inside: | + $METHOD(...) { + ... + $XMLFACTORY.setProperty(javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); + ... + } + - pattern-either: + - pattern: javax.xml.stream.XMLInputFactory.newFactory(...) + - pattern: new XMLInputFactory(...) + severity: WARNING + - id: java.spring.security.audit.spring-actuator-fully-enabled-yaml.spring-actuator-fully-enabled-yaml languages: - - regex - message: A gitleaks huggingface-organization-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?:^|[\\'"` >=:\(,)])(api_org_[a-zA-Z]{34})(?:$|[\\'"` <\),]) - severity: INFO - - id: generic.secrets.gitleaks.infracost-api-token.infracost-api-token - languages: - - regex - message: A gitleaks infracost-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - yaml + message: Spring Boot Actuator is fully enabled. This exposes sensitive endpoints such as /actuator/env, /actuator/logfile, /actuator/heapdump and others. Unless you have Spring Security enabled or another means to protect these endpoints, this functionality is available without authentication, causing a severe security risk. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints + - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 + - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators subcategory: - vuln technology: - - gitleaks + - spring patterns: - - pattern-regex: (?i)\b(ico-[a-zA-Z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.intercom-api-key.intercom-api-key + - pattern-inside: | + management: + ... + endpoints: + ... + web: + ... + exposure: + ... + - pattern: | + include: "*" + severity: WARNING + - id: java.spring.security.audit.spring-actuator-fully-enabled.spring-actuator-fully-enabled languages: - - regex - message: A gitleaks intercom-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - generic + message: Spring Boot Actuator is fully enabled. This exposes sensitive endpoints such as /actuator/env, /actuator/logfile, /actuator/heapdump and others. Unless you have Spring Security enabled or another means to protect these endpoints, this functionality is available without authentication, causing a significant security risk. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints + - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 + - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:intercom)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{60})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.intra42-client-secret.intra42-client-secret + - spring + paths: + include: + - '*properties' + pattern: management.endpoints.web.exposure.include=* + severity: ERROR + - id: java.spring.security.audit.spring-actuator-non-health-enabled-yaml.spring-actuator-dangerous-endpoints-enabled-yaml languages: - - regex - message: A gitleaks intra42-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - yaml + message: Spring Boot Actuator "$ACTUATOR" is enabled. Depending on the actuator, this can pose a significant security risk. Please double-check if the actuator is needed and properly secured. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints + - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 + - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators subcategory: - vuln technology: - - gitleaks + - spring patterns: - - pattern-regex: (?i)\b(s-s4t2(?:ud|af)-[abcdef0123456789]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.jfrog-api-key.jfrog-api-key + - pattern-inside: | + management: + ... + endpoints: + ... + web: + ... + exposure: + ... + include: + ... + - pattern: | + include: [..., $ACTUATOR, ...] + - metavariable-comparison: + comparison: not str($ACTUATOR) in ["health","*"] + metavariable: $ACTUATOR + severity: WARNING + - id: java.spring.security.audit.spring-actuator-non-health-enabled.spring-actuator-dangerous-endpoints-enabled languages: - - regex - message: A gitleaks jfrog-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - generic + message: Spring Boot Actuators "$...ACTUATORS" are enabled. Depending on the actuators, this can pose a significant security risk. Please double-check if the actuators are needed and properly secured. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints + - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 + - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators subcategory: - vuln technology: - - gitleaks + - spring + options: + generic_ellipsis_max_span: 0 patterns: - - pattern-regex: (?i)(?:jfrog|artifactory|bintray|xray)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{73})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.jfrog-identity-token.jfrog-identity-token + - pattern: management.endpoints.web.exposure.include=$...ACTUATORS + - metavariable-comparison: + comparison: not str($...ACTUATORS) in ["health","*"] + metavariable: $...ACTUATORS + severity: WARNING + - id: java.spring.security.audit.spring-sqli.spring-sqli languages: - - regex - message: A gitleaks jfrog-identity-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected a string argument from a public method contract in a raw SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:jfrog|artifactory|bintray|xray)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.jwt-base64.jwt-base64 + - spring + mode: taint + options: + taint_assume_safe_booleans: true + taint_assume_safe_numbers: true + pattern-sanitizers: + - not_conflicting: true + pattern-either: + - patterns: + - focus-metavariable: $A + - pattern-inside: | + new $TYPE(...,$A,...); + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - focus-metavariable: $A + - pattern: | + new PreparedStatementCreatorFactory($A,...); + - patterns: + - focus-metavariable: $A + - pattern: | + (JdbcTemplate $T).$M($A,...) + - patterns: + - pattern: (String $A) + - pattern-inside: | + (JdbcTemplate $T).batchUpdate(...) + - patterns: + - focus-metavariable: $A + - pattern: | + NamedParameterBatchUpdateUtils.$M($A,...) + - patterns: + - focus-metavariable: $A + - pattern: | + BatchUpdateUtils.$M($A,...) + pattern-sources: + - patterns: + - pattern: $ARG + - pattern-inside: | + public $T $M (..., String $ARG,...){...} + severity: WARNING + - id: java.spring.security.audit.spring-unvalidated-redirect.spring-unvalidated-redirect languages: - - regex - message: A gitleaks jwt-base64 was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Application redirects a user to a destination URL specified by a user supplied parameter that is not validated. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNVALIDATED_REDIRECT subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: \bZXlK(?:(?PaGJHY2lPaU)|(?PaGNIVWlPaU)|(?PaGNIWWlPaU)|(?PaGRXUWlPaU)|(?PaU5qUWlP)|(?PamNtbDBJanBi)|(?PamRIa2lPaU)|(?PbGNHc2lPbn)|(?PbGJtTWlPaU)|(?PcWEzVWlPaU)|(?PcWQyc2lPb)|(?PcGMzTWlPaU)|(?PcGRpSTZJ)|(?PcmFXUWlP)|(?PclpYbGZiM0J6SWpwY)|(?PcmRIa2lPaUp)|(?PdWIyNWpaU0k2)|(?Pd01tTWlP)|(?Pd01uTWlPaU)|(?Pd2NIUWlPaU)|(?PemRXSWlPaU)|(?PemRuUWlP)|(?PMFlXY2lPaU)|(?PMGVYQWlPaUp)|(?PMWNtd2l)|(?PMWMyVWlPaUp)|(?PMlpYSWlPaU)|(?PMlpYSnphVzl1SWpv)|(?PNElqb2)|(?PNE5XTWlP)|(?PNE5YUWlPaU)|(?PNE5YUWpVekkxTmlJNkl)|(?PNE5YVWlPaU)|(?PNmFYQWlPaU))[a-zA-Z0-9\/\\_+\-\r\n]{40,}={0,2} - severity: INFO - - id: generic.secrets.gitleaks.jwt.jwt + - spring + pattern-either: + - pattern: | + $X $METHOD(...,String $URL,...) { + return "redirect:" + $URL; + } + - pattern: | + $X $METHOD(...,String $URL,...) { + ... + String $REDIR = "redirect:" + $URL; + ... + return $REDIR; + ... + } + - pattern: | + $X $METHOD(...,String $URL,...) { + ... + new ModelAndView("redirect:" + $URL); + ... + } + - pattern: |- + $X $METHOD(...,String $URL,...) { + ... + String $REDIR = "redirect:" + $URL; + ... + new ModelAndView($REDIR); + ... + } + severity: WARNING + - id: java.spring.security.injection.tainted-file-path.tainted-file-path languages: - - regex - message: A gitleaks jwt was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected user input controlling a file path. An attacker could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + - 'CWE-23: Relative Path Traversal' + impact: HIGH + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/www-community/attacks/Path_Traversal subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: \b(ey[a-zA-Z0-9]{17,}\.ey[a-zA-Z0-9\/\\_-]{17,}\.(?:[a-zA-Z0-9\/\\_-]{10,}={0,2})?)(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.kraken-access-token.kraken-access-token + - java + - spring + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: new File(...) + - pattern: new java.io.File(...) + - pattern: new FileReader(...) + - pattern: new java.io.FileReader(...) + - pattern: new FileInputStream(...) + - pattern: new java.io.FileInputStream(...) + - pattern: (Paths $PATHS).get(...) + - patterns: + - pattern: | + $CLASS.$FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: ^(getResourceAsStream|getResource)$ + - patterns: + - pattern-either: + - pattern: new ClassPathResource($FILE, ...) + - pattern: ResourceUtils.getFile($FILE, ...) + - pattern: new FileOutputStream($FILE, ...) + - pattern: new java.io.FileOutputStream($FILE, ...) + - pattern: new StreamSource($FILE, ...) + - pattern: new javax.xml.transform.StreamSource($FILE, ...) + - pattern: FileUtils.openOutputStream($FILE, ...) + - focus-metavariable: $FILE + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + severity: ERROR + - id: java.spring.security.injection.tainted-html-string.tainted-html-string languages: - - regex - message: A gitleaks kraken-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. You can use the OWASP ESAPI encoder if you must render user data. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:kraken)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9\/=_\+\-]{80,90})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.kucoin-access-token.kucoin-access-token + - java + - spring + mode: taint + pattern-propagators: + - from: $...TAINTED + pattern: (StringBuilder $SB).append($...TAINTED) + to: $SB + - from: $...TAINTED + pattern: $VAR += $...TAINTED + to: $VAR + pattern-sanitizers: + - pattern-either: + - pattern: Encode.forHtml(...) + - pattern: (PolicyFactory $POLICY).sanitize(...) + - pattern: (AntiSamy $AS).scan(...) + - pattern: JSoup.clean(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: new ResponseEntity<>($PAYLOAD, ...) + - pattern: new ResponseEntity<$ERROR>($PAYLOAD, ...) + - pattern: ResponseEntity. ... .body($PAYLOAD) + - patterns: + - pattern: | + ResponseEntity.$RESPFUNC($PAYLOAD). ... + - metavariable-regex: + metavariable: $RESPFUNC + regex: ^(ok|of)$ + - focus-metavariable: $PAYLOAD + requires: CONCAT + pattern-sources: + - label: INPUT + patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + - by-side-effect: true + label: CONCAT + patterns: + - pattern-either: + - pattern: | + "$HTMLSTR" + ... + - pattern: | + "$HTMLSTR".concat(...) + - patterns: + - pattern-inside: | + StringBuilder $SB = new StringBuilder("$HTMLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$HTMLSTR"; + ... + - pattern: $VAR += ... + - pattern: String.format("$HTMLSTR", ...) + - patterns: + - pattern-inside: | + String $VAR = "$HTMLSTR"; + ... + - pattern: String.format($VAR, ...) + - metavariable-regex: + metavariable: $HTMLSTR + regex: ^<\w+ + requires: INPUT + severity: ERROR + - id: java.spring.security.injection.tainted-sql-string.tainted-sql-string languages: - - regex - message: A gitleaks kucoin-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.kucoin-secret-key.kucoin-secret-key + - spring + mode: taint + options: + interfile: true + taint_assume_safe_booleans: true + taint_assume_safe_numbers: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR".concat(...) + - patterns: + - pattern-inside: | + StringBuilder $SB = new StringBuilder("$SQLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$SQLSTR"; + ... + - pattern: $VAR += ... + - pattern: String.format("$SQLSTR", ...) + - patterns: + - pattern-inside: | + String $VAR = "$SQLSTR"; + ... + - pattern: String.format($VAR, ...) + - pattern-not-inside: System.out.println(...) + - pattern-not-inside: $LOG.info(...) + - pattern-not-inside: $LOG.warn(...) + - pattern-not-inside: $LOG.warning(...) + - pattern-not-inside: $LOG.debug(...) + - pattern-not-inside: $LOG.debugging(...) + - pattern-not-inside: $LOG.error(...) + - pattern-not-inside: new Exception(...) + - pattern-not-inside: throw ...; + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue) + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - focus-metavariable: $SOURCE + severity: ERROR + - id: java.spring.security.injection.tainted-system-command.tainted-system-command languages: - - regex - message: A gitleaks kucoin-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - java + message: 'Detected user input entering a method which executes a system command. This could result in a command injection vulnerability, which allows an attacker to inject an arbitrary system command onto the server. The attacker could download malware onto or steal data from the server. Instead, use ProcessBuilder, separating the command into individual arguments, like this: `new ProcessBuilder("ls", "-al", targetDirectory)`. Further, make sure you hardcode or allowlist the actual command so that attackers can''t run arbitrary commands.' metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.stackhawk.com/blog/command-injection-java/ + - https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html + - https://github.com/github/codeql/blob/main/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.java subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.launchdarkly-access-token.launchdarkly-access-token - languages: - - regex - message: A gitleaks launchdarkly-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - java + - spring + mode: taint + pattern-propagators: + - from: $INPUT + label: CONCAT + pattern: (StringBuilder $STRB).append($INPUT) + requires: INPUT + to: $STRB + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + (Process $P) = new Process(...); + - pattern: | + (ProcessBuilder $PB).command(...); + - patterns: + - pattern-either: + - pattern: | + (Runtime $R).$EXEC(...); + - pattern: | + Runtime.getRuntime(...).$EXEC(...); + - metavariable-regex: + metavariable: $EXEC + regex: (exec|loadLibrary|load) + - patterns: + - pattern: | + (ProcessBuilder $PB).command(...).$ADD(...); + - metavariable-regex: + metavariable: $ADD + regex: (add|addAll) + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $BUILDER = new ProcessBuilder(...); + ... + - pattern: $BUILDER.start(...) + - pattern: | + new ProcessBuilder(...). ... .start(...); + requires: CONCAT + pattern-sources: + - label: INPUT + patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + - label: CONCAT + patterns: + - pattern-either: + - pattern: $X + $SOURCE + - pattern: $SOURCE + $Y + - pattern: String.format("...", ..., $SOURCE, ...) + - pattern: String.join("...", ..., $SOURCE, ...) + - pattern: (String $STR).concat($SOURCE) + - pattern: $SOURCE.concat(...) + - pattern: $X += $SOURCE + - pattern: $SOURCE += $X + requires: INPUT + severity: ERROR + - id: java.spring.security.injection.tainted-url-host.tainted-url-host + languages: + - java + message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, hardcode the correct host, or ensure that the user data can only affect the path or parameters. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A10:2021 - Server-Side Request Forgery (SSRF) references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:launchdarkly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.linear-api-key.linear-api-key + - java + - spring + mode: taint + options: + interfile: true + pattern-sinks: + - pattern-either: + - pattern: new URL($ONEARG) + - patterns: + - pattern-either: + - pattern: | + "$URLSTR" + ... + - pattern: | + "$URLSTR".concat(...) + - patterns: + - pattern-inside: | + StringBuilder $SB = new StringBuilder("$URLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$URLSTR"; + ... + - pattern: $VAR += ... + - patterns: + - pattern: String.format("$URLSTR", ...) + - pattern-not: String.format("$URLSTR", "...", ...) + - patterns: + - pattern-inside: | + String $VAR = "$URLSTR"; + ... + - pattern: String.format($VAR, ...) + - metavariable-regex: + metavariable: $URLSTR + regex: http(s?)://%(v|s|q).* + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + severity: ERROR + - id: javascript.angular.security.detect-angular-element-taint.detect-angular-element-taint languages: - - regex - message: A gitleaks linear-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Use of angular.element can lead to XSS if user-input is treated as part of the HTML element within `$SINK`. It is recommended to contextually output encode user-input, before inserting into `$SINK`. If the HTML needs to be preserved it is recommended to sanitize the input using $sce.getTrustedHTML or $sanitize. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://docs.angularjs.org/api/ng/function/angular.element + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: lin_api_(?i)[a-z0-9]{40} - severity: INFO - - id: generic.secrets.gitleaks.linear-client-secret.linear-client-secret + - angularjs + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: $sce.getTrustedHtml(...) + - pattern: $sanitize(...) + - pattern: DOMPurify.sanitize(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + angular.element(...). ... .$SINK($QUERY) + - pattern-inside: | + $ANGULAR = angular.element(...) + ... + $ANGULAR. ... .$SINK($QUERY) + - metavariable-regex: + metavariable: $SINK + regex: ^(after|append|html|prepend|replaceWith|wrap)$ + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-either: + - pattern: window.location.search + - pattern: window.document.location.search + - pattern: document.location.search + - pattern: location.search + - pattern: $location.search(...) + - patterns: + - pattern-either: + - pattern: $DECODE(<... location.hash ...>) + - pattern: $DECODE(<... window.location.hash ...>) + - pattern: $DECODE(<... document.location.hash ...>) + - pattern: $DECODE(<... location.href ...>) + - pattern: $DECODE(<... window.location.href ...>) + - pattern: $DECODE(<... document.location.href ...>) + - pattern: $DECODE(<... document.URL ...>) + - pattern: $DECODE(<... window.document.URL ...>) + - pattern: $DECODE(<... document.location.href ...>) + - pattern: $DECODE(<... document.location.href ...>) + - pattern: $DECODE(<... $location.absUrl() ...>) + - pattern: $DECODE(<... $location.url() ...>) + - pattern: $DECODE(<... $location.hash() ...>) + - metavariable-regex: + metavariable: $DECODE + regex: ^(unescape|decodeURI|decodeURIComponent)$ + - patterns: + - pattern-inside: $http.$METHOD(...).$CONTINUE(function $FUNC($RES) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|delete|head|jsonp|post|put|patch) + - pattern: $RES.data + severity: WARNING + - id: javascript.angular.security.detect-angular-sce-disabled.detect-angular-sce-disabled languages: - - regex - message: A gitleaks linear-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: $sceProvider is set to false. Disabling Strict Contextual escaping (SCE) in an AngularJS application could provide additional attack surface for XSS vulnerabilities. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://docs.angularjs.org/api/ng/service/$sce + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:linear)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.linkedin-client-id.linkedin-client-id + - angular + pattern: | + $sceProvider.enabled(false); + severity: ERROR + - id: javascript.angular.security.detect-angular-trust-as-method.detect-angular-trust-as-method languages: - - regex - message: A gitleaks linkedin-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: The use of $sce.trustAs can be dangerous if unsanitized user input flows through this API. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://docs.angularjs.org/api/ng/service/$sce + - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{14})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.linkedin-client-secret.linkedin-client-secret + - angular + mode: taint + pattern-sinks: + - pattern: $sce.trustAs(...) + - pattern: $sce.trustAsHtml(...) + pattern-sources: + - patterns: + - pattern-inside: | + app.controller(..., function($scope,$sce) { + ... + }); + - pattern: $scope.$X + severity: WARNING + - id: javascript.argon2.security.unsafe-argon2-config.unsafe-argon2-config languages: - - regex - message: A gitleaks linkedin-client-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Prefer Argon2id where possible. Per RFC9016, section 4 IETF recommends selecting Argon2id unless you can guarantee an adversary has no direct access to the computing environment. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + - 'CWE-916: Use of Password Hash With Insufficient Computational Effort' + impact: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + - https://eprint.iacr.org/2016/759.pdf + - https://www.cs.tau.ac.il/~tromer/papers/cache-joc-20090619.pdf + - https://datatracker.ietf.org/doc/html/rfc9106#section-4 subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.lob-api-key.lob-api-key + - argon2 + - cryptography + mode: taint + pattern-sanitizers: + - patterns: + - pattern: | + {type: $ARGON.argon2id} + ... + pattern-sinks: + - patterns: + - pattern: | + $Y + - pattern-inside: | + $ARGON.hash(...,$Y) + pattern-sources: + - patterns: + - pattern-inside: | + $ARGON = require('argon2'); + ... + - pattern: | + {type: ...} + severity: WARNING + - id: javascript.aws-lambda.security.detect-child-process.detect-child-process languages: - - regex - message: A gitleaks lob-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Allowing spawning arbitrary programs or running shell processes with arbitrary arguments may end up in a command injection vulnerability. Try to avoid non-literal values for the command string. If it is not possible, then do not let running arbitrary commands, use a white list for inputs. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}((live|test)_[a-f0-9]{35})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.lob-pub-api-key.lob-pub-api-key + - javascript + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $CMD + - pattern-either: + - pattern: exec($CMD,...) + - pattern: execSync($CMD,...) + - pattern: spawn($CMD,...) + - pattern: spawnSync($CMD,...) + - pattern: $CP.exec($CMD,...) + - pattern: $CP.execSync($CMD,...) + - pattern: $CP.spawn($CMD,...) + - pattern: $CP.spawnSync($CMD,...) + - pattern-either: + - pattern-inside: | + require('child_process') + ... + - pattern-inside: | + import 'child_process' + ... + pattern-sources: + - patterns: + - pattern: $EVENT + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + severity: ERROR + - id: javascript.aws-lambda.security.dynamodb-request-object.dynamodb-request-object languages: - - regex - message: A gitleaks lob-pub-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected DynamoDB query params that are tainted by `$EVENT` object. This could lead to NoSQL injection if the variable is user-controlled and not properly sanitized. Explicitly assign query params instead of passing data from `$EVENT` directly to DynamoDB client. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + - 'CWE-943: Improper Neutralization of Special Elements in Data Query Logic' + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}((test|live)_pub_[a-f0-9]{31})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.mailchimp-api-key.mailchimp-api-key + - javascript + - aws-lambda + - dynamodb + mode: taint + pattern-sanitizers: + - patterns: + - pattern: | + {...} + pattern-sinks: + - patterns: + - focus-metavariable: $SINK + - pattern: | + $DC.$METHOD($SINK, ...) + - metavariable-regex: + metavariable: $METHOD + regex: (query|send|scan|delete|put|transactWrite|update|batchExecuteStatement|executeStatement|executeTransaction|transactWriteItems) + - pattern-either: + - pattern-inside: | + $DC = new $AWS.DocumentClient(...); + ... + - pattern-inside: | + $DC = new $AWS.DynamoDB(...); + ... + - pattern-inside: | + $DC = new DynamoDBClient(...); + ... + - pattern-inside: | + $DC = DynamoDBDocumentClient.from(...); + ... + pattern-sources: + - patterns: + - pattern: $EVENT + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + severity: ERROR + - id: javascript.aws-lambda.security.knex-sqli.knex-sqli languages: - - regex - message: A gitleaks mailchimp-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `knex.raw(''SELECT $1 from table'', [userinput])`' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://knexjs.org/#Builder-fromRaw + - https://knexjs.org/#Builder-whereRaw subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:MailchimpSDK.initialize|mailchimp)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32}-us\d\d)(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.mailgun-private-api-token.mailgun-private-api-token + - aws-lambda + - knex + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern: $KNEX.fromRaw($QUERY, ...) + - pattern: $KNEX.whereRaw($QUERY, ...) + - pattern: $KNEX.raw($QUERY, ...) + - pattern-either: + - pattern-inside: | + require('knex') + ... + - pattern-inside: | + import 'knex' + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.mysql-sqli.mysql-sqli languages: - - regex - message: A gitleaks mailgun-private-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `connection.query(''SELECT $1 from table'', [userinput])`' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.npmjs.com/package/mysql2 subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(key-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.mailgun-pub-key.mailgun-pub-key - languages: - - regex - message: A gitleaks mailgun-pub-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(pubkey-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.mailgun-signing-key.mailgun-signing-key - languages: - - regex - message: A gitleaks mailgun-signing-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.mapbox-api-token.mapbox-api-token + - aws-lambda + - mysql + - mysql2 + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern: $POOL.query($QUERY, ...) + - pattern: $POOL.execute($QUERY, ...) + - pattern-either: + - pattern-inside: | + require('mysql') + ... + - pattern-inside: | + require('mysql2') + ... + - pattern-inside: | + require('mysql2/promise') + ... + - pattern-inside: | + import 'mysql' + ... + - pattern-inside: | + import 'mysql2' + ... + - pattern-inside: | + import 'mysql2/promise' + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.pg-sqli.pg-sqli languages: - - regex - message: A gitleaks mapbox-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `connection.query(''SELECT $1 from table'', [userinput])`' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://node-postgres.com/features/queries subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:mapbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(pk\.[a-z0-9]{60}\.[a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.mattermost-access-token.mattermost-access-token + - aws-lambda + - postgres + - pg + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern: $DB.query($QUERY, ...) + - pattern-either: + - pattern-inside: | + require('pg') + ... + - pattern-inside: | + import 'pg' + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.sequelize-sqli.sequelize-sqli languages: - - regex - message: A gitleaks mattermost-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `sequelize.query(''SELECT * FROM projects WHERE status = ?'', { replacements: [''active''], type: QueryTypes.SELECT });`' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://sequelize.org/master/manual/raw-queries.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:mattermost)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{26})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.messagebird-api-token.messagebird-api-token + - aws-lambda + - sequelize + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern: $DB.query($QUERY, ...) + - pattern-either: + - pattern-inside: | + require('sequelize') + ... + - pattern-inside: | + import 'sequelize' + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.tainted-html-response.tainted-html-response languages: - - regex - message: A gitleaks messagebird-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected user input flowing into an HTML response. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.messagebird-client-id.messagebird-client-id + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $BODY + - pattern-inside: | + {..., headers: {..., 'Content-Type': 'text/html', ...}, body: $BODY, ... } + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.tainted-html-string.tainted-html-string languages: - - regex - message: A gitleaks messagebird-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates which will safely render HTML instead. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.microsoft-teams-webhook.microsoft-teams-webhook + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + "$HTMLSTR" + $EXPR + - pattern: | + "$HTMLSTR".concat(...) + - pattern: $UTIL.format($HTMLSTR, ...) + - pattern: format($HTMLSTR, ...) + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... + - patterns: + - pattern: | + `...${...}...` + - pattern-regex: | + .*<\w+.* + - pattern-not-inside: | + console.$LOG(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: WARNING + - id: javascript.aws-lambda.security.tainted-sql-string.tainted-sql-string languages: - - regex - message: A gitleaks microsoft-teams-webhook was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/www-community/attacks/SQL_Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: https:\/\/[a-z0-9]+\.webhook\.office\.com\/webhookb2\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12} - severity: INFO - - id: generic.secrets.gitleaks.netlify-access-token.netlify-access-token + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + $EXPR + - pattern: | + "$SQLSTR".concat(...) + - pattern: util.format($SQLSTR, ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - patterns: + - pattern: | + `...${...}...` + - pattern-regex: | + .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - pattern-not-inside: | + console.$LOG(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern: $EVENT + severity: ERROR + - id: javascript.aws-lambda.security.vm-runincontext-injection.vm-runincontext-injection languages: - - regex - message: A gitleaks netlify-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: The `vm` module enables compiling and running code within V8 Virtual Machine contexts. The `vm` module is not a security mechanism. Do not use it to run untrusted code. If code passed to `vm` functions is controlled by user input it could result in command injection. Do not let user input in `vm` functions. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:netlify)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40,46})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.new-relic-browser-api-token.new-relic-browser-api-token + - javascript + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('vm'); + ... + - pattern-inside: | + import 'vm' + ... + - pattern-either: + - pattern: $VM.runInContext($X,...) + - pattern: $VM.runInNewContext($X,...) + - pattern: $VM.runInThisContext($X,...) + - pattern: $VM.compileFunction($X,...) + - pattern: new $VM.Script($X,...) + - pattern: new $VM.SourceTextModule($X,...) + - pattern: runInContext($X,...) + - pattern: runInNewContext($X,...) + - pattern: runInThisContext($X,...) + - pattern: compileFunction($X,...) + - pattern: new Script($X,...) + - pattern: new SourceTextModule($X,...) + pattern-sources: + - patterns: + - pattern: $EVENT + - pattern-either: + - pattern-inside: | + exports.handler = function ($EVENT, ...) { + ... + } + - pattern-inside: | + function $FUNC ($EVENT, ...) {...} + ... + exports.handler = $FUNC + - pattern-inside: | + $FUNC = function ($EVENT, ...) {...} + ... + exports.handler = $FUNC + severity: ERROR + - id: javascript.browser.security.open-redirect.js-open-redirect languages: - - regex - message: A gitleaks new-relic-browser-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: The application accepts potentially user-controlled input `$PROP` which can control the location of the current window context. This can lead two types of vulnerabilities open-redirection and Cross-Site-Scripting (XSS) with JavaScript URIs. It is recommended to validate user-controllable input before allowing it to control the redirection. metadata: + asvs: + control_id: 5.5.1 Insecue Redirect + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' impact: MEDIUM - likelihood: LOW + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRJS-[a-f0-9]{19})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.new-relic-insert-key.new-relic-insert-key + - browser + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: location.href = $SINK + - pattern: $THIS. ... .location.href = $SINK + - pattern: location.replace($SINK) + - pattern: $THIS. ... .location.replace($SINK) + - pattern: location = $SINK + - pattern: $WINDOW. ... .location = $SINK + - focus-metavariable: $SINK + - metavariable-pattern: + metavariable: $SINK + patterns: + - pattern-not: | + "..." + $VALUE + - pattern-not: | + `...${$VALUE}` + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $PROP = new URLSearchParams($WINDOW. ... .location.search).get('...') + ... + - pattern-inside: | + $PROP = new URLSearchParams(location.search).get('...') + ... + - pattern-inside: | + $PROP = new URLSearchParams($WINDOW. ... .location.hash.substring(1)).get('...') + ... + - pattern-inside: | + $PROP = new URLSearchParams(location.hash.substring(1)).get('...') + ... + - pattern: $PROP + - patterns: + - pattern-either: + - pattern-inside: | + $PROPS = new URLSearchParams($WINDOW. ... .location.search) + ... + - pattern-inside: | + $PROPS = new URLSearchParams(location.search) + ... + - pattern-inside: | + $PROPS = new URLSearchParams($WINDOW. ... .location.hash.substring(1)) + ... + - pattern-inside: | + $PROPS = new URLSearchParams(location.hash.substring(1)) + ... + - pattern: $PROPS.get('...') + - patterns: + - pattern-either: + - pattern-inside: | + $PROPS = new URL($WINDOW. ... .location.href) + ... + - pattern-inside: | + $PROPS = new URL(location.href) + ... + - pattern: $PROPS.searchParams.get('...') + - patterns: + - pattern-either: + - pattern-inside: | + $PROPS = new URL($WINDOW. ... .location.href).searchParams.get('...') + ... + - pattern-inside: | + $PROPS = new URL(location.href).searchParams.get('...') + ... + - pattern: $PROPS + severity: WARNING + - id: javascript.browser.security.raw-html-concat.raw-html-concat languages: - - regex - message: A gitleaks new-relic-insert-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: User controlled data in a HTML string may result in XSS metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/www-community/attacks/xss/ subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRII-[a-z0-9-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.new-relic-user-api-id.new-relic-user-api-id - languages: - - regex - message: A gitleaks new-relic-user-api-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.new-relic-user-api-key.new-relic-user-api-key - languages: - - regex - message: A gitleaks new-relic-user-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRAK-[a-z0-9]{27})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.npm-access-token.npm-access-token + - browser + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + $S = new Remarkable() + ... + - pattern: $S.render(...) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: $STRING + $EXPR + - pattern-not: $STRING + "..." + - metavariable-pattern: + language: generic + metavariable: $STRING + patterns: + - pattern: <$TAG ... + - pattern-not: <$TAG ...>...... + - patterns: + - pattern: $EXPR + $STRING + - pattern-not: '"..." + $STRING' + - metavariable-pattern: + language: generic + metavariable: $STRING + patterns: + - pattern: '... |:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.okta-access-token.okta-access-token + - chrome-remote-interface + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('chrome-remote-interface'); + ... + - pattern-inside: | + import 'chrome-remote-interface'; + ... + - pattern-either: + - pattern: | + $RUNTIME.compileScript({expression: $SINK},...) + - pattern: | + $RUNTIME.evaluate({expression: $SINK},...) + - pattern: | + $PAGE.navigate({url: $SINK},...) + - pattern: | + $RUNTIME.printToPDF({headerTemplate: $SINK},...) + - pattern: | + $RUNTIME.printToPDF({footerTemplate: $SINK},...) + - pattern: | + $PAGE.setDocumentContent({html: $SINK},...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-inside: function ... (..., $ARG,...) {...} + - focus-metavariable: $ARG + severity: WARNING + - id: javascript.deno.security.audit.deno-dangerous-run.deno-dangerous-run languages: - - regex - message: A gitleaks okta-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected non-literal calls to Deno.run(). This could lead to a command injection vulnerability. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://deno.land/manual/examples/subprocess#simple-example subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:okta)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{42})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.openai-api-key.openai-api-key + - deno + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + Deno.run({cmd: [$INPUT,...]},...) + - pattern: | + Deno.run({cmd: ["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$INPUT,...]},...) + - patterns: + - pattern: | + Deno.run({cmd: [$CMD,"-c",$INPUT,...]},...) + - pattern-inside: | + $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/" + ... + - focus-metavariable: $INPUT + pattern-sources: + - patterns: + - pattern-inside: function ... (..., $ARG,...) {...} + - focus-metavariable: $ARG + severity: ERROR + - id: javascript.express.security.audit.express-check-directory-listing.express-check-directory-listing languages: - - regex - message: A gitleaks openai-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Directory listing/indexing is enabled, which may lead to disclosure of sensitive directories and files. It is recommended to disable directory listing unless it is a public resource. If you need directory listing, ensure that sensitive files are inaccessible when querying the resource. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-548: Exposure of Information Through Directory Listing' impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A06:2017 - Security Misconfiguration + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.npmjs.com/package/serve-index + - https://www.acunetix.com/blog/articles/directory-listing-information-disclosure/ subcategory: - vuln technology: - - gitleaks + - express + options: + interfile: true patterns: - - pattern-regex: (?i)\b(sk-[a-zA-Z0-9]{20}T3BlbkFJ[a-zA-Z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.plaid-api-token.plaid-api-token + - pattern-either: + - pattern: | + $APP.use(require('serve-index')(...)) + - patterns: + - pattern-either: + - pattern-inside: | + $SERVEINDEX = require('serve-index') + ... + - pattern-inside: | + import $SERVEINDEX from 'serve-index' + ... + - pattern-inside: | + import * as $SERVEINDEX from 'serve-index' + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $SERVEINDEX(...) + ... + - pattern: | + $VALUE(...) + - pattern: | + $APP.use(..., $SERVEINDEX(...), ...) + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-default-name languages: - - regex - message: A gitleaks plaid-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Don’t use the default session cookie name Using the default session cookie name can open your app to attacks. The security issue posed is similar to X-Powered-By: a potential attacker can use it to fingerprint the server and target attacks accordingly.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-522: Insufficiently Protected Credentials' cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html subcategory: - vuln technology: - - gitleaks + - express patterns: - - pattern-regex: (?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(access-(?:sandbox|development|production)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.plaid-client-id.plaid-client-id + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {name:...} ...>,...) + - pattern-not-inside: | + $OPTS = <... {name:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.name = ...; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-secure languages: - - regex - message: A gitleaks plaid-client-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Default session middleware settings: `secure` not set. It ensures the browser only sends the cookie over HTTPS.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-522: Insufficiently Protected Credentials' cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html subcategory: - vuln technology: - - gitleaks + - express patterns: - - pattern-regex: (?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.plaid-secret-key.plaid-secret-key + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{secure:true}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{secure:true}} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {secure:true} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {secure:true} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.secure = true; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.secure = true; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-httponly languages: - - regex - message: A gitleaks plaid-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Default session middleware settings: `httpOnly` not set. It ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-522: Insufficiently Protected Credentials' cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html subcategory: - vuln technology: - - gitleaks + - express patterns: - - pattern-regex: (?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.planetscale-api-token.planetscale-api-token + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{httpOnly:true}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{httpOnly:true}} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {httpOnly:true} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {httpOnly:true} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.httpOnly = true; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.httpOnly = true; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-domain languages: - - regex - message: A gitleaks planetscale-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Default session middleware settings: `domain` not set. It indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-522: Insufficiently Protected Credentials' cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html subcategory: - vuln technology: - - gitleaks + - express patterns: - - pattern-regex: (?i)\b(pscale_tkn_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.planetscale-oauth-token.planetscale-oauth-token - languages: - - regex - message: A gitleaks planetscale-oauth-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(pscale_oauth_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.planetscale-password.planetscale-password - languages: - - regex - message: A gitleaks planetscale-password was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(pscale_pw_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.postman-api-token.postman-api-token + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{domain:...}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{domain:...}} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {domain:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {domain:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.domain = ...; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.domain = ...; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-path languages: - - regex - message: A gitleaks postman-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Default session middleware settings: `path` not set. It indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-522: Insufficiently Protected Credentials' cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html subcategory: - vuln technology: - - gitleaks + - express patterns: - - pattern-regex: (?i)\b(PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.prefect-api-token.prefect-api-token + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{path:...}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{path:...}} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {path:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {path:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.path = ...; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie.path = ...; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-expires languages: - - regex - message: A gitleaks prefect-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Default session middleware settings: `expires` not set. Use it to set expiration date for persistent cookies.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-522: Insufficiently Protected Credentials' cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html subcategory: - vuln technology: - - gitleaks + - express patterns: - - pattern-regex: (?i)\b(pnu_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.private-key.private-key + - pattern-either: + - pattern-inside: | + $SESSION = require('cookie-session'); + ... + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern: $SESSION(...) + - pattern-not-inside: $SESSION(<... {cookie:{expires:...}} ...>,...) + - pattern-not-inside: | + $OPTS = <... {cookie:{expires:...}} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE = <... {expires:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $OPTS.cookie = <... {expires:...} ...>; + ... + $SESSION($OPTS,...); + - pattern-not-inside: | + $OPTS = ...; + ... + $COOKIE.expires = ...; + ... + $SESSION($OPTS,...); + - pattern-not-inside: |- + $OPTS = ...; + ... + $OPTS.cookie.expires = ...; + ... + $SESSION($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-jwt-not-revoked.express-jwt-not-revoked languages: - - regex - message: A gitleaks private-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: No token revoking configured for `express-jwt`. A leaked token could still be used and unable to be revoked. Consider using function as the `isRevoked` option. metadata: + asvs: + control_id: 3.5.3 Insecue Stateless Session Tokens + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-522: Insufficiently Protected Credentials' cwe2021-top25: true - cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://github.com/goldbergyoni/nodebestpractices/blob/master/sections/security/expirejwt.md subcategory: - vuln technology: - - gitleaks + - express patterns: - - pattern-regex: (?i)-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY( BLOCK)?-----[\s\S-]*KEY( BLOCK)?---- - severity: INFO - - id: generic.secrets.gitleaks.pulumi-api-token.pulumi-api-token + - pattern-inside: | + $JWT = require('express-jwt'); + ... + - pattern: $JWT(...) + - pattern-not-inside: $JWT(<... {isRevoked:...} ...>,...) + - pattern-not-inside: |- + $OPTS = <... {isRevoked:...} ...>; + ... + $JWT($OPTS,...); + severity: WARNING + - id: javascript.express.security.audit.express-libxml-noent.express-libxml-noent languages: - - regex - message: A gitleaks pulumi-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: The libxml library processes user-input with the `noent` attribute is set to `true` which can lead to being vulnerable to XML External Entities (XXE) type attacks. It is recommended to set `noent` to `false` when using this feature to ensure you are protected. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + interfile: true + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(pul-[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.pypi-upload-token.pypi-upload-token + - express + mode: taint + options: + interfile: true + pattern-sinks: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $XML = require('$IMPORT') + ... + - pattern-inside: | + import $XML from '$IMPORT' + ... + - pattern-inside: | + import * as $XML from '$IMPORT' + ... + - metavariable-regex: + metavariable: $IMPORT + regex: ^(libxmljs|libxmljs2)$ + - pattern-inside: $XML.$FUNC($QUERY, {...,noent:true,...}) + - metavariable-regex: + metavariable: $FUNC + regex: ^(parseXmlString|parseXml)$ + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - pattern: $REQ.files.$ANYTHING.data.toString('utf8') + - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - pattern: files.$ANYTHING.data.toString('utf8') + - pattern: files.$ANYTHING['data'].toString('utf8') + severity: ERROR + - id: javascript.express.security.audit.express-open-redirect.express-open-redirect languages: - - regex - message: A gitleaks pypi-upload-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: The application redirects to a URL specified by user-supplied input `$REQ` that is not validated. This could redirect users to malicious locations. Consider using an allow-list approach to validate URLs, or warn users they are being redirected to a third-party website. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000} - severity: INFO - - id: generic.secrets.gitleaks.rapidapi-access-token.rapidapi-access-token + - express + mode: taint + options: + symbolic_propagation: true + taint_unify_mvars: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.redirect("$HTTP"+$REQ. ... .$VALUE) + - pattern: $RES.redirect("$HTTP"+$REQ. ... .$VALUE + $...A) + - pattern: $RES.redirect(`$HTTP${$REQ. ... .$VALUE}...`) + - pattern: $RES.redirect("$HTTP"+$REQ.$VALUE[...]) + - pattern: $RES.redirect("$HTTP"+$REQ.$VALUE[...] + $...A) + - pattern: $RES.redirect(`$HTTP${$REQ.$VALUE[...]}...`) + - metavariable-regex: + metavariable: $HTTP + regex: ^https?:\/\/$ + - pattern-either: + - pattern: $REQ. ... .$VALUE + - patterns: + - pattern-either: + - pattern: $RES.redirect($REQ. ... .$VALUE) + - pattern: $RES.redirect($REQ. ... .$VALUE + $...A) + - pattern: $RES.redirect(`${$REQ. ... .$VALUE}...`) + - pattern: $REQ. ... .$VALUE + - patterns: + - pattern-either: + - pattern: $RES.redirect($REQ.$VALUE['...']) + - pattern: $RES.redirect($REQ.$VALUE['...'] + $...A) + - pattern: $RES.redirect(`${$REQ.$VALUE['...']}...`) + - pattern: $REQ.$VALUE + - patterns: + - pattern-either: + - pattern-inside: | + $ASSIGN = $REQ. ... .$VALUE + ... + - pattern-inside: | + $ASSIGN = $REQ.$VALUE['...'] + ... + - pattern-inside: | + $ASSIGN = $REQ. ... .$VALUE + $...A + ... + - pattern-inside: "$ASSIGN = $REQ.$VALUE['...'] + $...A\n... \n" + - pattern-inside: | + $ASSIGN = `${$REQ. ... .$VALUE}...` + ... + - pattern-inside: "$ASSIGN = `${$REQ.$VALUE['...']}...`\n... \n" + - pattern-either: + - pattern: $RES.redirect($ASSIGN) + - pattern: $RES.redirect($ASSIGN + $...FOO) + - pattern: $RES.redirect(`${$ASSIGN}...`) + - focus-metavariable: $ASSIGN + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.audit.express-path-join-resolve-traversal.express-path-join-resolve-traversal languages: - - regex - message: A gitleaks rapidapi-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Possible writing outside of the destination, make sure that the target path is nested in the intended destination metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/www-community/attacks/Path_Traversal subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:rapidapi)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{50})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.readme-api-token.readme-api-token + - express + - node.js + mode: taint + pattern-sanitizers: + - pattern: $Y.replace(...) + - pattern: $Y.indexOf(...) + - pattern: | + function ... (...) { + ... + <... $Y.indexOf(...) ...> + ... + } + - patterns: + - pattern: $FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: sanitize + pattern-sinks: + - patterns: + - focus-metavariable: $SINK + - pattern-either: + - pattern-inside: | + $PATH = require('path'); + ... + - pattern-inside: | + import $PATH from 'path'; + ... + - pattern-either: + - pattern: $PATH.join(...,$SINK,...) + - pattern: $PATH.resolve(...,$SINK,...) + - patterns: + - focus-metavariable: $SINK + - pattern-inside: | + import 'path'; + ... + - pattern-either: + - pattern: path.join(...,$SINK,...) + - pattern: path.resolve(...,$SINK,...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.audit.express-res-sendfile.express-res-sendfile languages: - - regex - message: A gitleaks readme-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: The application processes user-input, this is passed to res.sendFile which can allow an attacker to arbitrarily read files on the system through path traversal. It is recommended to perform input validation in addition to canonicalizing the path. This allows you to validate the path against the intended directory it should be accessing. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-73: External Control of File Name or Path' impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(rdme_[a-z0-9]{70})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.rubygems-api-token.rubygems-api-token - languages: - - regex - message: A gitleaks rubygems-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(rubygems_[a-f0-9]{48})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.scalingo-api-token.scalingo-api-token + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.$METH($QUERY,...) + - pattern-not-inside: $RES.$METH($QUERY,$OPTIONS) + - metavariable-regex: + metavariable: $METH + regex: ^(sendfile|sendFile)$ + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + function ... (...,$REQ: $TYPE, ...) {...} + - metavariable-regex: + metavariable: $TYPE + regex: ^(string|String) + severity: WARNING + - id: javascript.express.security.audit.express-session-hardcoded-secret.express-session-hardcoded-secret languages: - - regex - message: A gitleaks scalingo-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: LOW + confidence: HIGH cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + interfile: true + likelihood: HIGH owasp: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - gitleaks + - express + - secrets + options: + interfile: true patterns: - - pattern-regex: \b(tk-us-[a-zA-Z0-9-_]{48})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.sendbird-access-id.sendbird-access-id + - pattern-either: + - pattern-inside: | + $SESSION = require('express-session'); + ... + - pattern-inside: | + import $SESSION from 'express-session' + ... + - pattern-inside: | + import {..., $SESSION, ...} from 'express-session' + ... + - pattern-inside: | + import * as $SESSION from 'express-session' + ... + - patterns: + - pattern-either: + - pattern-inside: $APP.use($SESSION({...})) + - pattern: | + $SECRET = $VALUE + ... + $APP.use($SESSION($SECRET)) + - pattern: | + secret: '$Y' + severity: WARNING + - id: javascript.express.security.audit.express-ssrf.express-ssrf languages: - - regex - message: A gitleaks sendbird-access-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'The following request $REQUEST.$METHOD() was found to be crafted from user-input `$REQ` which can lead to Server-Side Request Forgery (SSRF) vulnerabilities. It is recommended where possible to not allow user-input to craft the base request, but to be treated as part of the path or query parameter. When user-input is necessary to craft the request, it is recommeneded to follow OWASP best practices to prevent abuse. ' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-918: Server-Side Request Forgery (SSRF)' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A10:2021 - Server-Side Request Forgery (SSRF) references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.sendbird-access-token.sendbird-access-token + - express + mode: taint + options: + taint_unify_mvars: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $REQUEST = require('request') + ... + - pattern-inside: | + import * as $REQUEST from 'request' + ... + - pattern-inside: | + import $REQUEST from 'request' + ... + - pattern-either: + - pattern: $REQUEST.$METHOD("$HTTP"+$REQ. ... .$VALUE) + - pattern: $REQUEST.$METHOD("$HTTP"+$REQ. ... .$VALUE + $...A) + - pattern: $REQUEST.$METHOD(`$HTTP${$REQ. ... .$VALUE}...`) + - pattern: $REQUEST.$METHOD("$HTTP"+$REQ.$VALUE[...]) + - pattern: $REQUEST.$METHOD("$HTTP"+$REQ.$VALUE[...] + $...A) + - pattern: $REQUEST.$METHOD(`$HTTP${$REQ.$VALUE[...]}...`) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|patch|del|head|delete)$ + - metavariable-regex: + metavariable: $HTTP + regex: ^(https?:\/\/|//)$ + - pattern-either: + - pattern: $REQ. ... .$VALUE + - patterns: + - pattern-either: + - pattern-inside: | + $REQUEST = require('request') + ... + - pattern-inside: | + import * as $REQUEST from 'request' + ... + - pattern-inside: | + import $REQUEST from 'request' + ... + - pattern-either: + - pattern: $REQUEST.$METHOD($REQ. ... .$VALUE,...) + - pattern: $REQUEST.$METHOD($REQ. ... .$VALUE + $...A,...) + - pattern: $REQUEST.$METHOD(`${$REQ. ... .$VALUE}...`,...) + - pattern: $REQ. ... .$VALUE + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|patch|del|head|delete)$ + - patterns: + - pattern-either: + - pattern-inside: | + $REQUEST = require('request') + ... + - pattern-inside: | + import * as $REQUEST from 'request' + ... + - pattern-inside: | + import $REQUEST from 'request' + ... + - pattern-either: + - pattern: $REQUEST.$METHOD($REQ.$VALUE['...'],...) + - pattern: $REQUEST.$METHOD($REQ.$VALUE['...'] + $...A,...) + - pattern: $REQUEST.$METHOD(`${$REQ.$VALUE['...']}...`,...) + - pattern: $REQ.$VALUE + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|patch|del|head|delete)$ + - patterns: + - pattern-either: + - pattern-inside: | + $REQUEST = require('request') + ... + - pattern-inside: | + import * as $REQUEST from 'request' + ... + - pattern-inside: | + import $REQUEST from 'request' + ... + - pattern-either: + - pattern-inside: | + $ASSIGN = $REQ. ... .$VALUE + ... + - pattern-inside: | + $ASSIGN = $REQ. ... .$VALUE['...'] + ... + - pattern-inside: | + $ASSIGN = $REQ. ... .$VALUE + $...A + ... + - pattern-inside: "$ASSIGN = $REQ. ... .$VALUE['...'] + $...A\n... \n" + - pattern-inside: | + $ASSIGN = `${$REQ. ... .$VALUE}...` + ... + - pattern-inside: "$ASSIGN = `${$REQ. ... .$VALUE['...']}...`\n... \n" + - patterns: + - pattern-either: + - pattern-inside: | + $ASSIGN = "$HTTP"+ $REQ. ... .$VALUE + ... + - pattern-inside: | + $ASSIGN = "$HTTP"+$REQ. ... .$VALUE + $...A + ... + - pattern-inside: | + $ASSIGN = "$HTTP"+$REQ.$VALUE[...] + ... + - pattern-inside: | + $ASSIGN = "$HTTP"+$REQ.$VALUE[...] + $...A + ... + - pattern-inside: | + $ASSIGN = `$HTTP${$REQ.$VALUE[...]}...` + ... + - metavariable-regex: + metavariable: $HTTP + regex: ^(https?:\/\/|//)$ + - pattern-either: + - pattern: $REQUEST.$METHOD($ASSIGN,...) + - pattern: $REQUEST.$METHOD($ASSIGN + $...FOO,...) + - pattern: $REQUEST.$METHOD(`${$ASSIGN}...`,...) + - patterns: + - pattern-either: + - pattern: $REQUEST.$METHOD("$HTTP"+$ASSIGN,...) + - pattern: $REQUEST.$METHOD("$HTTP"+$ASSIGN + $...A,...) + - pattern: $REQUEST.$METHOD(`$HTTP${$ASSIGN}...`,...) + - metavariable-regex: + metavariable: $HTTP + regex: ^(https?:\/\/|//)$ + - pattern: $ASSIGN + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|patch|del|head|delete)$ + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, ...) {...} + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,...) => + {...} + - pattern-inside: | + ({ $REQ }: $EXPRESS.Request,...) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.audit.express-third-party-object-deserialization.express-third-party-object-deserialization languages: - - regex - message: A gitleaks sendbird-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: The following function call $SER.$FUNC accepts user controlled data which can result in Remote Code Execution (RCE) through Object Deserialization. It is recommended to use secure data processing alternatives such as JSON.parse() and Buffer.from(). metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-502: Deserialization of Untrusted Data' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + interfile: true + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + source_rule_url: + - https://github.com/ajinabraham/njsscan/blob/75bfbeb9c8d72999e4d527dfa2548f7f0f3cc48a/njsscan/rules/semantic_grep/eval/eval_deserialize.yaml subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.sendgrid-api-token.sendgrid-api-token + - express + mode: taint + options: + interfile: true + pattern-sinks: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $SER = require('$IMPORT') + ... + - pattern-inside: | + import $SER from '$IMPORT' + ... + - pattern-inside: | + import * as $SER from '$IMPORT' + ... + - metavariable-regex: + metavariable: $IMPORT + regex: ^(node-serialize|serialize-to-js)$ + - pattern: $SER.$FUNC(...) + - metavariable-regex: + metavariable: $FUNC + regex: ^(unserialize|deserialize)$ + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - pattern: $REQ.files.$ANYTHING.data.toString('utf8') + - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - pattern: files.$ANYTHING.data.toString('utf8') + - pattern: files.$ANYTHING['data'].toString('utf8') + severity: WARNING + - id: javascript.express.security.audit.express-xml2json-xxe-event.express-xml2json-xxe-event languages: - - regex - message: A gitleaks sendgrid-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Xml Parser is used inside Request Event. Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.npmjs.com/package/xml2json subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(SG\.(?i)[a-z0-9=_\-\.]{66})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.sendinblue-api-token.sendinblue-api-token + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('xml2json'); + ... + - pattern-inside: | + import 'xml2json'; + ... + - pattern: $REQ.on('...', function(...) { ... $EXPAT.toJson($INPUT,...); ... }) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.audit.res-render-injection.res-render-injection languages: - - regex - message: A gitleaks sendinblue-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: User controllable data `$REQ` enters `$RES.render(...)` this can lead to the loading of other HTML/templating pages that they may not be authorized to render. An attacker may attempt to use directory traversal techniques e.g. `../folder/index` to access other HTML pages on the file system. Where possible, do not allow users to define what should be loaded in $RES.render or use an allow list for the existing application. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-706: Use of Incorrectly-Resolved Name or Reference' impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - http://expressjs.com/en/4x/api.html#res.render subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.sentry-access-token.sentry-access-token + - express + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.render($SINK, ...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.audit.xss.direct-response-write.direct-response-write languages: - - regex - message: A gitleaks sentry-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected directly writing to a Response object from user-defined input. This bypasses any HTML escaping and may expose your application to a Cross-Site-scripting (XSS) vulnerability. Instead, use 'resp.render()' to render safely escaped HTML. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:sentry)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.shippo-api-token.shippo-api-token - languages: - - regex - message: A gitleaks shippo-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(shippo_(live|test)_[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.shopify-access-token.shopify-access-token - languages: - - regex - message: A gitleaks shopify-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: shpat_[a-fA-F0-9]{32} - severity: INFO - - id: generic.secrets.gitleaks.shopify-custom-access-token.shopify-custom-access-token - languages: - - regex - message: A gitleaks shopify-custom-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: shpca_[a-fA-F0-9]{32} - severity: INFO - - id: generic.secrets.gitleaks.shopify-private-app-access-token.shopify-private-app-access-token - languages: - - regex - message: A gitleaks shopify-private-app-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: shppa_[a-fA-F0-9]{32} - severity: INFO - - id: generic.secrets.gitleaks.shopify-shared-secret.shopify-shared-secret - languages: - - regex - message: A gitleaks shopify-shared-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: shpss_[a-fA-F0-9]{32} - severity: INFO - - id: generic.secrets.gitleaks.sidekiq-secret.sidekiq-secret - languages: - - regex - message: A gitleaks sidekiq-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.sidekiq-sensitive-url.sidekiq-sensitive-url - languages: - - regex - message: A gitleaks sidekiq-sensitive-url was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(http(?:s??):\/\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$) - severity: INFO - - id: generic.secrets.gitleaks.slack-app-token.slack-app-token + - express + vulnerability_class: + - Cross-Site-Scripting (XSS) + mode: taint + options: + interfile: true + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + $S = new Remarkable() + ... + - pattern: $S.render(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'express-xss-sanitizer'; + ... + - pattern-inside: | + import * as $S from "express-xss-sanitizer"; + ... + - pattern-inside: | + const { ..., $S, ... } = require('express-xss-sanitizer'); + ... + - pattern-inside: | + var { ..., $S, ... } = require('express-xss-sanitizer'); + ... + - pattern-inside: | + let { ...,$S,... } = require('express-xss-sanitizer'); + ... + - pattern-inside: | + $S = require("express-xss-sanitizer") + ... + - pattern: $S(...) + - patterns: + - pattern: $RES. ... .type('$F'). ... .send(...) + - metavariable-regex: + metavariable: $F + regex: (?!.*text/html) + - patterns: + - pattern-inside: | + $X = [...]; + ... + - pattern: | + if(<... !$X.includes($SOURCE)...>) { + ... + return ... + } + ... + - pattern: $SOURCE + pattern-sinks: + - patterns: + - pattern-inside: function ... (..., $RES,...) {...} + - pattern-either: + - pattern: $RES.write($ARG) + - pattern: $RES.send($ARG) + - pattern-not: $RES. ... .set('...'). ... .send($ARG) + - pattern-not: $RES. ... .type('...'). ... .send($ARG) + - pattern-not-inside: $RES.$METHOD({ ... }) + - focus-metavariable: $ARG + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options) + - pattern-not-inside: | + function ... ($REQ, $RES) { + ... + $RES.$SET('Content-Type', '$TYPE') + } + - pattern-not-inside: | + $APP.$METHOD(..., function $FUNC($REQ, $RES) { + ... + $RES.$SET('Content-Type', '$TYPE') + }) + - pattern-not-inside: | + function ... ($REQ, $RES, $NEXT) { + ... + $RES.$SET('Content-Type', '$TYPE') + } + - pattern-not-inside: | + function ... ($REQ, $RES) { + ... + $RES.set('$TYPE') + } + - pattern-not-inside: | + $APP.$METHOD(..., function $FUNC($REQ, $RES) { + ... + $RES.set('$TYPE') + }) + - pattern-not-inside: | + function ... ($REQ, $RES, $NEXT) { + ... + $RES.set('$TYPE') + } + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - pattern-not-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + { + ... + $RES.$SET('Content-Type', '$TYPE') + } + - pattern-not-inside: | + ({ $REQ }: Request,$RES: Response) => { + ... + $RES.$SET('Content-Type', '$TYPE') + } + - pattern-not-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + { + ... + $RES.set('$TYPE') + } + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: body + severity: WARNING + - id: javascript.express.security.cors-misconfiguration.cors-misconfiguration languages: - - regex - message: A gitleaks slack-app-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: By letting user input control CORS parameters, there is a risk that software does not properly verify that the source of data or communication is valid. Use literal values for CORS settings. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-346: Origin Validation Error' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(xapp-\d-[A-Z0-9]+-\d+-[a-z0-9]+) - severity: INFO - - id: generic.secrets.gitleaks.slack-bot-token.slack-bot-token + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.set($HEADER, $X) + - pattern: $RES.header($HEADER, $X) + - pattern: $RES.setHeader($HEADER, $X) + - pattern: | + $RES.set({$HEADER: $X}, ...) + - pattern: | + $RES.writeHead($STATUS, {$HEADER: $X}, ...) + - focus-metavariable: $X + - metavariable-regex: + metavariable: $HEADER + regex: .*(Access-Control-Allow-Origin|access-control-allow-origin).* + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.express-expat-xxe.express-expat-xxe languages: - - regex - message: A gitleaks slack-bot-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities. metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://github.com/astro/node-expat subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (xoxb-[0-9]{10,13}\-[0-9]{10,13}[a-zA-Z0-9-]*) - severity: INFO - - id: generic.secrets.gitleaks.slack-config-access-token.slack-config-access-token + - express + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $XML = require('node-expat') + ... + - pattern-inside: | + import $XML from 'node-expat' + ... + - pattern-inside: | + import * as $XML from 'node-expat' + ... + - pattern-either: + - pattern-inside: | + $PARSER = new $XML.Parser(...); + ... + - pattern-either: + - pattern: $PARSER.parse($QUERY) + - pattern: $PARSER.write($QUERY) + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-insecure-template-usage.express-insecure-template-usage languages: - - regex - message: A gitleaks slack-config-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: User data from `$REQ` is being compiled into the template, which can lead to a Server Side Template Injection (SSTI) vulnerability. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine' impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection + - A01:2017 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html + source_rule_url: + - https://github.com/github/codeql/blob/2ba2642c7ab29b9eedef33bcc2b8cd1d203d0c10/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(xoxe.xox[bp]-\d-[A-Z0-9]{163,166}) - severity: INFO - - id: generic.secrets.gitleaks.slack-config-refresh-token.slack-config-refresh-token - languages: - - regex - message: A gitleaks slack-config-refresh-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)(xoxe-\d-[A-Z0-9]{146}) - severity: INFO - - id: generic.secrets.gitleaks.slack-legacy-bot-token.slack-legacy-bot-token + - javascript + - typescript + - express + - pug + - jade + - dot + - ejs + - nunjucks + - lodash + - handlbars + - mustache + - hogan.js + - eta + - squirrelly + mode: taint + options: + interfile: true + pattern-propagators: + - from: $E + pattern: $MODEL.$FIND($E).then((...,$S,...)=>{...}) + to: $S + pattern-sinks: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('pug') + ... + - pattern-inside: | + import * as $PUG from 'pug' + ... + - pattern-inside: | + $PUG = require('jade') + ... + - pattern-inside: | + import * as $PUG from 'jade' + ... + - pattern-either: + - pattern: $PUG.compile(...) + - pattern: $PUG.compileClient(...) + - pattern: $PUG.compileClientWithDependenciesTracked(...) + - pattern: $PUG.render(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('dot') + ... + - pattern-inside: | + import * as $PUG from 'dot' + ... + - pattern-either: + - pattern: $PUG.template(...) + - pattern: $PUG.compile(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('ejs') + ... + - pattern-inside: | + import * as $PUG from 'ejs' + ... + - pattern-either: + - pattern: $PUG.render(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('nunjucks') + ... + - pattern-inside: | + import * as $PUG from 'nunjucks' + ... + - pattern-either: + - pattern: $PUG.renderString(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('lodash') + ... + - pattern-inside: | + import * as $PUG from 'lodash' + ... + - pattern-either: + - pattern: $PUG.template(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('mustache') + ... + - pattern-inside: | + import * as $PUG from 'mustache' + ... + - pattern-inside: | + $PUG = require('eta') + ... + - pattern-inside: | + import * as $PUG from 'eta' + ... + - pattern-inside: | + $PUG = require('squirrelly') + ... + - pattern-inside: | + import * as $PUG from 'squirrelly' + ... + - pattern-either: + - pattern: $PUG.render(...) + - patterns: + - pattern-either: + - pattern-inside: | + $PUG = require('hogan.js') + ... + - pattern-inside: | + import * as $PUG from 'hogan.js' + ... + - pattern-inside: | + $PUG = require('handlebars') + ... + - pattern-inside: | + import * as $PUG from 'handlebars' + ... + - pattern-either: + - pattern: $PUG.compile(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.express-jwt-hardcoded-secret.express-jwt-hardcoded-secret languages: - - regex - message: A gitleaks slack-legacy-bot-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - confidence: LOW + confidence: HIGH cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: HIGH owasp: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - - vuln + - audit technology: - - gitleaks + - express + - secrets + options: + interfile: true patterns: - - pattern-regex: (xoxb-[0-9]{8,14}\-[a-zA-Z0-9]{18,26}) - severity: INFO - - id: generic.secrets.gitleaks.slack-legacy-token.slack-legacy-token + - pattern-either: + - pattern-inside: | + $JWT = require('express-jwt'); + ... + - pattern-inside: | + import $JWT from 'express-jwt'; + ... + - pattern-inside: | + import * as $JWT from 'express-jwt'; + ... + - pattern-inside: | + import { ..., $JWT, ... } from 'express-jwt'; + ... + - pattern-either: + - pattern: | + $JWT({...,secret: "$Y",...},...) + - pattern: | + $OPTS = "$Y"; + ... + $JWT({...,secret: $OPTS},...); + - focus-metavariable: $Y + severity: WARNING + - id: javascript.express.security.express-phantom-injection.express-phantom-injection languages: - - regex - message: A gitleaks slack-legacy-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: If unverified user data can reach the `phantom` methods it can result in Server-Side Request Forgery vulnerabilities metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-918: Server-Side Request Forgery (SSRF)' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A10:2021 - Server-Side Request Forgery (SSRF) references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://phantomjs.org/page-automation.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (xox[os]-\d+-\d+-\d+-[a-fA-F\d]+) - severity: INFO - - id: generic.secrets.gitleaks.slack-legacy-workspace-token.slack-legacy-workspace-token + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('phantom'); + ... + - pattern-inside: | + import 'phantom'; + ... + - pattern-either: + - pattern: $PAGE.open($SINK,...) + - pattern: $PAGE.setContent($SINK,...) + - pattern: $PAGE.openUrl($SINK,...) + - pattern: $PAGE.evaluateJavaScript($SINK,...) + - pattern: $PAGE.property("content",$SINK,...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-puppeteer-injection.express-puppeteer-injection languages: - - regex - message: A gitleaks slack-legacy-workspace-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: If unverified user data can reach the `puppeteer` methods it can result in Server-Side Request Forgery vulnerabilities metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-918: Server-Side Request Forgery (SSRF)' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A10:2021 - Server-Side Request Forgery (SSRF) references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://pptr.dev/api/puppeteer.page subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (xox[ar]-(?:\d-)?[0-9a-zA-Z]{8,48}) - severity: INFO - - id: generic.secrets.gitleaks.slack-user-token.slack-user-token + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('puppeteer'); + ... + - pattern-inside: | + import 'puppeteer'; + ... + - pattern-either: + - pattern: $PAGE.goto($SINK,...) + - pattern: $PAGE.setContent($SINK,...) + - pattern: $PAGE.evaluate($SINK,...) + - pattern: $PAGE.evaluate($CODE,$SINK,...) + - pattern: $PAGE.evaluateHandle($SINK,...) + - pattern: $PAGE.evaluateHandle($CODE,$SINK,...) + - pattern: $PAGE.evaluateOnNewDocument($SINK,...) + - pattern: $PAGE.evaluateOnNewDocument($CODE,$SINK,...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-sandbox-injection.express-sandbox-code-injection languages: - - regex - message: A gitleaks slack-user-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Make sure that unverified user data can not reach `sandbox`. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (xox[pe](?:-[0-9]{10,13}){3}-[a-zA-Z0-9-]{28,34}) - severity: INFO - - id: generic.secrets.gitleaks.slack-webhook-url.slack-webhook-url + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + $SANDBOX = require('sandbox'); + ... + - pattern-either: + - patterns: + - pattern-inside: | + $S = new $SANDBOX(...); + ... + - pattern: | + $S.run(...) + - pattern: | + new $SANDBOX($OPTS).run(...) + - pattern: new $SANDBOX().run(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-vm-injection.express-vm-injection languages: - - regex - message: A gitleaks slack-webhook-url was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Make sure that unverified user data can not reach `$VM`. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (https?:\/\/)?hooks.slack.com\/(services|workflows)\/[A-Za-z0-9+\/]{43,46} - severity: INFO - - id: generic.secrets.gitleaks.snyk-api-token.snyk-api-token + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + $VM = require('vm'); + ... + - pattern-either: + - pattern: | + $VM.runInContext(...) + - pattern: | + $VM.runInNewContext(...) + - pattern: | + $VM.compileFunction(...) + - pattern: | + $VM.runInThisContext(...) + - pattern: new $VM.Script(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.express-vm2-injection.express-vm2-injection languages: - - regex - message: A gitleaks snyk-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Make sure that unverified user data can not reach `vm2`. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:snyk_token|snyk_key|snyk_api_token|snyk_api_key|snyk_oauth_token)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.square-access-token.square-access-token - languages: - - regex - message: A gitleaks square-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules - subcategory: - - vuln - technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b((EAAA|sq0atp-)[0-9A-Za-z\-_]{22,60})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.squarespace-access-token.squarespace-access-token + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + require('vm2') + ... + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + $VM = new VM(...) + ... + - pattern-inside: | + $VM = new NodeVM(...) + ... + - pattern: | + $VM.run(...) + - pattern: | + new VM(...).run(...) + - pattern: | + new NodeVM(...).run(...) + - pattern: | + new VMScript(...) + - pattern: | + new VM(...) + - pattern: new NodeVM(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.express.security.express-xml2json-xxe.express-xml2json-xxe languages: - - regex - message: A gitleaks squarespace-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities metadata: + asvs: + control_id: 5.5.2 Insecue XML Deserialization + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention + section: V5 Validation, Sanitization and Encoding + version: "4" category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.npmjs.com/package/xml2json subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:squarespace)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.stripe-access-token.stripe-access-token + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + require('xml2json'); + ... + - pattern-inside: | + import 'xml2json'; + ... + - pattern: $EXPAT.toJson($SINK,...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - pattern: $REQ.files.$ANYTHING.data.toString('utf8') + - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - pattern: files.$ANYTHING.data.toString('utf8') + - pattern: files.$ANYTHING['data'].toString('utf8') + severity: ERROR + - id: javascript.express.security.injection.raw-html-format.raw-html-format languages: - - regex - message: A gitleaks stripe-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: User data flows into the host portion of this manually-constructed HTML. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. Consider using a sanitization library such as DOMPurify to sanitize the HTML within. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b((sk|rk)_(test|live|prod)_[0-9a-z]{10,99})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.sumologic-access-id.sumologic-access-id + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: '"$HTMLSTR" + $EXPR' + - pattern: '"$HTMLSTR".concat(...)' + - pattern: util.format($HTMLSTR, ...) + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... + - patterns: + - pattern: | + `...` + - pattern-regex: | + .*<\w+.* + requires: (EXPRESS and not CLEAN) or (EXPRESSTS and not CLEAN) + pattern-sources: + - label: EXPRESS + patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - label: EXPRESSTS + patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - by-side-effect: true + label: CLEAN + patterns: + - pattern-either: + - pattern: $A($SOURCE) + - pattern: $SANITIZE. ... .$A($SOURCE) + - pattern: $A. ... .$SANITIZE($SOURCE) + - focus-metavariable: $SOURCE + - metavariable-regex: + metavariable: $A + regex: (?i)(.*valid|.*sanitiz) + severity: WARNING + - id: javascript.express.security.injection.tainted-sql-string.tainted-sql-string languages: - - regex - message: A gitleaks sumologic-access-id was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/www-community/attacks/SQL_Injection subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i:(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3})(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(su[a-zA-Z0-9]{12})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.sumologic-access-token.sumologic-access-token + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: | + "$SQLSTR" + $EXPR + - pattern-inside: | + "$SQLSTR".concat($EXPR) + - pattern: util.format($SQLSTR, $EXPR) + - pattern: | + `$SQLSTR${$EXPR}...` + - metavariable-regex: + metavariable: $SQLSTR + regex: .*\b(?i)(select|delete|insert|create|update\s+.+\sset|alter|drop)\b.* + - focus-metavariable: $EXPR + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... (...,$REQ, ...) {...} + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + (...,{ $REQ }: Request,...) => {...} + - pattern-inside: | + (...,{ $REQ }: $EXPRESS.Request,...) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.require-request.require-request languages: - - regex - message: A gitleaks sumologic-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: If an attacker controls the x in require(x) then they can cause code to load that was not intended to run on the server. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-706: Use of Incorrectly-Resolved Name or Reference' impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://github.com/google/node-sec-roadmap/blob/master/chapter-2/dynamism.md#dynamism-when-you-need-it + source-rule-url: https://nodesecroadmap.fyi/chapter-1/threat-UIR.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.telegram-bot-api-token.telegram-bot-api-token + - express + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern: require($SINK) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: ERROR + - id: javascript.express.security.x-frame-options-misconfiguration.x-frame-options-misconfiguration languages: - - regex - message: A gitleaks telegram-bot-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: By letting user input control `X-Frame-Options` header, there is a risk that software does not properly verify whether or not a browser should be allowed to render a page in an `iframe`. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-451: User Interface (UI) Misrepresentation of Critical Information' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i:(?:telegr)(?:[0-9a-z\(-_\t .\\]{0,40})(?:[\s|']|[\s|"]){0,3})(?:=|\|\|:|<=|=>|:|\?=|\()(?:'|\"|\s|=|\x60){0,5}([0-9]{5,16}:A[a-z0-9_\-]{34})(?:['|\"|\n|\r|\s|\x60|;|\\]|$) - severity: INFO - - id: generic.secrets.gitleaks.travisci-access-token.travisci-access-token + - express + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $RES.set($HEADER, ...) + - pattern: $RES.header($HEADER, ...) + - pattern: $RES.setHeader($HEADER, ...) + - pattern: | + $RES.set({$HEADER: ...}, ...) + - pattern: | + $RES.writeHead($STATUS, {$HEADER: ...}, ...) + - metavariable-regex: + metavariable: $HEADER + regex: .*(X-Frame-Options|x-frame-options).* + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + severity: WARNING + - id: javascript.intercom.security.audit.intercom-settings-user-identifier-without-user-hash.intercom-settings-user-identifier-without-user-hash languages: - - regex - message: A gitleaks travisci-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - js + message: Found an initialization of the Intercom Messenger that identifies a User, but does not specify a `user_hash`.This configuration allows users to impersonate one another. See the Intercom Identity Verification docs for more context https://www.intercom.com/help/en/articles/183-set-up-identity-verification-for-web-and-mobile metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + - 'CWE-287: Improper Authentication' + impact: HIGH + likelihood: MEDIUM references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.intercom.com/help/en/articles/183-set-up-identity-verification-for-web-and-mobile subcategory: - - vuln + - guardrail technology: - - gitleaks + - intercom patterns: - - pattern-regex: (?i)(?:travis)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.twilio-api-key.twilio-api-key + - pattern-either: + - pattern: | + window.intercomSettings = {..., email: $EMAIL, ...}; + - pattern: | + window.intercomSettings = {..., user_id: $USER_ID, ...}; + - pattern: | + Intercom('boot', {..., email: $EMAIL, ...}); + - pattern: | + Intercom('boot', {..., user_id: $USER_ID, ...}); + - pattern: | + $VAR = {..., email: $EMAIL, ...}; + ... + Intercom('boot', $VAR); + - pattern: | + $VAR = {..., user_id: $EMAIL, ...}; + ... + Intercom('boot', $VAR); + - pattern-not: | + window.intercomSettings = {..., user_hash: $USER_HASH, ...}; + - pattern-not: | + Intercom('boot', {..., user_hash: $USER_HASH, ...}); + - pattern-not: | + $VAR = {..., user_hash: $USER_HASH, ...}; + ... + Intercom('boot', $VAR); + severity: WARNING + - id: javascript.jose.security.jwt-hardcode.hardcoded-jwt-secret languages: - - regex - message: A gitleaks twilio-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: + asvs: + control_id: 3.5.2 Static API keys or secret + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: HIGH owasp: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - gitleaks + - jose + - jwt + - secrets + options: + interfile: true + symbolic_propagation: true patterns: - - pattern-regex: SK[0-9a-fA-F]{32} - severity: INFO - - id: generic.secrets.gitleaks.twitch-api-token.twitch-api-token + - pattern-inside: | + $JOSE = require("jose"); + ... + - pattern-either: + - pattern-inside: | + var {JWT} = $JOSE; + ... + - pattern-inside: | + var {JWK, JWT} = $JOSE; + ... + - pattern-inside: | + const {JWT} = $JOSE; + ... + - pattern-inside: | + const {JWK, JWT} = $JOSE; + ... + - pattern-inside: | + let {JWT} = $JOSE; + ... + - pattern-inside: | + let {JWK, JWT} = $JOSE; + ... + - pattern-either: + - pattern: | + JWT.verify($P, "...", ...); + - pattern: | + JWT.sign($P, "...", ...); + - pattern: "JWT.verify($P, JWK.asKey(\"...\"), ...); \n" + - pattern: | + $JWT.sign($P, JWK.asKey("..."), ...); + severity: WARNING + - id: javascript.jose.security.jwt-none-alg.jwt-none-alg languages: - - regex - message: A gitleaks twitch-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + asvs: + control_id: 3.5.3 Insecue Stateless Session Tokens + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" + category: security + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:twitch)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.twitter-access-secret.twitter-access-secret + - jose + - jwt + pattern-either: + - pattern: | + var $JOSE = require("jose"); + ... + var { JWK, JWT } = $JOSE; + ... + var $T = JWT.verify($P, JWK.None,...); + - pattern: | + var $JOSE = require("jose"); + ... + var { JWK, JWT } = $JOSE; + ... + $T = JWT.verify($P, JWK.None,...); + - pattern: | + var $JOSE = require("jose"); + ... + var { JWK, JWT } = $JOSE; + ... + JWT.verify($P, JWK.None,...); + severity: ERROR + - id: javascript.jsonwebtoken.security.jwt-hardcode.hardcoded-jwt-secret languages: - - regex - message: A gitleaks twitter-access-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: + asvs: + control_id: 3.5.2 Static API keys or secret + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{45})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.twitter-access-token.twitter-access-token + - jwt + - javascript + - secrets + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $JWT = require("jsonwebtoken") + ... + - pattern-inside: | + import $JWT from "jsonwebtoken" + ... + - pattern-inside: | + import * as $JWT from "jsonwebtoken" + ... + - pattern-inside: | + import {...,$JWT,...} from "jsonwebtoken" + ... + - pattern-either: + - pattern-inside: | + $JWT.sign($DATA,$VALUE,...); + - pattern-inside: | + $JWT.verify($DATA,$VALUE,...); + - focus-metavariable: $VALUE + pattern-sources: + - patterns: + - pattern: "$X = '...' \n" + - pattern: "$X = '$Y' \n" + - patterns: + - pattern-either: + - pattern-inside: | + $JWT.sign($DATA,"...",...); + - pattern-inside: | + $JWT.verify($DATA,"...",...); + severity: WARNING + - id: javascript.jsonwebtoken.security.jwt-none-alg.jwt-none-alg languages: - - regex - message: A gitleaks twitter-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. metadata: + asvs: + control_id: 3.5.3 Insecue Stateless Session Tokens + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ subcategory: - vuln technology: - - gitleaks + - jwt patterns: - - pattern-regex: (?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{15,25}-[a-zA-Z0-9]{20,40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.twitter-api-key.twitter-api-key + - pattern-inside: | + $JWT = require("jsonwebtoken"); + ... + - pattern: $JWT.verify($P, $X, {algorithms:[...,'none',...]},...) + severity: ERROR + - id: javascript.jwt-simple.security.jwt-simple-noverify.jwt-simple-noverify languages: - - regex - message: A gitleaks twitter-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Set 'verify' to `true` before using the token. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + - 'CWE-287: Improper Authentication' + - 'CWE-345: Insufficient Verification of Data Authenticity' + - 'CWE-347: Improper Verification of Cryptographic Signature' + impact: HIGH + likelihood: MEDIUM owasp: + - A05:2021 - Security Misconfiguration - A07:2021 - Identification and Authentication Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://www.npmjs.com/package/jwt-simple + - https://cwe.mitre.org/data/definitions/287 + - https://cwe.mitre.org/data/definitions/345 + - https://cwe.mitre.org/data/definitions/347 subcategory: - vuln technology: - - gitleaks + - jwt-simple + - jwt patterns: - - pattern-regex: (?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.twitter-api-secret.twitter-api-secret + - pattern-inside: | + $JWT = require('jwt-simple'); + ... + - pattern: $JWT.decode($TOKEN, $SECRET, $NOVERIFY, ...) + - metavariable-pattern: + metavariable: $NOVERIFY + patterns: + - pattern-either: + - pattern: | + true + - pattern: | + "..." + severity: ERROR + - id: javascript.lang.security.audit.code-string-concat.code-string-concat languages: - - regex - message: A gitleaks twitter-api-secret was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Found data from an Express or Next web request flowing to `eval`. If this data is user-controllable this can lead to execution of arbitrary system commands in the context of your application process. Avoid `eval` whenever possible. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' impact: MEDIUM - likelihood: LOW + interfile: true + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval + - https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback + - https://www.stackhawk.com/blog/nodejs-command-injection-examples-and-prevention/ + - https://ckarande.gitbooks.io/owasp-nodegoat-tutorial/content/tutorial/a1_-_server_side_js_injection.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{50})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.twitter-bearer-token.twitter-bearer-token + - node.js + - Express + - Next.js + mode: taint + options: + interfile: true + pattern-sinks: + - patterns: + - pattern: | + eval(...) + pattern-sources: + - pattern-either: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - patterns: + - pattern-either: + - pattern-inside: | + import { ...,$IMPORT,... } from 'next/router' + ... + - pattern-inside: | + import $IMPORT from 'next/router'; + ... + - pattern-either: + - patterns: + - pattern-inside: | + $ROUTER = $IMPORT() + ... + - pattern-either: + - pattern-inside: | + const { ...,$PROPS,... } = $ROUTER.query + ... + - pattern-inside: | + var { ...,$PROPS,... } = $ROUTER.query + ... + - pattern-inside: | + let { ...,$PROPS,... } = $ROUTER.query + ... + - focus-metavariable: $PROPS + - patterns: + - pattern-inside: | + $ROUTER = $IMPORT() + ... + - pattern: "$ROUTER.query.$VALUE \n" + - patterns: + - pattern: $IMPORT().query.$VALUE + severity: ERROR + - id: javascript.lang.security.audit.sqli.node-knex-sqli.node-knex-sqli languages: - - regex - message: A gitleaks twitter-bearer-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: 'Detected SQL statement that is tainted by `$REQ` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements. An example of parameterized queries like so: `knex.raw(''SELECT $1 from table'', [userinput])` can help prevent SQLi.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://knexjs.org/#Builder-fromRaw + - https://knexjs.org/#Builder-whereRaw + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(A{22}[a-zA-Z0-9%]{80,100})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.typeform-api-token.typeform-api-token + - express + - nodejs + - knex + mode: taint + pattern-sanitizers: + - patterns: + - pattern: parseInt(...) + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern-inside: $KNEX.fromRaw($QUERY, ...) + - pattern-inside: $KNEX.whereRaw($QUERY, ...) + - pattern-inside: $KNEX.raw($QUERY, ...) + - pattern-either: + - pattern-inside: | + require('knex') + ... + - pattern-inside: | + import 'knex' + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options) + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - pattern: $REQ.files.$ANYTHING.data.toString('utf8') + - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - pattern: files.$ANYTHING.data.toString('utf8') + - pattern: files.$ANYTHING['data'].toString('utf8') + severity: WARNING + - id: javascript.lang.security.detect-eval-with-expression.detect-eval-with-expression languages: - - regex - message: A gitleaks typeform-api-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected use of dynamic execution of JavaScript which may come from user-input, which can lead to Cross-Site-Scripting (XSS). Where possible avoid including user-input in functions which dynamically execute user-input. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#never_use_eval! + source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-eval-with-expression.js subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:typeform)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(tfp_[a-z0-9\-_\.=]{59})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.vault-batch-token.vault-batch-token + - javascript + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: location.href = $FUNC(...) + - pattern: location.hash = $FUNC(...) + - pattern: location.search = $FUNC(...) + - pattern: $WINDOW. ... .location.href = $FUNC(...) + - pattern: $WINDOW. ... .location.hash = $FUNC(...) + - pattern: $WINDOW. ... .location.search = $FUNC(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: eval(<... $SINK ...>) + - pattern: window.eval(<... $SINK ...>) + - pattern: new Function(<... $SINK ...>) + - pattern: new Function(<... $SINK ...>)(...) + - pattern: setTimeout(<... $SINK ...>,...) + - pattern: setInterval(<... $SINK ...>,...) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $PROP = new URLSearchParams($WINDOW. ... .location.search).get('...') + ... + - pattern-inside: | + $PROP = new URLSearchParams(location.search).get('...') + ... + - pattern-inside: | + $PROP = new URLSearchParams($WINDOW. ... .location.hash.substring(1)).get('...') + ... + - pattern-inside: | + $PROP = new URLSearchParams(location.hash.substring(1)).get('...') + ... + - focus-metavariable: $PROP + - patterns: + - pattern-either: + - pattern-inside: | + $PROPS = new URLSearchParams($WINDOW. ... .location.search) + ... + - pattern-inside: | + $PROPS = new URLSearchParams(location.search) + ... + - pattern-inside: | + $PROPS = new + URLSearchParams($WINDOW. ... .location.hash.substring(1)) + ... + - pattern-inside: | + $PROPS = new URLSearchParams(location.hash.substring(1)) + ... + - pattern: $PROPS.get('...') + - focus-metavariable: $PROPS + - patterns: + - pattern-either: + - pattern: location.href + - pattern: location.hash + - pattern: location.search + - pattern: $WINDOW. ... .location.href + - pattern: $WINDOW. ... .location.hash + - pattern: $WINDOW. ... .location.search + severity: WARNING + - id: javascript.passport-jwt.security.passport-hardcode.hardcoded-passport-secret languages: - - regex - message: A gitleaks vault-batch-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: + asvs: + control_id: 3.5.2 Static API keys or secret + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management + section: 'V3: Session Management Verification Requirements' + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - 'CWE-798: Use of Hard-coded Credentials' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - A07:2021 - Identification and Authentication Failures references: - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(hvb\.[a-z0-9_-]{138,212})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.vault-service-token.vault-service-token + - jwt + - nodejs + - secrets + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $F = require("$I").Strategy + ... + - pattern-inside: | + $F = require("$I") + ... + - pattern-inside: | + import { $STRAT as $F } from '$I' + ... + - pattern-inside: | + import $F from '$I' + ... + - metavariable-regex: + metavariable: $I + regex: (passport-.*) + - pattern-inside: | + new $F($VALUE,...) + - focus-metavariable: $VALUE + pattern-sources: + - by-side-effect: true + patterns: + - pattern-either: + - pattern: | + {..., clientSecret: "...", ...} + - pattern: | + {..., secretOrKey: "...", ...} + - pattern: | + {..., consumerSecret: "...", ...} + - patterns: + - pattern-inside: | + $OBJ = {} + ... + - pattern-either: + - pattern: | + $OBJ.clientSecret = "..." + - pattern: | + $OBJ.secretOrKey = "..." + - pattern: | + $OBJ.consumerSecret = "..." + - pattern: $OBJ + - patterns: + - pattern-inside: | + $SECRET = '...' + ... + - pattern-either: + - pattern: | + {..., clientSecret: $SECRET, ...} + - pattern: | + {..., secretOrKey: $SECRET, ...} + - pattern: | + {..., consumerSecret: $SECRET, ...} + - patterns: + - pattern-inside: | + $SECRET = '...' + ... + - pattern-either: + - pattern-inside: | + $VALUE = {..., clientSecret: $SECRET, ...} + ... + - pattern-inside: | + $VALUE = {..., secretOrKey: $SECRET, ...} + ... + - pattern-inside: | + $VALUE = {..., consumerSecret: $SECRET, ...} + ... + - pattern: $VALUE + severity: WARNING + - id: javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection languages: - - regex - message: A gitleaks vault-service-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - javascript + - typescript + message: Detected a sequelize statement that is tainted by user-input. This could lead to SQL injection if the variable is user-controlled and is not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + impact: HIGH + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://sequelize.org/docs/v6/core-concepts/raw-queries/#replacements subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)\b(hvs\.[a-z0-9_-]{90,100})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.yandex-api-key.yandex-api-key + - express + mode: taint + options: + interfile: true + pattern-sanitizers: + - pattern-either: + - pattern: parseInt(...) + - pattern: $FUNC. ... .hash(...) + pattern-sinks: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sequelize.query($QUERY,...) + - pattern: $DB.sequelize.query($QUERY,...) + - focus-metavariable: $QUERY + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: function ... ($REQ, $RES) {...} + - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} + - patterns: + - pattern-either: + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) + - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) + - metavariable-regex: + metavariable: $METHOD + regex: ^(get|post|put|head|delete|options)$ + - pattern-either: + - pattern: $REQ.query + - pattern: $REQ.body + - pattern: $REQ.params + - pattern: $REQ.cookies + - pattern: $REQ.headers + - pattern: $REQ.files.$ANYTHING.data.toString('utf8') + - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') + - patterns: + - pattern-either: + - pattern-inside: | + ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => + {...} + - pattern-inside: | + ({ $REQ }: Request,$RES: Response) => {...} + - focus-metavariable: $REQ + - pattern-either: + - pattern: params + - pattern: query + - pattern: cookies + - pattern: headers + - pattern: body + - pattern: files.$ANYTHING.data.toString('utf8') + - pattern: files.$ANYTHING['data'].toString('utf8') + severity: ERROR + - id: json.aws.security.public-s3-bucket.public-s3-bucket languages: - - regex - message: A gitleaks yandex-api-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - json + message: Detected public S3 bucket. This policy allows anyone to have some kind of access to the bucket. The exact level of access and types of actions allowed will depend on the configuration of bucket policy and ACLs. Please review the bucket configuration to make sure they are set with intended values. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM + - 'CWE-264: CWE CATEGORY: Permissions, Privileges, and Access Controls' + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html subcategory: - vuln technology: - - gitleaks + - aws patterns: - - pattern-regex: (?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(AQVN[A-Za-z0-9_\-]{35,38})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.yandex-aws-access-token.yandex-aws-access-token + - pattern-inside: | + $BUCKETNAME: { + "Type": "AWS::S3::Bucket", + "Properties": { + ..., + }, + ..., + } + - pattern-either: + - pattern: | + "PublicAccessBlockConfiguration": { + ..., + "RestrictPublicBuckets": false, + ..., + }, + - pattern: | + "PublicAccessBlockConfiguration": { + ..., + "IgnorePublicAcls": false, + ..., + }, + - pattern: | + "PublicAccessBlockConfiguration": { + ..., + "BlockPublicAcls": false, + ..., + }, + - pattern: | + "PublicAccessBlockConfiguration": { + ..., + "BlockPublicPolicy": false, + ..., + }, + severity: WARNING + - id: json.aws.security.public-s3-policy-statement.public-s3-policy-statement languages: - - regex - message: A gitleaks yandex-aws-access-token was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - json + message: Detected public S3 bucket policy. This policy allows anyone to access certain properties of or items in the bucket. Do not do this unless you will never have sensitive data inside the bucket. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM + - 'CWE-264: CWE CATEGORY: Permissions, Privileges, and Access Controls' + impact: HIGH likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteAccessPermissionsReqd.html subcategory: - vuln technology: - - gitleaks - patterns: - - pattern-regex: (?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(YC[a-zA-Z0-9_\-]{38})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.gitleaks.zendesk-secret-key.zendesk-secret-key + - aws + pattern: | + { + "Effect": "Allow", + "Principal": "*", + "Resource": [ + ..., "=~/arn:aws:s3.*/", ... + ], + ... + } + severity: WARNING + - id: json.aws.security.wildcard-assume-role.wildcard-assume-role languages: - - regex - message: A gitleaks zendesk-secret-key was detected which attempts to identify hard-coded credentials. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - json + message: 'Detected wildcard access granted to sts:AssumeRole. This means anyone with your AWS account ID and the name of the role can assume the role. Instead, limit to a specific identity in your account, like this: `arn:aws:iam:::root`.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + - 'CWE-250: Execution with Unnecessary Privileges' + impact: HIGH + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A06:2017 - Security Misconfiguration + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/zricethezav/gitleaks/tree/master/cmd/generate/config/rules + - https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/ subcategory: - vuln technology: - - gitleaks + - aws patterns: - - pattern-regex: (?i)(?:zendesk)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$) - severity: INFO - - id: generic.secrets.security.detected-amazon-mws-auth-token.detected-amazon-mws-auth-token + - pattern-inside: | + "Statement": [...] + - pattern-inside: | + {..., "Effect": "Allow", ..., "Action": "sts:AssumeRole", ...} + - pattern: | + "Principal": {..., "AWS": "*", ...} + severity: ERROR + - id: kotlin.lang.security.anonymous-ldap-bind.anonymous-ldap-bind languages: - - regex - message: Amazon MWS Auth Token detected + - kt + message: Detected anonymous LDAP bind. This permits anonymous users to execute LDAP statements. Consider enforcing authentication for LDAP. See https://docs.oracle.com/javase/tutorial/jndi/ldap/auth_mechs.html for more information. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-287: Improper Authentication' cwe2021-top25: true cwe2022-top25: true - impact: HIGH + impact: MEDIUM likelihood: LOW owasp: + - A02:2017 - Broken Authentication - A07:2021 - Identification and Authentication Failures references: - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#LDAP_ANONYMOUS subcategory: - - audit + - vuln technology: - - secrets - - aws - pattern-regex: amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} - severity: ERROR - - id: generic.secrets.security.detected-artifactory-password.detected-artifactory-password + - kotlin + pattern: | + $ENV.put($CTX.SECURITY_AUTHENTICATION, "none") + ... + $DCTX = InitialDirContext($ENV, ...) + severity: WARNING + - id: kotlin.lang.security.ecb-cipher.ecb-cipher languages: - - regex - message: Artifactory token detected + - kt + message: Cipher in ECB mode is detected. ECB mode produces the same output for the same input each time which allows an attacker to intercept and replay the data. Further, ECB mode does not provide any integrity checking. See https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/Yelp/detect-secrets/blob/master/detect_secrets/plugins/artifactory.py + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#ECB_MODE subcategory: - - audit + - vuln technology: - - secrets - - artifactory - paths: - exclude: - - '*.svg' - - '*go.sum' - - '*package.json' - - '*cargo.lock' - - '*package-lock.json' - - '*bundle.js' - - '*pnpm-lock*' - - '*Podfile.lock' - - '*/openssl/*.h' - - '*.xcscmblueprint' + - kotlin patterns: - - pattern-regex: (?\bAP[\dABCDEF][a-zA-Z0-9]{8,}) - - pattern-regex: .*(?i)arti[-_]?factory.* - - pattern-not-regex: .*(?i)sha(1|2|3|118|256|512).* - - pattern-not-regex: (?i)-----\s*?BEGIN[ A-Z0-9_-]*? KEY( BLOCK)?-----[\s\S]*?-----\s*?END[ A-Z0-9_-]*?\s*?----- - - metavariable-analysis: - analyzer: entropy - metavariable: $ITEM - - pattern-not-regex: (\w|\.|\*)\1{4} - severity: ERROR - - id: generic.secrets.security.detected-artifactory-token.detected-artifactory-token + - pattern-either: + - pattern: | + val $VAR : Cipher = $CIPHER.getInstance($MODE) + - pattern: | + var $VAR : Cipher = $CIPHER.getInstance($MODE) + - pattern: | + val $VAR = $CIPHER.getInstance($MODE) + - pattern: | + var $VAR = $CIPHER.getInstance($MODE) + - metavariable-regex: + metavariable: $MODE + regex: .*ECB.* + severity: WARNING + - id: kotlin.lang.security.no-null-cipher.no-null-cipher languages: - - regex - message: Artifactory token detected + - kt + - scala + message: 'NullCipher was detected. This will not encrypt anything; the cipher text will be the same as the plain text. Use a valid, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/Yelp/detect-secrets/blob/master/detect_secrets/plugins/artifactory.py + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#NULL_CIPHER subcategory: - - audit + - vuln technology: - - secrets - - artifactory - paths: - exclude: - - '*.svg' - - '*go.sum' - - '*package.json' - - '*package-lock.json' - - '*bundle.js' - - '*pnpm-lock*' - - '*Podfile.lock' - - '*/openssl/*.h' - - '*.xcscmblueprint' - - '*cargo.lock' - patterns: - - pattern-regex: | - \bAKC[a-zA-Z0-9]{10,} - - pattern-not-regex: | - sha(128|256|512).* - - pattern-not-regex: (?s)---BEGIN.*---\Z - severity: ERROR - - id: generic.secrets.security.detected-aws-access-key-id-value.detected-aws-access-key-id-value + - kotlin + pattern: NullCipher(...) + severity: WARNING + - id: kotlin.lang.security.use-of-md5.use-of-md5 languages: - - regex - message: AWS Access Key ID Value detected. This is a sensitive credential and should not be hardcoded here. Instead, read this value from an environment variable or keep it in a separate, private file. + - kt + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH + - 'CWE-328: Use of Weak Hash' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_MD5 subcategory: - - audit + - vuln technology: - - secrets - - aws - patterns: - - pattern-regex: \b(A3T[A-Z0-9]|AKIA|AGPA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}\b - - pattern-not-regex: (?i)example|sample|test|fake - severity: ERROR - - id: generic.secrets.security.detected-aws-account-id.detected-aws-account-id + - kotlin + pattern-either: + - pattern: | + $VAR = $MD.getInstance("MD5") + - pattern: | + $DU.getMd5Digest().digest(...) + severity: WARNING + - id: kotlin.lang.security.use-of-sha1.use-of-sha1 languages: - - generic - message: AWS Account ID detected. While not considered sensitive information, it is important to use them and share them carefully. For that reason it would be preferrable avoiding to hardcoded it here. Instead, read the value from an environment variable or keep the value in a separate, private file. + - kt + message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_SHA1 subcategory: - - audit + - vuln technology: - - secrets - - aws - patterns: - - pattern-either: - - pattern: | - $ACCOUNT_ID = $SECRET - - pattern: | - $ACCOUNT_ID : $SECRET - - pattern: | - $ACCOUNT_ID => $SECRET - - pattern: | - $ACCOUNT_ID = "$SECRET" - - pattern: | - $ACCOUNT_ID : "$SECRET" - - pattern: | - $ACCOUNT_ID => "$SECRET" - - pattern: | - "$ACCOUNT_ID" = "$SECRET" - - pattern: | - "$ACCOUNT_ID" : "$SECRET" + - kotlin + pattern-either: + - patterns: - pattern: | - "$ACCOUNT_ID" => "$SECRET" - - metavariable-analysis: - analyzer: entropy - metavariable: $SECRET - - metavariable-regex: - metavariable: $SECRET - regex: ^((?!(12345|0000).*)[0-9]{12})$ - - metavariable-regex: - metavariable: $ACCOUNT_ID - regex: (AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?("|')? - severity: ERROR - - id: generic.secrets.security.detected-aws-appsync-graphql-key.detected-aws-appsync-graphql-key + $VAR = $MD.getInstance("$ALGO") + - metavariable-regex: + metavariable: $ALGO + regex: (SHA1|SHA-1) + - pattern: | + $DU.getSha1Digest().digest(...) + severity: WARNING + - id: kotlin.lang.security.weak-rsa.use-of-weak-rsa-key languages: - - regex - message: AWS AppSync GraphQL Key detected + - kt + message: RSA keys should be at least 2048 bits based on NIST recommendation. metadata: + asvs: + control_id: 6.2.5 Insecure Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#RSA_KEY_SIZE subcategory: - audit technology: - - secrets - - appsync - pattern-regex: da2-[a-z0-9]{26} - severity: ERROR - - id: generic.secrets.security.detected-aws-secret-access-key.detected-aws-secret-access-key + - kotlin + patterns: + - pattern-either: + - pattern: | + $KEY = $G.getInstance("RSA") + ... + $KEY.initialize($BITS) + - metavariable-comparison: + comparison: $BITS < 2048 + metavariable: $BITS + severity: WARNING + - id: php.doctrine.security.audit.doctrine-orm-dangerous-query.doctrine-orm-dangerous-query languages: - - regex - message: AWS Secret Access Key detected + - php + message: '`$QUERY` Detected string concatenation with a non-literal variable in a Doctrine QueryBuilder method. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true - impact: HIGH - likelihood: LOW + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/query-builder.html#security-safely-preventing-sql-injection + - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html subcategory: - - audit + - vuln technology: - - secrets - - aws - patterns: - - pattern-regex: (("|'|`)?((?i)aws)_?\w*((?i)secret)_?\w*("|'|`)?\s{0,50}(:|=>|=)\s{0,50}("|'|`)?[A-Za-z0-9/+=]{40}("|'|`)?) - - pattern-not-regex: (?i)example|sample|test|fake|xxxxxx - severity: ERROR - - id: generic.secrets.security.detected-aws-session-token.detected-aws-session-token + - doctrine + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $SINK + - pattern-either: + - pattern: $QUERY->add(...,$SINK,...) + - pattern: $QUERY->select(...,$SINK,...) + - pattern: $QUERY->addSelect(...,$SINK,...) + - pattern: $QUERY->delete(...,$SINK,...) + - pattern: $QUERY->update(...,$SINK,...) + - pattern: $QUERY->insert(...,$SINK,...) + - pattern: $QUERY->from(...,$SINK,...) + - pattern: $QUERY->join(...,$SINK,...) + - pattern: $QUERY->innerJoin(...,$SINK,...) + - pattern: $QUERY->leftJoin(...,$SINK,...) + - pattern: $QUERY->rightJoin(...,$SINK,...) + - pattern: $QUERY->where(...,$SINK,...) + - pattern: $QUERY->andWhere(...,$SINK,...) + - pattern: $QUERY->orWhere(...,$SINK,...) + - pattern: $QUERY->groupBy(...,$SINK,...) + - pattern: $QUERY->addGroupBy(...,$SINK,...) + - pattern: $QUERY->having(...,$SINK,...) + - pattern: $QUERY->andHaving(...,$SINK,...) + - pattern: $QUERY->orHaving(...,$SINK,...) + - pattern: $QUERY->orderBy(...,$SINK,...) + - pattern: $QUERY->addOrderBy(...,$SINK,...) + - pattern: $QUERY->set($SINK,...) + - pattern: $QUERY->setValue($SINK,...) + - pattern-either: + - pattern-inside: | + $Q = $X->createQueryBuilder(); + ... + - pattern-inside: | + $Q = new QueryBuilder(...); + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern: sprintf(...) + - pattern: | + "...".$SMTH + severity: WARNING + - id: php.lang.security.assert-use.assert-use languages: - - regex - message: AWS Session Token detected + - php + message: Calling assert with user input is equivalent to eval'ing. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://www.php.net/manual/en/function.assert + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/AssertsSniff.php subcategory: - - audit + - vuln technology: - - secrets - - aws - patterns: - - pattern-regex: ((?i)AWS_SESSION_TOKEN)\s*(:|=>|=)\s*(?P[A-Za-z0-9/+=]{16,}) - - pattern-not-regex: (?i)example|sample|test|fake - - metavariable-analysis: - analyzer: entropy - metavariable: $TOKEN + - php + mode: taint + pattern-sinks: + - patterns: + - pattern: assert($SINK, ...); + - pattern-not: assert("...", ...); + - pattern: $SINK + pattern-sources: + - pattern-either: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - pattern: $_SERVER + - patterns: + - pattern: | + Route::$METHOD($ROUTENAME, function(..., $ARG, ...) { ... }) + - focus-metavariable: $ARG severity: ERROR - - id: generic.secrets.security.detected-bcrypt-hash.detected-bcrypt-hash + - id: php.lang.security.base-convert-loses-precision.base-convert-loses-precision languages: - - regex - message: bcrypt hash detected + - php + message: The function base_convert uses 64-bit numbers internally, and does not correctly convert large numbers. It is not suitable for random tokens such as those used for session tokens or CSRF tokens. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH + - 'CWE-190: Integer Overflow or Wraparound' + impact: LOW likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + - https://www.php.net/base_convert + - https://www.sjoerdlangkemper.nl/2017/03/15/dont-use-base-convert-on-random-tokens/ subcategory: - audit technology: - - secrets - - bcrypt - pattern-regex: \$2[aby]?\$[\d]+\$[./A-Za-z0-9]{53} - severity: ERROR - - id: generic.secrets.security.detected-codeclimate.detected-codeclimate + - php + mode: taint + pattern-sanitizers: + - patterns: + - pattern: substr(..., $LENGTH) + - metavariable-comparison: + comparison: $LENGTH <= 7 + metavariable: $LENGTH + pattern-sinks: + - pattern: base_convert(...) + pattern-sources: + - pattern: hash(...) + - pattern: hash_hmac(...) + - pattern: sha1(...) + - pattern: md5(...) + - patterns: + - pattern: random_bytes($N) + - metavariable-comparison: + comparison: $N > 7 + metavariable: $N + - patterns: + - pattern: openssl_random_pseudo_bytes($N) + - metavariable-comparison: + comparison: $N > 7 + metavariable: $N + - patterns: + - pattern: $OBJ->get_random_bytes($N) + - metavariable-comparison: + comparison: $N > 7 + metavariable: $N + severity: WARNING + - id: php.lang.security.curl-ssl-verifypeer-off.curl-ssl-verifypeer-off languages: - - regex - message: CodeClimate detected + - php + message: SSL verification is disabled but should not be (currently CURLOPT_SSL_VERIFYPEER= $IS_VERIFIED) metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW likelihood: LOW owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://www.saotn.org/dont-turn-off-curlopt_ssl_verifypeer-fix-php-configuration/ subcategory: - - audit + - vuln technology: - - secrets - - codeclimate - pattern-regex: (?i)codeclima.{0,50}["|'|`]?[0-9a-f]{64}["|'|`]? + - php + patterns: + - pattern-either: + - pattern: | + $ARG = $IS_VERIFIED; + ... + curl_setopt(..., CURLOPT_SSL_VERIFYPEER, $ARG); + - pattern: curl_setopt(..., CURLOPT_SSL_VERIFYPEER, $IS_VERIFIED) + - metavariable-regex: + metavariable: $IS_VERIFIED + regex: 0|false|null severity: ERROR - - id: generic.secrets.security.detected-etc-shadow.detected-etc-shadow + - id: php.lang.security.deserialization.extract-user-data languages: - - regex - message: linux shadow file detected + - php + message: Do not call 'extract()' on user-controllable data. If you must, then you must also provide the EXTR_SKIP flag to prevent overwriting existing variables. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-502: Deserialization of Untrusted Data' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + - https://www.php.net/manual/en/function.extract.php#refsect1-function.extract-notes subcategory: - - audit + - vuln technology: - - secrets - patterns: - - pattern-regex: ^(\s*)(?Proot:[x!*]*:[0-9]*:[0-9]*) - - focus-metavariable: $ROOT + - php + mode: taint + pattern-sanitizers: + - pattern: extract($VAR, EXTR_SKIP,...) + pattern-sinks: + - pattern: extract(...) + pattern-sources: + - pattern-either: + - pattern: $_GET[...] + - pattern: $_FILES[...] + - pattern: $_POST[...] severity: ERROR - - id: generic.secrets.security.detected-facebook-access-token.detected-facebook-access-token + - fix: echo htmlentities($...VARS); + id: php.lang.security.injection.echoed-request.echoed-request languages: - - regex - message: Facebook Access Token detected + - php + message: '`Echo`ing user input risks cross-site scripting vulnerability. You should use `htmlentities()` when showing data to users.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://www.php.net/manual/en/function.htmlentities.php + - https://www.php.net/manual/en/reserved.variables.request.php + - https://www.php.net/manual/en/reserved.variables.post.php + - https://www.php.net/manual/en/reserved.variables.get.php + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html subcategory: - - audit + - vuln technology: - - secrets - - facebook - pattern-either: - - pattern-regex: EAACEdEose0cBA[0-9A-Za-z]+ - - pattern-regex: EAAAACZAVC6ygB[0-9A-Za-z]+ - - pattern-regex: EAAAAZAw4[0-9A-Za-z]+ + - php + mode: taint + pattern-sanitizers: + - pattern: htmlentities(...) + - pattern: htmlspecialchars(...) + - pattern: strip_tags(...) + - pattern: isset(...) + - pattern: empty(...) + - pattern: esc_html(...) + - pattern: esc_attr(...) + - pattern: wp_kses(...) + - pattern: e(...) + - pattern: twig_escape_filter(...) + - pattern: xss_clean(...) + - pattern: html_escape(...) + - pattern: Html::escape(...) + - pattern: Xss::filter(...) + - pattern: escapeHtml(...) + - pattern: escapeHtml(...) + - pattern: escapeHtmlAttr(...) + pattern-sinks: + - pattern: echo $...VARS; + pattern-sources: + - pattern: $_REQUEST + - pattern: $_GET + - pattern: $_POST severity: ERROR - - id: generic.secrets.security.detected-facebook-oauth.detected-facebook-oauth + - fix: print(htmlentities($...VARS)); + id: php.lang.security.injection.printed-request.printed-request languages: - - regex - message: Facebook OAuth detected + - php + message: '`Printing user input risks cross-site scripting vulnerability. You should use `htmlentities()` when showing data to users.' metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://www.php.net/manual/en/function.htmlentities.php + - https://www.php.net/manual/en/reserved.variables.request.php + - https://www.php.net/manual/en/reserved.variables.post.php + - https://www.php.net/manual/en/reserved.variables.get.php + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html subcategory: - - audit + - vuln technology: - - secrets - - facebook - pattern-regex: '[fF][aA][cC][eE][bB][oO][oO][kK].*[tT][oO][kK][eE][nN].*[''|"]?[0-9a-f]{32}[''|"]?' + - php + mode: taint + pattern-sanitizers: + - pattern: htmlentities(...) + - pattern: htmlspecialchars(...) + - pattern: strip_tags(...) + - pattern: isset(...) + - pattern: empty(...) + - pattern: esc_html(...) + - pattern: esc_attr(...) + - pattern: wp_kses(...) + - pattern: e(...) + - pattern: twig_escape_filter(...) + - pattern: xss_clean(...) + - pattern: html_escape(...) + - pattern: Html::escape(...) + - pattern: Xss::filter(...) + - pattern: escapeHtml(...) + - pattern: escapeHtml(...) + - pattern: escapeHtmlAttr(...) + pattern-sinks: + - pattern: print($...VARS); + pattern-sources: + - pattern: $_REQUEST + - pattern: $_GET + - pattern: $_POST severity: ERROR - - id: generic.secrets.security.detected-generic-api-key.detected-generic-api-key + - id: php.lang.security.injection.tainted-filename.tainted-filename languages: - - regex - message: Generic API Key detected + - php + message: File name based on user input risks server-side request forgery. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-918: Server-Side Request Forgery (SSRF)' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A10:2021 - Server-Side Request Forgery (SSRF) references: - - https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://owasp.org/Top10/A10_2021-Server-Side_Request_Forgery_%28SSRF%29 subcategory: - - audit + - vuln technology: - - secrets - patterns: - - pattern-regex: '[aA][pP][iI]_?[kK][eE][yY][=_:\s-]+[''|"]?(?[0-9a-zA-Z]{32,45})[''|"]?' - - metavariable-analysis: - analyzer: entropy - metavariable: $SECRET - severity: ERROR - - id: generic.secrets.security.detected-generic-secret.detected-generic-secret + - php + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern-inside: basename($PATH, ...) + - pattern-inside: linkinfo($PATH, ...) + - pattern-inside: readlink($PATH, ...) + - pattern-inside: realpath($PATH, ...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: opcache_compile_file($FILENAME, ...) + - pattern-inside: opcache_invalidate($FILENAME, ...) + - pattern-inside: opcache_is_script_cached($FILENAME, ...) + - pattern-inside: runkit7_import($FILENAME, ...) + - pattern-inside: readline_read_history($FILENAME, ...) + - pattern-inside: readline_write_history($FILENAME, ...) + - pattern-inside: rar_open($FILENAME, ...) + - pattern-inside: zip_open($FILENAME, ...) + - pattern-inside: gzfile($FILENAME, ...) + - pattern-inside: gzopen($FILENAME, ...) + - pattern-inside: readgzfile($FILENAME, ...) + - pattern-inside: hash_file($ALGO, $FILENAME, ...) + - pattern-inside: hash_update_file($CONTEXT, $FILENAME, ...) + - pattern-inside: pg_trace($FILENAME, ...) + - pattern-inside: dio_open($FILENAME, ...) + - pattern-inside: finfo_file($FINFO, $FILENAME, ...) + - pattern-inside: mime_content_type($FILENAME, ...) + - pattern-inside: chgrp($FILENAME, ...) + - pattern-inside: chmod($FILENAME, ...) + - pattern-inside: chown($FILENAME, ...) + - pattern-inside: clearstatcache($CLEAR_REALPATH_CACHE, $FILENAME, ...) + - pattern-inside: file_exists($FILENAME, ...) + - pattern-inside: file_get_contents($FILENAME, ...) + - pattern-inside: file_put_contents($FILENAME, ...) + - pattern-inside: file($FILENAME, ...) + - pattern-inside: fileatime($FILENAME, ...) + - pattern-inside: filectime($FILENAME, ...) + - pattern-inside: filegroup($FILENAME, ...) + - pattern-inside: fileinode($FILENAME, ...) + - pattern-inside: filemtime($FILENAME, ...) + - pattern-inside: fileowner($FILENAME, ...) + - pattern-inside: fileperms($FILENAME, ...) + - pattern-inside: filesize($FILENAME, ...) + - pattern-inside: filetype($FILENAME, ...) + - pattern-inside: fnmatch($PATTERN, $FILENAME, ...) + - pattern-inside: fopen($FILENAME, ...) + - pattern-inside: is_dir($FILENAME, ...) + - pattern-inside: is_executable($FILENAME, ...) + - pattern-inside: is_file($FILENAME, ...) + - pattern-inside: is_link($FILENAME, ...) + - pattern-inside: is_readable($FILENAME, ...) + - pattern-inside: is_uploaded_file($FILENAME, ...) + - pattern-inside: is_writable($FILENAME, ...) + - pattern-inside: lchgrp($FILENAME, ...) + - pattern-inside: lchown($FILENAME, ...) + - pattern-inside: lstat($FILENAME, ...) + - pattern-inside: parse_ini_file($FILENAME, ...) + - pattern-inside: readfile($FILENAME, ...) + - pattern-inside: stat($FILENAME, ...) + - pattern-inside: touch($FILENAME, ...) + - pattern-inside: unlink($FILENAME, ...) + - pattern-inside: xattr_get($FILENAME, ...) + - pattern-inside: xattr_list($FILENAME, ...) + - pattern-inside: xattr_remove($FILENAME, ...) + - pattern-inside: xattr_set($FILENAME, ...) + - pattern-inside: xattr_supported($FILENAME, ...) + - pattern-inside: enchant_broker_request_pwl_dict($BROKER, $FILENAME, ...) + - pattern-inside: pspell_config_personal($CONFIG, $FILENAME, ...) + - pattern-inside: pspell_config_repl($CONFIG, $FILENAME, ...) + - pattern-inside: pspell_new_personal($FILENAME, ...) + - pattern-inside: exif_imagetype($FILENAME, ...) + - pattern-inside: getimagesize($FILENAME, ...) + - pattern-inside: image2wbmp($IMAGE, $FILENAME, ...) + - pattern-inside: imagecreatefromavif($FILENAME, ...) + - pattern-inside: imagecreatefrombmp($FILENAME, ...) + - pattern-inside: imagecreatefromgd2($FILENAME, ...) + - pattern-inside: imagecreatefromgd2part($FILENAME, ...) + - pattern-inside: imagecreatefromgd($FILENAME, ...) + - pattern-inside: imagecreatefromgif($FILENAME, ...) + - pattern-inside: imagecreatefromjpeg($FILENAME, ...) + - pattern-inside: imagecreatefrompng($FILENAME, ...) + - pattern-inside: imagecreatefromtga($FILENAME, ...) + - pattern-inside: imagecreatefromwbmp($FILENAME, ...) + - pattern-inside: imagecreatefromwebp($FILENAME, ...) + - pattern-inside: imagecreatefromxbm($FILENAME, ...) + - pattern-inside: imagecreatefromxpm($FILENAME, ...) + - pattern-inside: imageloadfont($FILENAME, ...) + - pattern-inside: imagexbm($IMAGE, $FILENAME, ...) + - pattern-inside: iptcembed($IPTC_DATA, $FILENAME, ...) + - pattern-inside: mailparse_msg_extract_part_file($MIMEMAIL, $FILENAME, ...) + - pattern-inside: mailparse_msg_extract_whole_part_file($MIMEMAIL, $FILENAME, ...) + - pattern-inside: mailparse_msg_parse_file($FILENAME, ...) + - pattern-inside: fdf_add_template($FDF_DOCUMENT, $NEWPAGE, $FILENAME, ...) + - pattern-inside: fdf_get_ap($FDF_DOCUMENT, $FIELD, $FACE, $FILENAME, ...) + - pattern-inside: fdf_open($FILENAME, ...) + - pattern-inside: fdf_save($FDF_DOCUMENT, $FILENAME, ...) + - pattern-inside: fdf_set_ap($FDF_DOCUMENT, $FIELD_NAME, $FACE, $FILENAME, ...) + - pattern-inside: ps_add_launchlink($PSDOC, $LLX, $LLY, $URX, $URY, $FILENAME, ...) + - pattern-inside: ps_add_pdflink($PSDOC, $LLX, $LLY, $URX, $URY, $FILENAME, ...) + - pattern-inside: ps_open_file($PSDOC, $FILENAME, ...) + - pattern-inside: ps_open_image_file($PSDOC, $TYPE, $FILENAME, ...) + - pattern-inside: posix_access($FILENAME, ...) + - pattern-inside: posix_mkfifo($FILENAME, ...) + - pattern-inside: posix_mknod($FILENAME, ...) + - pattern-inside: ftok($FILENAME, ...) + - pattern-inside: fann_cascadetrain_on_file($ANN, $FILENAME, ...) + - pattern-inside: fann_read_train_from_file($FILENAME, ...) + - pattern-inside: fann_train_on_file($ANN, $FILENAME, ...) + - pattern-inside: highlight_file($FILENAME, ...) + - pattern-inside: php_strip_whitespace($FILENAME, ...) + - pattern-inside: stream_resolve_include_path($FILENAME, ...) + - pattern-inside: swoole_async_read($FILENAME, ...) + - pattern-inside: swoole_async_readfile($FILENAME, ...) + - pattern-inside: swoole_async_write($FILENAME, ...) + - pattern-inside: swoole_async_writefile($FILENAME, ...) + - pattern-inside: swoole_load_module($FILENAME, ...) + - pattern-inside: tidy_parse_file($FILENAME, ...) + - pattern-inside: tidy_repair_file($FILENAME, ...) + - pattern-inside: get_meta_tags($FILENAME, ...) + - pattern-inside: yaml_emit_file($FILENAME, ...) + - pattern-inside: yaml_parse_file($FILENAME, ...) + - pattern-inside: curl_file_create($FILENAME, ...) + - pattern-inside: ftp_chmod($FTP, $PERMISSIONS, $FILENAME, ...) + - pattern-inside: ftp_delete($FTP, $FILENAME, ...) + - pattern-inside: ftp_mdtm($FTP, $FILENAME, ...) + - pattern-inside: ftp_size($FTP, $FILENAME, ...) + - pattern-inside: rrd_create($FILENAME, ...) + - pattern-inside: rrd_fetch($FILENAME, ...) + - pattern-inside: rrd_graph($FILENAME, ...) + - pattern-inside: rrd_info($FILENAME, ...) + - pattern-inside: rrd_last($FILENAME, ...) + - pattern-inside: rrd_lastupdate($FILENAME, ...) + - pattern-inside: rrd_tune($FILENAME, ...) + - pattern-inside: rrd_update($FILENAME, ...) + - pattern-inside: snmp_read_mib($FILENAME, ...) + - pattern-inside: ssh2_sftp_chmod($SFTP, $FILENAME, ...) + - pattern-inside: ssh2_sftp_realpath($SFTP, $FILENAME, ...) + - pattern-inside: ssh2_sftp_unlink($SFTP, $FILENAME, ...) + - pattern-inside: apache_lookup_uri($FILENAME, ...) + - pattern-inside: md5_file($FILENAME, ...) + - pattern-inside: sha1_file($FILENAME, ...) + - pattern-inside: simplexml_load_file($FILENAME, ...) + - pattern: $FILENAME + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - pattern: $_SERVER + severity: WARNING + - id: php.lang.security.injection.tainted-object-instantiation.tainted-object-instantiation languages: - - regex - message: Generic Secret detected + - php + message: <- A new object is created where the class name is based on user input. This could lead to remote code execution, as it allows to instantiate any class in the application. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-470: Use of Externally-Controlled Input to Select Classes or Code (''Unsafe Reflection'')' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2021 - Injection references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://owasp.org/Top10/A03_2021-Injection subcategory: - - audit + - vuln technology: - - secrets - patterns: - - pattern-regex: '[sS][eE][cC][rR][eE][tT][:= \t]*[''|\"]?(?[0-9a-zA-Z]{32,45})[''|\"]?' - - metavariable-analysis: - analyzer: entropy - metavariable: $SECRET - severity: ERROR - - id: generic.secrets.security.detected-github-token.detected-github-token + - php + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: new $SINK(...) + - pattern: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - pattern: $_SERVER + severity: WARNING + - id: php.lang.security.injection.tainted-session.tainted-session languages: - - generic - message: GitHub Token detected + - php + message: Session key based on user input risks session poisoning. The user can determine the key used for the session, and thus write any session variable. Session variables are typically trusted to be set only by the application, and manipulating the session can result in access control issues. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-284: Improper Access Control' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.blog/changelog/2021-03-04-authentication-token-format-updates/ + - https://en.wikipedia.org/wiki/Session_poisoning subcategory: - - audit + - vuln technology: - - secrets - - github - patterns: - - pattern-either: - - pattern: | - $VAR = $SECRET - - pattern: | - $VAR: $SECRET - - pattern: | - $VAR = '$SECRET' - - pattern: | - $VAR: '$SECRET' - - pattern: | - '$VAR' = '$SECRET' - - pattern: | - '$VAR': '$SECRET' - - pattern: | - "[hH][tT][tT][pP][sS]?://.*$SECRET.*" - - metavariable-regex: - metavariable: $SECRET - regex: gh[pousr]_[A-Za-z0-9_]{36,251} - - metavariable-analysis: - analyzer: entropy - metavariable: $SECRET - severity: ERROR - - id: generic.secrets.security.detected-google-api-key.detected-google-api-key + - php + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: $A . $B + - pattern: bin2hex(...) + - pattern: crc32(...) + - pattern: crypt(...) + - pattern: filter_input(...) + - pattern: filter_var(...) + - pattern: hash(...) + - pattern: md5(...) + - pattern: preg_filter(...) + - pattern: preg_grep(...) + - pattern: preg_match_all(...) + - pattern: sha1(...) + - pattern: sprintf(...) + - pattern: str_contains(...) + - pattern: str_ends_with(...) + - pattern: str_starts_with(...) + - pattern: strcasecmp(...) + - pattern: strchr(...) + - pattern: stripos(...) + - pattern: stristr(...) + - pattern: strnatcasecmp(...) + - pattern: strnatcmp(...) + - pattern: strncmp(...) + - pattern: strpbrk(...) + - pattern: strpos(...) + - pattern: strripos(...) + - pattern: strrpos(...) + - pattern: strspn(...) + - pattern: strstr(...) + - pattern: strtok(...) + - pattern: substr_compare(...) + - pattern: substr_count(...) + - pattern: vsprintf(...) + pattern-sinks: + - patterns: + - pattern-inside: $_SESSION[$KEY] = $VAL; + - pattern: $KEY + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + severity: WARNING + - id: php.lang.security.injection.tainted-sql-string.tainted-sql-string languages: - - regex - message: Google API Key Detected + - php + message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`$mysqli->prepare("INSERT INTO test(id, label) VALUES (?, ?)");`) or a safe library. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://owasp.org/www-community/attacks/SQL_Injection subcategory: - - audit + - vuln technology: - - secrets - - google - patterns: - - pattern-regex: \bAIzaSy[0-9A-Za-z-_]{33}\b - - pattern-not-regex: \bAIzaSy[0-9A-Za-z-_]{33}\b[=] - severity: ERROR - - id: generic.secrets.security.detected-google-cloud-api-key.detected-google-cloud-api-key - languages: - - regex - message: Google Cloud API Key detected - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go - subcategory: - - audit - technology: - - secrets - - google-cloud - pattern-regex: AIza[0-9A-Za-z\\-_]{35} + - php + mode: taint + pattern-sanitizers: + - pattern-either: + - pattern: mysqli_real_escape_string(...) + - pattern: real_escape_string(...) + - pattern: $MYSQLI->real_escape_string(...) + pattern-sinks: + - pattern-either: + - patterns: + - pattern: | + sprintf($SQLSTR, ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - patterns: + - pattern: | + "...$EXPR..." + - metavariable-regex: + metavariable: $EXPR + regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - patterns: + - pattern: | + "$SQLSTR".$EXPR + - metavariable-regex: + metavariable: $SQLSTR + regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST severity: ERROR - - id: generic.secrets.security.detected-google-gcm-service-account.detected-google-gcm-service-account + - id: php.lang.security.injection.tainted-url-host.tainted-url-host languages: - - regex - message: Google (GCM) Service account detected + - php + message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-918: Server-Side Request Forgery (SSRF)' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A10:2021 - Server-Side Request Forgery (SSRF) references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html subcategory: - - audit + - vuln technology: - - secrets - - google-cloud - pattern-regex: (("|'|`)?type("|'|`)?\s{0,50}(:|=>|=)\s{0,50}("|'|`)?service_account("|'|`)?,?) - severity: ERROR - - id: generic.secrets.security.detected-google-oauth-access-token.detected-google-oauth-access-token + - php + mode: taint + pattern-sinks: + - pattern-either: + - patterns: + - pattern: | + sprintf($URLSTR, ...) + - metavariable-pattern: + language: generic + metavariable: $URLSTR + pattern: $SCHEME://%s + - patterns: + - pattern: | + "...{$EXPR}..." + - pattern-regex: | + .*://\{.* + - patterns: + - pattern: | + "...$EXPR..." + - pattern-regex: | + .*://\$.* + - patterns: + - pattern: | + "...".$EXPR + - pattern-regex: | + .*://["'].* + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + severity: WARNING + - id: php.lang.security.md5-used-as-password.md5-used-as-password languages: - - regex - message: Google OAuth Access Token detected + - php + message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as bcrypt. You can use `password_hash($PASSWORD, PASSWORD_BCRYPT, $OPTIONS);`. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://tools.ietf.org/html/rfc6151 + - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision + - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords + - https://github.com/returntocorp/semgrep-rules/issues/1609 + - https://www.php.net/password_hash subcategory: - - audit + - vuln technology: - - secrets - - google - pattern-regex: ya29\.[0-9A-Za-z\-_]+ - severity: ERROR - - id: generic.secrets.security.detected-google-oauth.detected-google-oauth-url + - md5 + mode: taint + pattern-sinks: + - patterns: + - pattern: $FUNCTION(...) + - metavariable-regex: + metavariable: $FUNCTION + regex: (?i)(.*password.*) + pattern-sources: + - patterns: + - pattern-either: + - pattern: md5(...) + - pattern: hash('md5', ...) + severity: WARNING + - id: php.lang.security.openssl-cbc-static-iv.openssl-cbc-static-iv languages: - - regex - message: Google OAuth url detected + - php + message: Static IV used with AES in CBC mode. Static IVs enable chosen-plaintext attacks against encrypted data. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-329: Generation of Predictable IV with CBC Mode' impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://csrc.nist.gov/publications/detail/sp/800-38a/final subcategory: - - audit + - vuln technology: - - secrets - - google - pattern-regex: '[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com' + - php + - openssl + patterns: + - pattern-either: + - pattern: openssl_encrypt($D, $M, $K, $FLAGS, "...",...); + - pattern: openssl_decrypt($D, $M, $K, $FLAGS, "...",...); + - metavariable-comparison: + comparison: re.match(".*-CBC",$M) + metavariable: $M severity: ERROR - - id: generic.secrets.security.detected-heroku-api-key.detected-heroku-api-key + - id: php.lang.security.phpinfo-use.phpinfo-use languages: - - regex - message: Heroku API Key detected + - php + message: The 'phpinfo' function may reveal sensitive information about your environment. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' cwe2021-top25: true - cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2021 - Broken Access Control references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://www.php.net/manual/en/function.phpinfo + - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/PhpinfosSniff.php subcategory: - - audit + - vuln technology: - - secrets - - heroku - pattern-regex: '[hH][eE][rR][oO][kK][uU].*[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}' + - php + pattern: phpinfo(...); severity: ERROR - - id: generic.secrets.security.detected-hockeyapp.detected-hockeyapp + - id: php.lang.security.redirect-to-request-uri.redirect-to-request-uri languages: - - regex - message: HockeyApp detected + - php + message: Redirecting to the current request URL may redirect to another domain, if the current path starts with two slashes. E.g. in https://www.example.com//attacker.com, the value of REQUEST_URI is //attacker.com, and redirecting to it will redirect to that domain. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: LOW + likelihood: MEDIUM owasp: - - A07:2021 - Identification and Authentication Failures + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://www.php.net/manual/en/reserved.variables.server.php + - https://owasp.org/www-project-top-ten/2017/A5_2017-Broken_Access_Control.html subcategory: - - audit + - vuln technology: - - secrets - - hockeyapp - pattern-regex: (?i)hockey.{0,50}(\\\"|'|`)?[0-9a-f]{32}(\\\"|'|`)? - severity: ERROR - - id: generic.secrets.security.detected-jwt-token.detected-jwt-token + - php + patterns: + - pattern-either: + - pattern: | + header('$LOCATION' . $_SERVER['REQUEST_URI']); + - pattern: | + header('$LOCATION' . $_SERVER['REQUEST_URI'] . $MORE); + - metavariable-regex: + metavariable: $LOCATION + regex: ^(?i)location:\s*$ + severity: WARNING + - id: php.lang.security.tainted-exec.tainted-exec languages: - - regex - message: JWT token detected + - php + message: Executing non-constant commands. This can lead to command injection. You should use `escapeshellarg()` when using command. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-321: Use of Hard-coded Cryptographic Key' - impact: MEDIUM - likelihood: LOW + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: HIGH owasp: - - A02:2021 - Cryptographic Failures + - A03:2021 - Injection references: - - https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - source-rule-url: https://github.com/Yelp/detect-secrets/blob/master/detect_secrets/plugins/jwt.py + - https://www.stackhawk.com/blog/php-command-injection/ + - https://brightsec.com/blog/code-injection-php/ + - https://www.acunetix.com/websitesecurity/php-security-2/ subcategory: - - audit + - vuln technology: - - secrets - - jwt - pattern-regex: eyJ[A-Za-z0-9-_=]{14,}\.[A-Za-z0-9-_=]{13,}\.?[A-Za-z0-9-_.+/=]*? + - php + mode: taint + pattern-sanitizers: + - pattern: escapeshellarg(...) + pattern-sinks: + - pattern: exec(...) + - pattern: system(...) + - pattern: popen(...) + - pattern: passthru(...) + - pattern: shell_exec(...) + - pattern: pcntl_exec(...) + - pattern: proc_open(...) + pattern-sources: + - pattern: $_REQUEST + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE severity: ERROR - - id: generic.secrets.security.detected-kolide-api-key.detected-kolide-api-key + - id: php.laravel.security.laravel-api-route-sql-injection.laravel-api-route-sql-injection languages: - - regex - message: Kolide API Key detected + - php + message: HTTP method [$METHOD] to Laravel route $ROUTE_NAME is vulnerable to SQL injection via string concatenation or unsafe interpolation. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + - https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Laravel_Cheat_Sheet.md subcategory: - - audit + - vuln technology: - - secrets - - kolide - pattern-regex: k2sk_v[0-9]_[0-9a-zA-Z]{24} - severity: ERROR - - id: generic.secrets.security.detected-mailchimp-api-key.detected-mailchimp-api-key + - php + - laravel + mode: taint + pattern-sanitizers: + - patterns: + - pattern: | + DB::raw("...",[...]) + pattern-sinks: + - patterns: + - pattern: | + DB::raw(...) + pattern-sources: + - patterns: + - focus-metavariable: $ARG + - pattern-inside: | + Route::$METHOD($ROUTE_NAME, function(...,$ARG,...){...}) + severity: WARNING + - id: php.laravel.security.laravel-sql-injection.laravel-sql-injection languages: - - regex - message: MailChimp API Key detected + - php + message: Detected a SQL query based on user input. This could lead to SQL injection, which could potentially result in sensitive data being exfiltrated by attackers. Instead, use parameterized queries and prepared statements. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://laravel.com/docs/8.x/queries subcategory: - - audit + - vuln technology: - - secrets - - mailchimp - pattern-regex: '[0-9a-f]{32}-us[0-9]{1,2}' - severity: ERROR - - id: generic.secrets.security.detected-mailgun-api-key.detected-mailgun-api-key + - laravel + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: $SQL + - pattern-either: + - pattern-inside: DB::table(...)->whereRaw($SQL, ...) + - pattern-inside: DB::table(...)->orWhereRaw($SQL, ...) + - pattern-inside: DB::table(...)->groupByRaw($SQL, ...) + - pattern-inside: DB::table(...)->havingRaw($SQL, ...) + - pattern-inside: DB::table(...)->orHavingRaw($SQL, ...) + - pattern-inside: DB::table(...)->orderByRaw($SQL, ...) + - patterns: + - pattern: $EXPRESSION + - pattern-either: + - pattern-inside: DB::table(...)->selectRaw($EXPRESSION, ...) + - pattern-inside: DB::table(...)->fromRaw($EXPRESSION, ...) + - patterns: + - pattern: $COLUMNS + - pattern-either: + - pattern-inside: DB::table(...)->whereNull($COLUMNS, ...) + - pattern-inside: DB::table(...)->orWhereNull($COLUMN) + - pattern-inside: DB::table(...)->whereNotNull($COLUMNS, ...) + - pattern-inside: DB::table(...)->whereRowValues($COLUMNS, ...) + - pattern-inside: DB::table(...)->orWhereRowValues($COLUMNS, ...) + - pattern-inside: DB::table(...)->find($ID, $COLUMNS) + - pattern-inside: DB::table(...)->paginate($PERPAGE, $COLUMNS, ...) + - pattern-inside: DB::table(...)->simplePaginate($PERPAGE, $COLUMNS, ...) + - pattern-inside: DB::table(...)->cursorPaginate($PERPAGE, $COLUMNS, ...) + - pattern-inside: DB::table(...)->getCountForPagination($COLUMNS) + - pattern-inside: DB::table(...)->aggregate($FUNCTION, $COLUMNS) + - pattern-inside: DB::table(...)->numericAggregate($FUNCTION, $COLUMNS) + - pattern-inside: DB::table(...)->insertUsing($COLUMNS, ...) + - pattern-inside: DB::table(...)->select($COLUMNS) + - pattern-inside: DB::table(...)->get($COLUMNS) + - pattern-inside: DB::table(...)->count($COLUMNS) + - patterns: + - pattern: $COLUMN + - pattern-either: + - pattern-inside: DB::table(...)->whereIn($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereIn($COLUMN, ...) + - pattern-inside: DB::table(...)->whereNotIn($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereNotIn($COLUMN, ...) + - pattern-inside: DB::table(...)->whereIntegerInRaw($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereIntegerInRaw($COLUMN, ...) + - pattern-inside: DB::table(...)->whereIntegerNotInRaw($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereIntegerNotInRaw($COLUMN, ...) + - pattern-inside: DB::table(...)->whereBetweenColumns($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereBetween($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereBetweenColumns($COLUMN, ...) + - pattern-inside: DB::table(...)->whereNotBetween($COLUMN, ...) + - pattern-inside: DB::table(...)->whereNotBetweenColumns($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereNotBetween($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereNotBetweenColumns($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereNotNull($COLUMN) + - pattern-inside: DB::table(...)->whereDate($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereDate($COLUMN, ...) + - pattern-inside: DB::table(...)->whereTime($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereTime($COLUMN, ...) + - pattern-inside: DB::table(...)->whereDay($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereDay($COLUMN, ...) + - pattern-inside: DB::table(...)->whereMonth($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereMonth($COLUMN, ...) + - pattern-inside: DB::table(...)->whereYear($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereYear($COLUMN, ...) + - pattern-inside: DB::table(...)->whereJsonContains($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereJsonContains($COLUMN, ...) + - pattern-inside: DB::table(...)->whereJsonDoesntContain($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereJsonDoesntContain($COLUMN, ...) + - pattern-inside: DB::table(...)->whereJsonLength($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhereJsonLength($COLUMN, ...) + - pattern-inside: DB::table(...)->having($COLUMN, ...) + - pattern-inside: DB::table(...)->orHaving($COLUMN, ...) + - pattern-inside: DB::table(...)->havingBetween($COLUMN, ...) + - pattern-inside: DB::table(...)->orderBy($COLUMN, ...) + - pattern-inside: DB::table(...)->orderByDesc($COLUMN) + - pattern-inside: DB::table(...)->latest($COLUMN) + - pattern-inside: DB::table(...)->oldest($COLUMN) + - pattern-inside: DB::table(...)->forPageBeforeId($PERPAGE, $LASTID, $COLUMN) + - pattern-inside: DB::table(...)->forPageAfterId($PERPAGE, $LASTID, $COLUMN) + - pattern-inside: DB::table(...)->value($COLUMN) + - pattern-inside: DB::table(...)->pluck($COLUMN, ...) + - pattern-inside: DB::table(...)->implode($COLUMN, ...) + - pattern-inside: DB::table(...)->min($COLUMN) + - pattern-inside: DB::table(...)->max($COLUMN) + - pattern-inside: DB::table(...)->sum($COLUMN) + - pattern-inside: DB::table(...)->avg($COLUMN) + - pattern-inside: DB::table(...)->average($COLUMN) + - pattern-inside: DB::table(...)->increment($COLUMN, ...) + - pattern-inside: DB::table(...)->decrement($COLUMN, ...) + - pattern-inside: DB::table(...)->where($COLUMN, ...) + - pattern-inside: DB::table(...)->orWhere($COLUMN, ...) + - pattern-inside: DB::table(...)->addSelect($COLUMN) + - patterns: + - pattern: $QUERY + - pattern-inside: DB::unprepared($QUERY) + pattern-sources: + - patterns: + - pattern-either: + - pattern: $_GET + - pattern: $_POST + - pattern: $_COOKIE + - pattern: $_REQUEST + - pattern: $_SERVER + severity: WARNING + - id: php.laravel.security.laravel-unsafe-validator.laravel-unsafe-validator languages: - - regex - message: Mailgun API Key detected + - php + message: Found a request argument passed to an `ignore()` definition in a Rule constraint. This can lead to SQL injection. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - likelihood: LOW + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://laravel.com/docs/9.x/validation#rule-unique subcategory: - - audit + - vuln technology: - - secrets - - mailgun - pattern-regex: key-[0-9a-zA-Z]{32} + - php + - laravel + mode: taint + pattern-sinks: + - patterns: + - pattern: | + Illuminate\Validation\Rule::unique(...)->ignore(...,$IGNORE,...) + - focus-metavariable: $IGNORE + pattern-sources: + - patterns: + - pattern: | + public function $F(...,Request $R,...){...} + - focus-metavariable: $R + - patterns: + - pattern-either: + - pattern: | + $this->$PROPERTY + - pattern: | + $this->$PROPERTY->$GET + - metavariable-pattern: + metavariable: $PROPERTY + patterns: + - pattern-either: + - pattern: query + - pattern: request + - pattern: headers + - pattern: cookies + - pattern: cookie + - pattern: files + - pattern: file + - pattern: allFiles + - pattern: input + - pattern: all + - pattern: post + - pattern: json + - pattern-either: + - pattern-inside: | + class $CL extends Illuminate\Http\Request {...} + - pattern-inside: | + class $CL extends Illuminate\Foundation\Http\FormRequest {...} severity: ERROR - - id: generic.secrets.security.detected-npm-registry-auth-token.detected-npm-registry-auth-token + - id: problem-based-packs.insecure-transport.go-stdlib.bypass-tls-verification.bypass-tls-verification languages: - - generic - message: NPM registry authentication token detected + - go + message: Checks for disabling of TLS/SSL certificate verification. This should only be used for debugging purposes because it leads to vulnerability to MTM attacks. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: HIGH + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + - https://stackoverflow.com/questions/12122159/how-to-do-a-https-request-with-bad-certificate subcategory: - - audit + - vuln technology: - - secrets - - npm - paths: - include: - - '*npmrc*' - patterns: - - pattern: $AUTHTOKEN = $VALUE - - metavariable-regex: - metavariable: $AUTHTOKEN - regex: _(authToken|auth|password) - - pattern-not: $AUTHTOKEN = ${...} - severity: ERROR - - id: generic.secrets.security.detected-outlook-team.detected-outlook-team + - go + vulnerability: Insecure Transport + pattern-either: + - pattern: | + tls.Config{..., InsecureSkipVerify: true, ...} + - pattern: | + $CONFIG = &tls.Config{...} + ... + $CONFIG.InsecureSkipVerify = true + severity: WARNING + - id: problem-based-packs.insecure-transport.go-stdlib.disallow-old-tls-versions.disallow-old-tls-versions languages: - - regex - message: Outlook Team detected + - go + message: Detects creations of tls configuration objects with an insecure MinVersion of TLS. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go - subcategory: - - audit - technology: - - secrets - - outlook - pattern-regex: https://outlook\.office\.com/webhook/[0-9a-f-]{36} - severity: ERROR - - id: generic.secrets.security.detected-paypal-braintree-access-token.detected-paypal-braintree-access-token - languages: - - regex - message: PayPal Braintree Access Token detected - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: HIGH + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: HIGH + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://stackoverflow.com/questions/26429751/java-http-clients-and-poodle subcategory: - - audit + - vuln technology: - - secrets - - paypal - - braintree - pattern-regex: access_token\$production\$[0-9a-z]{16}\$[0-9a-z]{32} - severity: ERROR - - id: generic.secrets.security.detected-pgp-private-key-block.detected-pgp-private-key-block + - go + vulnerability: Insecure Transport + patterns: + - pattern-either: + - pattern: | + tls.Config{..., MinVersion: $TLS.$VERSION, ...} + - pattern: | + $CONFIG = &tls.Config{...} + ... + $CONFIG.MinVersion = $TLS.$VERSION + - metavariable-regex: + metavariable: $VERSION + regex: (VersionTLS10|VersionTLS11|VersionSSL30) + severity: WARNING + - fix-regex: + count: 1 + regex: '[fF][tT][pP]://' + replacement: sftp:// + id: problem-based-packs.insecure-transport.go-stdlib.ftp-request.ftp-request languages: - - regex - message: Something that looks like a PGP private key block is detected. This is a potential hardcoded secret that could be leaked if this code is committed. Instead, remove this code block from the commit. + - go + message: Checks for outgoing connections to ftp servers with the ftp package. FTP does not encrypt traffic, possibly leading to PII being sent plaintext over the network. Instead, connect via the SFTP protocol. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://godoc.org/github.com/jlaffaye/ftp#Dial + - https://github.com/jlaffaye/ftp subcategory: - - audit + - vuln technology: - - secrets - pattern-regex: '-----BEGIN PGP PRIVATE KEY BLOCK-----' - severity: ERROR - - id: generic.secrets.security.detected-picatic-api-key.detected-picatic-api-key + - ftp + vulnerability: Insecure Transport + pattern-either: + - pattern: | + ftp.Dial("=~/^[fF][tT][pP]://.*/", ...) + - pattern: | + ftp.DialTimeout("=~/^[fF][tT][pP]://.*/", ...) + - pattern: | + ftp.Connect("=~/^[fF][tT][pP]://.*/") + - pattern: | + $URL = "=~/^[fF][tT][pP]://.*/" + ... + ftp.Dial($URL, ...) + - pattern: | + $URL = "=~/^[fF][tT][pP]://.*/" + ... + ftp.DialTimeout($URL, ...) + - pattern: | + $URL = "=~/^[fF][tT][pP]://.*/" + ... + ftp.Connect($URL) + severity: WARNING + - id: problem-based-packs.insecure-transport.go-stdlib.gorequest-http-request.gorequest-http-request languages: - - regex - message: Picatic API Key detected + - go + message: Checks for requests to http (unencrypted) sites using gorequest, a popular HTTP client library. This is dangerous because it could result in plaintext PII being passed around the network. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: HIGH + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://github.com/parnurzeal/gorequest subcategory: - - audit + - vuln technology: - - secrets - - picatic - pattern-regex: sk_live_[0-9a-z]{32} - severity: ERROR - - id: generic.secrets.security.detected-private-key.detected-private-key + - gorequest + vulnerability: Insecure Transport + pattern-either: + - patterns: + - pattern-inside: | + $REQ = gorequest.New() + ... + $RES = ... + - pattern: | + $REQ.$FUNC("=~/[hH][tT][tT][pP]://.*/") + - metavariable-regex: + metavariable: $FUNC + regex: (Get|Post|Delete|Head|Put|Patch) + - patterns: + - pattern: gorequest.New().$FUNC("=~/[hH][tT][tT][pP]://.*/") + - metavariable-regex: + metavariable: $FUNC + regex: (Get|Post|Delete|Head|Put|Patch) + severity: WARNING + - id: problem-based-packs.insecure-transport.go-stdlib.grequests-http-request.grequests-http-request languages: - - generic - message: Private Key detected. This is a sensitive credential and should not be hardcoded here. Instead, store this in a separate, private file. + - go + message: Checks for requests to http (unencrypted) sites using grequests, a popular HTTP client library. This is dangerous because it could result in plaintext PII being passed around the network. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://godoc.org/github.com/levigross/grequests#DoRegularRequest + - https://github.com/levigross/grequests subcategory: - - audit + - vuln technology: - - secrets + - grequests + vulnerability: Insecure Transport patterns: - pattern-either: - - patterns: - - pattern: '-----BEGIN $TYPE PRIVATE KEY----- $KEY' - - metavariable-regex: - metavariable: $TYPE - regex: (?i)([dr]sa|ec|openssh|encrypted)? - - patterns: - - pattern: | - -----BEGIN PRIVATE KEY----- - $KEY - - metavariable-analysis: - analyzer: entropy - metavariable: $KEY - severity: ERROR - - id: generic.secrets.security.detected-sauce-token.detected-sauce-token + - pattern: | + grequests.$FUNC(...,"=~/[hH][tT][tT][pP]://.*/", ...) + - pattern: | + $FUNC(...,"=~/[hH][tT][tT][pP]://.*/", ...) + - metavariable-regex: + metavariable: $FUNC + regex: (Get|Head|Post|Put|Delete|Patch|Options|Req|DoRegularRequest) + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: problem-based-packs.insecure-transport.go-stdlib.http-customized-request.http-customized-request languages: - - regex - message: Sauce Token detected + - go + message: Checks for requests sent via http.NewRequest to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://golang.org/pkg/net/http/#NewRequest subcategory: - - audit + - vuln technology: - - secrets - - sauce - pattern-regex: (?i)sauce.{0,50}(\\\"|'|`)?[0-9a-f-]{36}(\\\"|'|`)? - severity: ERROR - - id: generic.secrets.security.detected-sendgrid-api-key.detected-sendgrid-api-key + - go + vulnerability: Insecure Transport + pattern: | + http.NewRequest(..., "=~/[hH][tT][tT][pP]://.*/", ...) + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: problem-based-packs.insecure-transport.go-stdlib.http-request.http-request languages: - - regex - message: SendGrid API Key detected + - go + message: Checks for requests sent via http.$FUNC to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/narendrakadali/gitrob/blob/master/rules/contentsignatures.json + - https://golang.org/pkg/net/http/#Get subcategory: - - audit + - vuln technology: - - secrets - - sendgrid - pattern-regex: SG\.[a-zA-Z0-9]{22}\.[a-zA-Z0-9-]{43}\b - severity: ERROR - - id: generic.secrets.security.detected-slack-token.detected-slack-token + - go + vulnerability: Insecure Transport + patterns: + - pattern-either: + - pattern: | + http.$FUNC("=~/[hH][tT][tT][pP]://.*/", ...) + - patterns: + - pattern-inside: | + $CLIENT := &http.Client{...} + ... + - pattern: | + client.$FUNC("=~/[hH][tT][tT][pP]://.*/", ...) + - pattern-not: http.$FUNC("=~/[hH][tT][tT][pP]://127.0.0.1.*/", ...) + - pattern-not: client.$FUNC("=~/[hH][tT][tT][pP]://127.0.0.1.*/", ...) + - pattern-not: http.$FUNC("=~/[hH][tT][tT][pP]://localhost.*/", ...) + - pattern-not: client.$FUNC("=~/[hH][tT][tT][pP]://localhost.*/", ...) + - metavariable-regex: + metavariable: $FUNC + regex: (Get|Post|Head|PostForm) + severity: WARNING + - id: problem-based-packs.insecure-transport.go-stdlib.sling-http-request.sling-http-request languages: - - regex - message: Slack Token detected + - go + message: Checks for requests to http (unencrypted) sites using gorequest, a popular HTTP client library. This is dangerous because it could result in plaintext PII being passed around the network. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://github.com/davidburkitt/python-secret-scanner/blob/335a1f6dab8de59cf39063e57aea39a58951e939/patterns.txt#L58 - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://godoc.org/github.com/dghubble/sling#Sling.Add + - https://github.com/dghubble/sling subcategory: - - audit + - vuln technology: - - secrets - - slack + - sling + vulnerability: Insecure Transport pattern-either: - - pattern-regex: (xox[pboa]-[0-9]{12}-[0-9]{12}-[0-9]{12}-[a-z0-9]{32}) - - pattern-regex: xox.-[0-9]{12}-[0-9]{12}-[0-9a-zA-Z]{24} - severity: ERROR - - id: generic.secrets.security.detected-slack-webhook.detected-slack-webhook + - patterns: + - pattern-inside: | + $REQ = sling.New() + ... + $RES = ... + - pattern: | + $REQ.$FUNC("=~/[hH][tT][tT][pP]://.*/") + - metavariable-regex: + metavariable: $FUNC + regex: (Get|Post|Delete|Head|Put|Options|Patch|Base|Connect) + - patterns: + - pattern: sling.New().$FUNC("=~/[hH][tT][tT][pP]://.*/") + - metavariable-regex: + metavariable: $FUNC + regex: (Get|Post|Delete|Head|Put|Options|Patch|Base|Connect) + - patterns: + - pattern-inside: | + $REQ = sling.New() + ... + $URL = "=~/[hH][tT][tT][pP]://.*/" + ... + $RES = ... + - pattern: | + $REQ.$FUNC($URL) + - metavariable-regex: + metavariable: $FUNC + regex: (Get|Post|Delete|Head|Put|Options|Patch|Base|Connect) + - patterns: + - pattern-inside: | + $URL = "=~/[hH][tT][tT][pP]://.*/" + ... + $RES = ... + - pattern: | + sling.New().$FUNC($URL) + - metavariable-regex: + metavariable: $FUNC + regex: (Get|Post|Delete|Head|Put|Options|Patch|Base|Connect) + severity: WARNING + - id: problem-based-packs.insecure-transport.go-stdlib.telnet-request.telnet-request languages: - - regex - message: Slack Webhook detected + - go + message: Checks for attempts to connect to an insecure telnet server using the package telnet. This is bad because it can lead to man in the middle attacks. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://api.slack.com/messaging/webhooks - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://godoc.org/github.com/reiver/go-telnet subcategory: - - audit + - vuln technology: - - secrets - - slack - pattern-regex: https://hooks\.slack\.com/services/T[a-zA-Z0-9_]{8,10}/B[a-zA-Z0-9_]{8,10}/[a-zA-Z0-9_]{24} - severity: ERROR - - id: generic.secrets.security.detected-snyk-api-key.detected-snyk-api-key + - go-telnet + vulnerability: Insecure Transport + pattern: | + telnet.DialToAndCall(...) + severity: WARNING + - id: problem-based-packs.insecure-transport.java-spring.bypass-tls-verification.bypass-tls-verification languages: - - regex - message: Snyk API Key detected + - java + message: Checks for redefinitions of functions that check TLS/SSL certificate verification. This can lead to vulnerabilities, as simple errors in the code can result in lack of proper certificate validation. This should only be used for debugging purposes because it leads to vulnerability to MTM attacks. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: HIGH + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + - https://stackoverflow.com/questions/4072585/disabling-ssl-certificate-validation-in-spring-resttemplate + - https://stackoverflow.com/questions/35530558/how-to-fix-unsafe-implementation-of-x509trustmanager-in-android-app?rq=1 subcategory: - - audit + - vuln technology: - - secrets - - snyk - pattern-regex: (?i)snyk.{0,50}['|"|`]?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}['"\s]? - severity: ERROR - - id: generic.secrets.security.detected-softlayer-api-key.detected-softlayer-api-key + - spring + vulnerability: Insecure Transport + pattern-either: + - pattern: | + new HostnameVerifier() { + ... + public boolean verify(String hostname, SSLSession session) { + ... + } + ... + }; + - pattern: | + public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { + ... + TrustStrategy $FUNCNAME = (X509Certificate[] chain, String authType) -> ...; + ... + } + - pattern: | + TrustStrategy $FUNCNAME= new TrustStrategy() { + ... + public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + ... + } + ... + }; + severity: WARNING + - fix-regex: + count: 1 + regex: '[fF][tT][pP]://' + replacement: sftp:// + id: problem-based-packs.insecure-transport.java-spring.spring-ftp-request.spring-ftp-request languages: - - regex - message: SoftLayer API Key detected + - java + message: Checks for outgoing connections to ftp servers via Spring plugin ftpSessionFactory. FTP does not encrypt traffic, possibly leading to PII being sent plaintext over the network. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/Yelp/detect-secrets/blob/master/detect_secrets/plugins/softlayer.py + - https://docs.spring.io/spring-integration/api/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.html#setClientMode-int- subcategory: - - audit + - vuln technology: - - secrets - - softlayer - pattern-regex: (?i)softlayer.{0,50}["|'|`]?[a-z0-9]{64}["|'|`]? - severity: ERROR - - id: generic.secrets.security.detected-sonarqube-docs-api-key.detected-sonarqube-docs-api-key + - spring + vulnerability: Insecure Transport + pattern-either: + - pattern: | + $SF = new DefaultFtpSessionFactory(...); + ... + $SF.setHost("=~/^[fF][tT][pP]://.*/"); + ... + $SF.$FUNC(...); + - pattern: | + $SF = new DefaultFtpSessionFactory(...); + ... + String $URL = "=~/^[fF][tT][pP]://.*/"; + ... + $SF.setHost($URL); + ... + $SF.$FUNC(...); + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: problem-based-packs.insecure-transport.java-spring.spring-http-request.spring-http-request languages: - - regex - message: SonarQube Docs API Key detected + - java + message: Checks for requests sent via Java Spring RestTemplate API to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#delete-java.lang.String-java.util.Map- + - https://www.baeldung.com/rest-template subcategory: - - audit + - vuln technology: - - secrets - - sonarqube - paths: - exclude: - - '*.svg' - - '*go.sum' - - '*cargo.lock' - - '*package.json' - - '*yarn.lock' - - '*package-lock.json' - - '*bundle.js' - - '*pnpm-lock*' - - '*Podfile.lock' - - '*/openssl/*.h' - - '*.xcscmblueprint' - pattern-regex: (?i)sonar.{0,50}(\\\"|'|`)?[0-9a-f]{40}(\\\"|'|`)? - severity: ERROR - - id: generic.secrets.security.detected-square-access-token.detected-square-access-token + - spring + vulnerability: Insecure Transport + patterns: + - pattern-either: + - pattern: | + $RESTTEMP = new RestTemplate(...); + ... + $RESTTEMP.$FUNC("=~/[hH][tT][tT][pP]://.*/", ...); + - pattern: | + $RESTTEMP = new RestTemplate(...); + ... + String $URL = "=~/[hH][tT][tT][pP]://.*/"; + ... + $RESTTEMP.$FUNC($URL, ...); + - pattern: | + $RESTTEMP = new RestTemplate(...); + ... + $URL = new URI(..., "=~/[hH][tT][tT][pP]://.*/", ...); + ... + $RESTTEMP.$FUNC($URL, ...); + - metavariable-regex: + metavariable: $FUNC + regex: (delete|doExecute|exchange|getForEntity|getForObject|headForHeaders|optionsForAllow|patchForObject|postForEntity|postForLocation|postForObject|put) + severity: WARNING + - id: problem-based-packs.insecure-transport.java-stdlib.bypass-tls-verification.bypass-tls-verification languages: - - regex - message: Square Access Token detected + - java + message: Checks for redefinitions of the checkServerTrusted function in the X509TrustManager class that disables TLS/SSL certificate verification. This should only be used for debugging purposes because it leads to vulnerability to MTM attacks. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://riptutorial.com/java/example/16517/temporarily-disable-ssl-verification--for-testing-purposes- + - https://stackoverflow.com/questions/35530558/how-to-fix-unsafe-implementation-of-x509trustmanager-in-android-app?rq=1 subcategory: - - audit + - vuln technology: - - secrets - - square - pattern-regex: sq0atp-[0-9A-Za-z\-_]{22} - severity: ERROR - - id: generic.secrets.security.detected-square-oauth-secret.detected-square-oauth-secret - languages: - - regex - message: Square OAuth Secret detected - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://github.com/Yelp/detect-secrets/blob/master/tests/plugins/square_oauth_test.py - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json - subcategory: - - audit - technology: - - secrets - - square - pattern-regex: sq0csp-[0-9A-Za-z\\\-_]{43} - severity: ERROR - - id: generic.secrets.security.detected-ssh-password.detected-ssh-password + - java + vulnerability: Insecure Transport + patterns: + - pattern: | + new X509TrustManager() { + ... + public void checkClientTrusted(X509Certificate[] certs, String authType) {...} + ... + } + - pattern-not: | + new X509TrustManager() { + ... + public void checkServerTrusted(X509Certificate[] certs, String authType) { + ... + throw new CertificateException(...); + ... + } + ... + } + - pattern-not: | + new X509TrustManager() { + ... + public void checkServerTrusted(X509Certificate[] certs, String authType) { + ... + throw new IllegalArgumentException(...); + ... + } + ... + } + severity: WARNING + - id: problem-based-packs.insecure-transport.java-stdlib.disallow-old-tls-versions1.disallow-old-tls-versions1 languages: - - regex - message: SSH Password detected + - java + message: Detects direct creations of SSLConnectionSocketFactories that don't disallow SSL v2, SSL v3, and TLS v1. SSLSocketFactory can be used to validate the identity of the HTTPS server against a list of trusted certificates. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: HIGH + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://stackoverflow.com/questions/26429751/java-http-clients-and-poodle subcategory: - - audit + - vuln technology: - - secrets - - ssh - pattern-regex: sshpass -p\s*['|\\\"][^%] - severity: ERROR - - id: generic.secrets.security.detected-stripe-api-key.detected-stripe-api-key + - java + vulnerability: Insecure Transport + patterns: + - pattern: | + new SSLConnectionSocketFactory(...); + - pattern-not: | + new SSLConnectionSocketFactory(..., new String[] {"TLSv1.2", "TLSv1.3"}, ...); + - pattern-not: | + new SSLConnectionSocketFactory(..., new String[] {"TLSv1.3", "TLSv1.2"}, ...); + - pattern-not: | + new SSLConnectionSocketFactory(..., new String[] {"TLSv1.3"}, ...); + - pattern-not: | + new SSLConnectionSocketFactory(..., new String[] {"TLSv1.2"}, ...); + - pattern-not-inside: | + (SSLConnectionSocketFactory $SF) = new SSLConnectionSocketFactory(...); ... (TlsConfig $TLSCONFIG) = TlsConfig.custom(). ... .setSupportedProtocols(TLS.V_1_2). ... .build(); ... HttpClientConnectionManager cm = $CM.create(). ... .setSSLSocketFactory($SF). ... .setDefaultTlsConfig($TLSCONFIG). ... .build(); + - pattern-not-inside: | + (SSLConnectionSocketFactory $SF) = new SSLConnectionSocketFactory(...); ... (TlsConfig $TLSCONFIG) = TlsConfig.custom(). ... .setSupportedProtocols(TLS.V_1_3). ... .build(); ... HttpClientConnectionManager cm = $CM.create(). ... .setSSLSocketFactory($SF). ... .setDefaultTlsConfig($TLSCONFIG). ... .build(); + severity: WARNING + - id: problem-based-packs.insecure-transport.java-stdlib.disallow-old-tls-versions2.disallow-old-tls-versions2 languages: - - regex - message: Stripe API Key detected + - java + message: Detects setting client protocols to insecure versions of TLS and SSL. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://stackoverflow.com/questions/26504653/is-it-possible-to-disable-sslv3-for-all-java-applications subcategory: - - audit + - vuln technology: - - secrets - - stripe - pattern-regex: sk_live_[0-9a-zA-Z]{24} - severity: ERROR - - id: generic.secrets.security.detected-stripe-restricted-api-key.detected-stripe-restricted-api-key + - java + vulnerability: Insecure Transport + patterns: + - pattern: $VALUE. ... .setProperty("jdk.tls.client.protocols", "$PATTERNS"); + - metavariable-pattern: + language: generic + metavariable: $PATTERNS + patterns: + - pattern-either: + - pattern: TLS1 + - pattern-regex: ^(.*TLSv1|.*SSLv.*)$ + - pattern-regex: ^(.*TLSv1,.*) + severity: WARNING + - fix-regex: + count: 1 + regex: '[fF][tT][pP]://' + replacement: sftp:// + id: problem-based-packs.insecure-transport.java-stdlib.ftp-request.ftp-request languages: - - regex - message: Stripe Restricted API Key detected + - java + message: Checks for outgoing connections to ftp servers. FTP does not encrypt traffic, possibly leading to PII being sent plaintext over the network. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://www.codejava.net/java-se/ftp/connect-and-login-to-a-ftp-server + - https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html subcategory: - - audit + - vuln technology: - - secrets - - stripe - pattern-regex: rk_live_[0-9a-zA-Z]{24} - severity: ERROR - - id: generic.secrets.security.detected-telegram-bot-api-key.detected-telegram-bot-api-key + - java + vulnerability: Insecure Transport + pattern-either: + - pattern: | + FTPClient $FTPCLIENT = new FTPClient(); + ... + $FTPCLIENT.connect(...); + - pattern: | + URL $URL = new URL("=~/^[fF][tT][pP]://.*/"); + ... + URLConnection $CONN = $URL.openConnection(...); + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: problem-based-packs.insecure-transport.java-stdlib.http-components-request.http-components-request languages: - - regex - message: Telegram Bot API Key detected + - java + message: Checks for requests sent via Apache HTTP Components to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://hc.apache.org/httpcomponents-client-ga/quickstart.html subcategory: - - audit + - vuln technology: - - secrets - - telegram - patterns: - - pattern-regex: '[0-9]+:AA[0-9A-Za-z\-_]{33}' - - pattern-not-regex: go\.mod.* - - pattern-not-regex: v[\d]+\.[\d]+\.[\d]+.* - severity: ERROR - - id: generic.secrets.security.detected-twilio-api-key.detected-twilio-api-key + - java + vulnerability: Insecure Transport + pattern-either: + - pattern: | + $HTTPCLIENT = HttpClients.$CREATE(...); + ... + $HTTPREQ = new $HTTPFUNC("=~/[hH][tT][tT][pP]://.*/"); + ... + $RESPONSE = $HTTPCLIENT.execute($HTTPREQ); + - pattern: | + $HTTPCLIENT = HttpClients.$CREATE(...); + ... + $RESPONSE = $HTTPCLIENT.execute(new $HTTPFUNC("=~/[hH][tT][tT][pP]://.*/")); + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: problem-based-packs.insecure-transport.java-stdlib.httpclient-http-request.httpclient-http-request languages: - - regex - message: Twilio API Key detected + - java + message: Checks for requests sent via HttpClient to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS. metadata: category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json + - https://openjdk.java.net/groups/net/httpclient/intro.html subcategory: - - audit + - vuln technology: - - secrets - - twilio - pattern-regex: SK[0-9a-fA-F]{32} - severity: ERROR - - id: generic.secrets.security.detected-username-and-password-in-uri.detected-username-and-password-in-uri + - java + vulnerability: Insecure Transport + pattern-either: + - patterns: + - pattern: | + URI.create("=~/[hH][tT][tT][pP]://.*/", ...) + - pattern-inside: | + HttpClient $CLIENT = ...; + ... + HttpRequest $REQ = ...; + ... + $CLIENT.sendAsync(...); + - patterns: + - pattern: | + URI.create("=~/[hH][tT][tT][pP]://.*/", ...) + - pattern-inside: | + HttpClient $CLIENT = ...; + ... + HttpRequest $REQ = ...; + ... + $CLIENT.send(...); + - patterns: + - pattern: | + URI.create($URI) + - pattern-inside: | + String $URI = "=~/[hH][tT][tT][pP]://.*/"; + ... + HttpClient $CLIENT = ...; + ... + HttpRequest $REQ = ...; + ... + $CLIENT.send(...); + - patterns: + - pattern: | + URI.create($URI) + - pattern-inside: | + String $URI = "=~/[hH][tT][tT][pP]://.*/"; + ... + HttpClient $CLIENT = ...; + ... + HttpRequest $REQ = ...; + ... + $CLIENT.sendAsync(...); + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: problem-based-packs.insecure-transport.java-stdlib.httpget-http-request.httpget-http-request languages: - - generic - message: Username and password in URI detected + - java + message: Detected an HTTP request sent via HttpGet. This could lead to sensitive information being sent over an insecure channel. Instead, it is recommended to send requests over HTTPS. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: MEDIUM - owasp: - - A07:2021 - Identification and Authentication Failures + owasp: A03:2017 - Sensitive Data Exposure references: - - https://github.com/grab/secret-scanner/blob/master/scanner/signatures/pattern.go + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() subcategory: - vuln technology: - - secrets + - java + vulnerability: Insecure Transport patterns: - - pattern: $PROTOCOL://$...USERNAME:$...PASSWORD@$END - - metavariable-regex: - metavariable: $...USERNAME - regex: \A({?)([A-Za-z])([A-Za-z0-9_-]){5,31}(}?)\Z - - metavariable-regex: - metavariable: $...PASSWORD - regex: (?!.*[\s])(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]){6,32} - - metavariable-regex: - metavariable: $PROTOCOL - regex: (.*http.*)|(.*sql.*)|(.*ftp.*)|(.*smtp.*) - severity: ERROR - - id: generic.secrets.security.google-maps-apikeyleak.google-maps-apikeyleak + - pattern: | + "=~/[Hh][Tt][Tt][Pp]://.*/" + - pattern-inside: | + $R = new HttpGet("=~/[Hh][Tt][Tt][Pp]://.*/"); + ... + $CLIENT. ... .execute($R, ...); + severity: WARNING + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: problem-based-packs.insecure-transport.java-stdlib.httpurlconnection-http-request.httpurlconnection-http-request languages: - - generic - message: Detects potential Google Maps API keys in code + - java + message: Detected an HTTP request sent via HttpURLConnection. This could lead to sensitive information being sent over an insecure channel. Instead, it is recommended to send requests over HTTPS. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-538: Insertion of Sensitive Information into Externally-Accessible File or Directory' - description: Detects potential Google Maps API keys in code - impact: HIGH + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM likelihood: MEDIUM - owasp: - - A3:2017 Sensitive Data Exposure + owasp: A03:2017 - Sensitive Data Exposure references: - - https://ozguralp.medium.com/unauthorized-google-maps-api-key-usage-cases-and-why-you-need-to-care-1ccb28bf21e - severity: MEDIUM + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() subcategory: - - audit + - vuln technology: - - Google Maps + - java + vulnerability: Insecure Transport patterns: - - pattern-regex: ^(AIza[0-9A-Za-z_-]{35}(?!\S))$ + - pattern: | + "=~/[Hh][Tt][Tt][Pp]://.*/" + - pattern-either: + - pattern-inside: | + URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); + ... + $CON = (HttpURLConnection) $URL.openConnection(...); + ... + $CON.$FUNC(...); + - pattern-inside: | + URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); + ... + $CON = $URL.openConnection(...); + ... + $CON.$FUNC(...); severity: WARNING - - id: generic.unicode.security.bidi.contains-bidirectional-characters + - id: problem-based-packs.insecure-transport.java-stdlib.telnet-request.telnet-request languages: - - bash - - c - - cpp - - csharp - - go - java - - javascript - - json - - kotlin - - lua - - ocaml - - php - - python - - ruby - - rust - - scala - - sh - - typescript - - yaml - message: This code contains bidirectional (bidi) characters. While this is useful for support of right-to-left languages such as Arabic or Hebrew, it can also be used to trick language parsers into executing code in a manner that is different from how it is displayed in code editing and review tools. If this is not what you were expecting, please review this code in an editor that can reveal hidden Unicode characters. + message: Checks for attempts to connect through telnet. This is insecure as the telnet protocol supports no encryption, and data passes through unencrypted. metadata: category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://trojansource.codes/ + - https://commons.apache.org/proper/commons-net/javadocs/api-3.6/org/apache/commons/net/telnet/TelnetClient.html subcategory: - - audit + - vuln technology: - - unicode - patterns: - - pattern-either: - - pattern-regex: ‪ - - pattern-regex: ‫ - - pattern-regex: ‭ - - pattern-regex: ‮ - - pattern-regex: ⁦ - - pattern-regex: ⁧ - - pattern-regex: ⁨ - - pattern-regex: ‬ - - pattern-regex: ⁩ + - java + vulnerability: Insecure Transport + pattern: | + $TELNETCLIENT = new TelnetClient(...); + ... + $TELNETCLIENT.connect(...); severity: WARNING - - id: generic.visualforce.security.ncino.html.usesriforcdns.use-sri-for-cdns + - id: problem-based-packs.insecure-transport.java-stdlib.tls-renegotiation.tls-renegotiation languages: - - generic - message: 'Consuming CDNs without including a SubResource Integrity (SRI) can expose your application and its users to compromised code. SRIs allow you to consume specific versions of content where if even a single byte is compromised, the resource will not be loaded. Add an integrity attribute to your - - pattern-not: - severity: ERROR - - id: generic.visualforce.security.ncino.xml.cspheaderattribute.csp-header-attribute + - unirest + vulnerability: Insecure Transport + pattern-either: + - pattern: | + Unirest.get("=~/[hH][tT][tT][pP]://.*/") + - pattern: | + Unirest.post("=~/[hH][tT][tT][pP]://.*/") + severity: WARNING + - id: problem-based-packs.insecure-transport.js-node.bypass-tls-verification.bypass-tls-verification languages: - - generic - message: Visualforce Pages must have the cspHeader attribute set to true. This attribute is available in API version 55 or higher. + - javascript + - typescript + message: Checks for setting the environment variable NODE_TLS_REJECT_UNAUTHORIZED to 0, which disables TLS verification. This should only be used for debugging purposes. Setting the option rejectUnauthorized to false bypasses verification against the list of trusted CAs, which also leads to insecure transport. These options lead to vulnerability to MTM attacks, and should not be used. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://help.salesforce.com/s/articleView?id=sf.csp_trusted_sites.htm&type=5 + - https://nodejs.org/api/https.html#https_https_request_options_callback + - https://stackoverflow.com/questions/20433287/node-js-request-cert-has-expired#answer-29397100 subcategory: - vuln technology: - - salesforce - - visualforce - paths: - include: - - '*.page' - patterns: - - pattern: ... - - pattern-not: ... - - pattern-not: ...... - - pattern-not: ...... - severity: INFO - - id: generic.visualforce.security.ncino.xml.visualforceapiversion.visualforce-page-api-version + - node.js + vulnerability: Insecure Transport + pattern-either: + - pattern: | + process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; + - pattern: | + {rejectUnauthorized:false} + severity: WARNING + - id: problem-based-packs.insecure-transport.js-node.disallow-old-tls-versions1.disallow-old-tls-versions1 languages: - - generic - message: Visualforce Pages must use API version 55 or higher for required use of the cspHeader attribute set to true. + - javascript + - typescript + message: Detects direct creations of $HTTPS servers that don't disallow SSL v2, SSL v3, and TLS v1. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities. metadata: category: security - confidence: HIGH - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_pages.htm + - https://us-cert.cisa.gov/ncas/alerts/TA14-290A + - https://stackoverflow.com/questions/40434934/how-to-disable-the-ssl-3-0-and-tls-1-0-in-nodejs + - https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener subcategory: - vuln technology: - - salesforce - - visualforce - paths: - include: - - '*.page-meta.xml' + - node.js + vulnerability: Insecure Transport patterns: - - pattern-inside: - pattern-either: - - pattern-regex: '[>][0-9].[0-9][<]' - - pattern-regex: '[>][1-4][0-9].[0-9][<]' - - pattern-regex: '[>][5][0-4].[0-9][<]' + - pattern-inside: | + $CONST = require('crypto'); + ... + - pattern-inside: | + $CONST = require('constants'); + ... + - pattern-inside: | + $HTTPS = require('https'); + ... + - pattern: | + $HTTPS.createServer(...).$FUNC(...); + - pattern-not: | + $HTTPS.createServer({secureOptions: $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_SSLv2 }, ...).$FUNC(...); + - pattern-not: | + $HTTPS.createServer({secureOptions: $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv2 |$CONST.SSL_OP_NO_SSLv3 }, ...).$FUNC(...); + - pattern-not: | + $HTTPS.createServer({secureOptions: $CONST.SSL_OP_NO_SSLv2 |$CONST.SSL_OP_NO_SSLv3 |$CONST.SSL_OP_NO_TLSv1 }, ...).$FUNC(...); + - pattern-not: | + $HTTPS.createServer({secureOptions: $CONST.SSL_OP_NO_SSLv2 |$CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv3}, ...).$FUNC(...); + - pattern-not: | + $HTTPS.createServer({secureOptions:$CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_SSLv2 |$CONST.SSL_OP_NO_TLSv1}, ...).$FUNC(...); + - pattern-not: | + $HTTPS.createServer({secureOptions:$CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_TLSv1| $CONST.SSL_OP_NO_SSLv2}, ...).$FUNC(...); severity: WARNING - - id: go.aws-lambda.security.database-sqli.database-sqli + - id: problem-based-packs.insecure-transport.js-node.disallow-old-tls-versions2.disallow-old-tls-versions2 languages: - - go - message: Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use prepared statements with the 'Prepare' and 'PrepareContext' calls. + - javascript + - typescript + message: Detects creations of $HTTPS servers from option objects that don't disallow SSL v2, SSL v3, and TLS v1. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://pkg.go.dev/database/sql#DB.Query + - https://us-cert.cisa.gov/ncas/alerts/TA14-290A + - https://stackoverflow.com/questions/40434934/how-to-disable-the-ssl-3-0-and-tls-1-0-in-nodejs + - https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener subcategory: - vuln technology: - - aws-lambda - - database - - sql - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $DB.Exec($QUERY,...) - - pattern: $DB.ExecContent($QUERY,...) - - pattern: $DB.Query($QUERY,...) - - pattern: $DB.QueryContext($QUERY,...) - - pattern: $DB.QueryRow($QUERY,...) - - pattern: $DB.QueryRowContext($QUERY,...) + - node.js + vulnerability: Insecure Transport + patterns: + - pattern-either: - pattern-inside: | - import "database/sql" + $CONST = require('crypto'); ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...} - ... - lambda.Start($HANDLER, ...) - - patterns: - - pattern-inside: | - func $HANDLER($EVENT $TYPE) {...} - ... - lambda.Start($HANDLER, ...) - - pattern-not-inside: | - func $HANDLER($EVENT context.Context) {...} - ... - lambda.Start($HANDLER, ...) - - focus-metavariable: $EVENT + - pattern-inside: | + $CONST = require('constants'); + ... + - pattern-inside: | + $HTTPS = require('https'); + ... + - pattern: | + $OPTIONS = {}; + ... + $HTTPS.createServer($OPTIONS, ...); + - pattern-not: | + $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_SSLv2}; + ... + $HTTPS.createServer($OPTIONS, ...); + - pattern-not: | + $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv2 | $CONST.SSL_OP_NO_SSLv3}; + ... + $HTTPS.createServer($OPTIONS, ...); + - pattern-not: | + $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_SSLv2 | $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv3}; + ... + $HTTPS.createServer($OPTIONS, ...); + - pattern-not: | + $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_SSLv2 | $CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_TLSv1}; + ... + $HTTPS.createServer($OPTIONS, ...); + - pattern-not: | + $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_SSLv2 | $CONST.SSL_OP_NO_TLSv1}; + ... + $HTTPS.createServer($OPTIONS, ...); + - pattern-not: | + $OPTIONS = {secureOptions: $CONST.SSL_OP_NO_SSLv3 | $CONST.SSL_OP_NO_TLSv1 | $CONST.SSL_OP_NO_SSLv2}; + ... + $HTTPS.createServer($OPTIONS, ...); severity: WARNING - - id: go.aws-lambda.security.tainted-sql-string.tainted-sql-string + - id: problem-based-packs.insecure-transport.js-node.ftp-request.ftp-request languages: - - go - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + - javascript + - typescript + message: 'Checks for lack of usage of the "secure: true" option when sending ftp requests through the nodejs ftp module. This leads to unencrypted traffic being sent to the ftp server. There are other options such as "implicit" that still does not encrypt all traffic. ftp is the most utilized npm ftp module.' metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/www-community/attacks/SQL_Injection + - https://www.npmjs.com/package/ftp + - https://openbase.io/js/ftp subcategory: - vuln technology: - - aws-lambda - mode: taint - pattern-sanitizers: - - pattern: strconv.Atoi(...) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: | - "$SQLSTR" + ... - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(\s*select|\s*delete|\s*insert|\s*create|\s*update|\s*alter|\s*drop).* - - patterns: - - pattern-either: - - pattern: fmt.Fprintf($F, "$SQLSTR", ...) - - pattern: fmt.Sprintf("$SQLSTR", ...) - - pattern: fmt.Printf("$SQLSTR", ...) - - metavariable-regex: - metavariable: $SQLSTR - regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).* - - pattern-not-inside: | - log.$PRINT(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...} - ... - lambda.Start($HANDLER, ...) - - patterns: - - pattern-inside: | - func $HANDLER($EVENT $TYPE) {...} - ... - lambda.Start($HANDLER, ...) - - pattern-not-inside: | - func $HANDLER($EVENT context.Context) {...} - ... - lambda.Start($HANDLER, ...) - - focus-metavariable: $EVENT - severity: ERROR - - id: go.gorilla.security.audit.handler-assignment-from-multiple-sources.handler-assignment-from-multiple-sources + - node.js + vulnerability: Insecure Transport + patterns: + - pattern-inside: | + $X = require('ftp'); + ... + $C = new $X(); + ... + - pattern-not-inside: | + $OPTIONS = {secure: true}; + ... + - pattern: | + $C.connect($OPTIONS,...); + - pattern-not: | + $C.connect({...,secure: true}); + severity: WARNING + - id: problem-based-packs.insecure-transport.js-node.http-request.http-request languages: - - go - message: 'Variable $VAR is assigned from two different sources: ''$Y'' and ''$R''. Make sure this is intended, as this could cause logic bugs if they are treated as they are the same object.' + - javascript + message: Checks for requests sent to http:// URLs. This is dangerous as the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, only send requests to https:// URLs. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-289: Authentication Bypass by Alternate Name' + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://cwe.mitre.org/data/definitions/289.html + - https://nodejs.org/api/http.html#http_http_request_options_callback subcategory: - - audit + - vuln technology: - - gorilla - mode: taint - pattern-sinks: - - patterns: + - node.js + vulnerability: Insecure Transport + patterns: + - pattern-inside: | + $HTTP = require('http'); + ... + - pattern-either: - pattern: | - $Y, err := store.Get(...) + $HTTP.request("=~/http://.*/",...); + - pattern: | + $HTTP.get("=~/http://.*/", ...) + - pattern: | + $VAR = new URL("=~/http://.*/"); ... - $VAR := $Y.Values[...] + $HTTP.request($VAR, ...); + - pattern: | + $VAR = {...,hostname: "..."}; ... - $VAR = $R - - focus-metavariable: $R - - patterns: + $HTTP.request(..., $VAR, ...); - pattern: | - $Y, err := store.Get(...) + $HTTP.request(..., {...,hostname: "..."}, ...); + - pattern-not: | + $VAR = {...,protocol: "https"}; + ... + $HTTP.request(..., $VAR, ...); + - pattern-not: | + $HTTP.request(..., {...,protocol: "https"}, ...); + severity: WARNING + - id: problem-based-packs.insecure-transport.js-node.rest-http-client-support.rest-http-client-support + languages: + - javascript + message: Checks for requests to http (unencrypted) sites using some of node js's most popular REST/HTTP libraries, including node-rest-client, axios, and got. + metadata: + category: security + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure + references: + - https://www.npmjs.com/package/axios + - https://www.npmjs.com/package/got + - https://www.npmjs.com/package/node-rest-client + subcategory: + - vuln + technology: + - node.js + vulnerability: Insecure Transport + patterns: + - pattern-either: + - pattern-inside: | + $CLIENT = require('node-rest-client').Client; ... - var $VAR $INT = $Y.Values["..."].($INT) + $C = new $CLIENT(); ... - $VAR = $R - - focus-metavariable: $R - pattern-sources: - - patterns: - pattern-inside: | - func $HANDLER(..., $R *http.Request, ...) { - ... - } - - focus-metavariable: $R - - pattern-either: - - pattern: $R.query + $C = require('axios'); + ... + - pattern-inside: | + $C = require('got'); + ... + - pattern-either: + - pattern: | + $C.$REQ("=~/http://.*/", ...) + - pattern: | + $C("=~/http://.*/", ...) + - pattern: | + $C({...,url: "=~/http://.*/"}) + - pattern: | + $C.$REQ({...,url: "=~/http://.*/"}) severity: WARNING - - fix-regex: - regex: (HttpOnly\s*:\s+)false - replacement: \1true - id: go.gorilla.security.audit.session-cookie-missing-httponly.session-cookie-missing-httponly + - id: problem-based-packs.insecure-transport.js-node.telnet-request.telnet-request languages: - - go - message: A session cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie which mitigates XSS attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' in the Options struct. + - javascript + message: Checks for creation of telnet servers or attempts to connect through telnet. This is insecure as the telnet protocol supports no encryption, and data passes through unencrypted. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 + - https://www.npmjs.com/package/telnet + - https://www.npmjs.com/package/telnet-client subcategory: - - audit + - vuln technology: - - gorilla + - node.js + vulnerability: Insecure Transport patterns: - - pattern-not-inside: | - &sessions.Options{ - ..., - HttpOnly: true, - ..., - } - - pattern: | - &sessions.Options{ - ..., - } + - pattern-either: + - pattern-inside: | + $TEL = require('telnet-client'); + ... + $SERVER = new $TEL(); + ... + - pattern-inside: | + $SERVER = require('telnet'); + ... + - pattern-either: + - pattern: | + $SERVER.on(...) + - pattern: | + $SERVER.connect(...) + - pattern: | + $SERVER.createServer(...) severity: WARNING - - fix-regex: - regex: (Secure\s*:\s+)false - replacement: \1true - id: go.gorilla.security.audit.session-cookie-missing-secure.session-cookie-missing-secure + - id: problem-based-packs.insecure-transport.ruby-stdlib.http-client-requests.http-client-requests languages: - - go - message: A session cookie was detected without setting the 'Secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'Secure' flag by setting 'Secure' to 'true' in the Options struct. + - ruby + message: Checks for requests to http (unencrypted) sites using some of ruby's most popular REST/HTTP libraries, including httparty and restclient. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 + - https://github.com/rest-client/rest-client + - https://github.com/jnunemaker/httparty/tree/master/docs subcategory: - - audit + - vuln technology: - - gorilla - patterns: - - pattern-not-inside: | - &sessions.Options{ - ..., - Secure: true, - ..., - } + - httparty + - rest-client + vulnerability: Insecure Transport + pattern-either: - pattern: | - &sessions.Options{ - ..., - } + HTTParty.$PARTYVERB("=~/[hH][tT][tT][pP]://.*/", ...) + - pattern: | + $STRING = "=~/[hH][tT][tT][pP]://.*/" + ... + HTTParty.$PARTYVERB($STRING, ...) + - pattern: | + RestClient.$RESTVERB "=~/[hH][tT][tT][pP]://.*/", ... + - pattern: | + RestClient::Request.execute(..., url: "=~/[hH][tT][tT][pP]://.*/", ...) severity: WARNING - - fix-regex: - regex: (SameSite\s*:\s+)http.SameSiteNoneMode - replacement: \1http.SameSiteDefaultMode - id: go.gorilla.security.audit.session-cookie-samesitenone.session-cookie-samesitenone + - id: problem-based-packs.insecure-transport.ruby-stdlib.net-ftp-request.net-ftp-request languages: - - go - message: Found SameSiteNoneMode setting in Gorilla session options. Consider setting SameSite to Lax, Strict or Default for enhanced security. + - ruby + message: Checks for outgoing connections to ftp servers with the 'net/ftp' package. FTP does not encrypt traffic, possibly leading to PII being sent plaintext over the network. Instead, connect via the SFTP protocol. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://pkg.go.dev/github.com/gorilla/sessions#Options + - https://docs.ruby-lang.org/en/2.0.0/Net/FTP.html subcategory: - - audit + - vuln technology: - - gorilla - patterns: - - pattern-inside: | - &sessions.Options{ - ..., - SameSite: http.SameSiteNoneMode, - ..., - } + - ruby + vulnerability: Insecure Transport + pattern-either: - pattern: | - &sessions.Options{ - ..., - } + $FTP = Net::FTP.new('...') + ... + $FTP.login + - pattern: | + Net::FTP.open('...') do |ftp| + ... + ftp.login + end severity: WARNING - - id: go.gorilla.security.audit.websocket-missing-origin-check.websocket-missing-origin-check + - id: problem-based-packs.insecure-transport.ruby-stdlib.net-http-request.net-http-request languages: - - go - message: 'The Origin header in the HTTP WebSocket handshake is used to guarantee that the connection accepted by the WebSocket is from a trusted origin domain. Failure to enforce can lead to Cross Site Request Forgery (CSRF). As per "gorilla/websocket" documentation: "A CheckOrigin function should carefully validate the request origin to prevent cross-site request forgery."' + - ruby + message: Checks for requests sent to http:// URLs. This is dangerous as the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, only send requests to https:// URLs. metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure references: - - https://pkg.go.dev/github.com/gorilla/websocket#Upgrader + - https://ruby-doc.org/stdlib-2.6.5/libdoc/net/http/rdoc/Net/ subcategory: - - audit + - vuln technology: - - gorilla - patterns: - - pattern-inside: | - import ("github.com/gorilla/websocket") - ... - - patterns: - - pattern-not-inside: | - $UPGRADER = websocket.Upgrader{..., CheckOrigin: $FN ,...} + - ruby + vulnerability: Insecure Transport + patterns: + - pattern-either: + - pattern: | + $URI = URI('=~/[hH][tT][tT][pP]://.*/') ... - - pattern-not-inside: | - $UPGRADER.CheckOrigin = $FN2 + Net::HTTP::$FUNC.new $URI + - pattern: | + $URI = URI('=~/[hH][tT][tT][pP]://.*/') ... + Net::HTTP.$FUNC($URI, ...) - pattern: | - $UPGRADER.Upgrade(...) + Net::HTTP.$FUNC(URI('=~/[hH][tT][tT][pP]://.*/'), ...) + - metavariable-regex: + metavariable: $FUNC + regex: ([gG]et|post_form|[pP]ost|get_response|get_print|Head|Patch|Put|Proppatch|Lock|Unlock|Options|Propfind|Delete|Move|Copy|Trace|Mkcol) severity: WARNING - - id: go.gorm.security.audit.gorm-dangerous-methods-usage.gorm-dangerous-method-usage + - id: problem-based-packs.insecure-transport.ruby-stdlib.net-telnet-request.net-telnet-request languages: - - go - message: Detected usage of dangerous method $METHOD which does not escape inputs (see link in references). If the argument is user-controlled, this can lead to SQL injection. When using $METHOD function, do not trust user-submitted data and only allow approved list of input (possibly, use an allowlist approach). + - ruby + message: Checks for creation of telnet servers or attempts to connect through telnet. This is insecure as the telnet protocol supports no encryption, and data passes through unencrypted. metadata: category: security - confidence: HIGH + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure + references: + - https://docs.ruby-lang.org/en/2.2.0/Net/Telnet.html + - https://www.rubydoc.info/gems/net-ssh-telnet2/0.1.0/Net/SSH/Telnet + subcategory: + - vuln + technology: + - ruby + vulnerability: Insecure Transport + pattern-either: + - pattern: | + Net::Telnet::new(...) + - pattern: | + Net::SSH::Telnet.new(...) + severity: WARNING + - id: problem-based-packs.insecure-transport.ruby-stdlib.openuri-request.openuri-request + languages: + - ruby + message: Checks for requests to http and ftp (unencrypted) sites using OpenURI. + metadata: + category: security + confidence: MEDIUM + cwe: 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM + owasp: A03:2017 - Sensitive Data Exposure + references: + - https://ruby-doc.org/stdlib-2.6.3/libdoc/open-uri/rdoc/OpenURI.html + subcategory: + - vuln + technology: + - open-uri + vulnerability: Insecure Transport + pattern-either: + - pattern: | + URI.open('=~/[hH][tT][tT][pP]://.*/', ...) + - pattern: | + $URI = URI.parse('=~/[hH][tT][tT][pP]://.*/', ...) + ... + $URI.open + - pattern: | + URI.open('=~/^[fF][tT][pP]://.*/', ...) + - pattern: | + $URI = URI.parse('=~/^[fF][tT][pP]://.*/', ...) + ... + $URI.open + severity: WARNING + - id: python.aws-lambda.security.dangerous-asyncio-create-exec.dangerous-asyncio-create-exec + languages: + - python + message: Detected 'create_subprocess_exec' function with argument tainted by `event` object. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. + metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" + category: security + confidence: MEDIUM cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: HIGH owasp: - A01:2017 - Injection - A03:2021 - Injection references: - - https://gorm.io/docs/security.html#SQL-injection-Methods - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + - https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.create_subprocess_exec + - https://docs.python.org/3/library/shlex.html subcategory: - vuln technology: - - gorm + - python mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern-either: - - pattern: strconv.Atoi(...) - - pattern: | - ($X: bool) pattern-sinks: - patterns: - - pattern-inside: | - import ("gorm.io/gorm") - ... - - patterns: - - pattern-inside: | - func $VAL(..., $GORM *gorm.DB,... ) { - ... - } - - pattern-either: - - pattern: | - $GORM. ... .$METHOD($VALUE) - - pattern: | - $DB := $GORM. ... .$ANYTHING(...) - ... - $DB. ... .$METHOD($VALUE) - - focus-metavariable: $VALUE - - metavariable-regex: - metavariable: $METHOD - regex: ^(Order|Exec|Raw|Group|Having|Distinct|Select|Pluck)$ + - focus-metavariable: $CMD + - pattern-either: + - pattern: asyncio.create_subprocess_exec($PROG, $CMD, ...) + - pattern: asyncio.create_subprocess_exec($PROG, [$CMD, ...], ...) + - pattern: asyncio.subprocess.create_subprocess_exec($PROG, $CMD, ...) + - pattern: asyncio.subprocess.create_subprocess_exec($PROG, [$CMD, ...], ...) + - pattern: asyncio.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...) + - pattern: asyncio.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...], ...) + - pattern: asyncio.subprocess.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...) + - pattern: asyncio.subprocess.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...], ...) pattern-sources: - patterns: - - pattern-either: - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - severity: WARNING - - fix-regex: - regex: (.*)WithInsecure\(.*?\) - replacement: \1WithTransportCredentials(credentials.NewTLS()) - id: go.grpc.security.grpc-client-insecure-connection.grpc-client-insecure-connection + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... + severity: ERROR + - id: python.aws-lambda.security.dangerous-asyncio-exec.dangerous-asyncio-exec languages: - - go - message: 'Found an insecure gRPC connection using ''grpc.WithInsecure()''. This creates a connection without encryption to a gRPC server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. Instead, establish a secure connection with an SSL certificate using the ''grpc.WithTransportCredentials()'' function. You can create a create credentials using a ''tls.Config{}'' struct with ''credentials.NewTLS()''. The final fix looks like this: ''grpc.WithTransportCredentials(credentials.NewTLS())''.' + - python + message: Detected subprocess function '$LOOP.subprocess_exec' with argument tainted by `event` object. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - confidence: HIGH + confidence: MEDIUM cwe: - - 'CWE-300: Channel Accessible by Non-Endpoint' - impact: LOW - likelihood: LOW + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption + - https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec + - https://docs.python.org/3/library/shlex.html subcategory: - - audit + - vuln technology: - - grpc - pattern: $GRPC.Dial($ADDR, ..., $GRPC.WithInsecure(...), ...) + - python + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $CMD + - pattern-either: + - pattern: $LOOP.subprocess_exec($PROTOCOL, $CMD, ...) + - pattern: $LOOP.subprocess_exec($PROTOCOL, [$CMD, ...], ...) + - pattern: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...) + - pattern: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $CMD, ...], ...) + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... severity: ERROR - - id: go.grpc.security.grpc-server-insecure-connection.grpc-server-insecure-connection + - id: python.aws-lambda.security.dangerous-asyncio-shell.dangerous-asyncio-shell languages: - - go - message: Found an insecure gRPC server without 'grpc.Creds()' or options with credentials. This allows for a connection without encryption to this server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. Include credentials derived from an SSL certificate in order to create a secure gRPC connection. You can create credentials using 'credentials.NewServerTLSFromFile("cert.pem", "cert.key")'. + - python + message: Detected asyncio subprocess function with argument tainted by `event` object. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - confidence: HIGH + confidence: MEDIUM cwe: - - 'CWE-300: Channel Accessible by Non-Endpoint' - impact: LOW - likelihood: LOW + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption + - https://docs.python.org/3/library/asyncio-subprocess.html + - https://docs.python.org/3/library/shlex.html subcategory: - - audit + - vuln technology: - - grpc + - python + - aws-lambda mode: taint pattern-sinks: - - pattern: grpc.NewServer($OPT, ...) - requires: OPTIONS and not CREDS - - pattern: grpc.NewServer() - requires: EMPTY_CONSTRUCTOR + - patterns: + - focus-metavariable: $CMD + - pattern-either: + - pattern: $LOOP.subprocess_shell($PROTOCOL, $CMD) + - pattern: asyncio.subprocess.create_subprocess_shell($CMD, ...) + - pattern: asyncio.create_subprocess_shell($CMD, ...) pattern-sources: - - label: OPTIONS - pattern: grpc.ServerOption{ ... } - - label: CREDS - pattern: grpc.Creds(...) - - label: EMPTY_CONSTRUCTOR - pattern: grpc.NewServer() + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... severity: ERROR - - id: go.jwt-go.security.audit.jwt-parse-unverified.jwt-go-parse-unverified + - id: python.aws-lambda.security.dangerous-spawn-process.dangerous-spawn-process languages: - - go - message: Detected the decoding of a JWT token without a verify step. Don't use `ParseUnverified` unless you know what you're doing This method parses the token but doesn't validate the signature. It's only ever useful in cases where you know the signature is valid (because it has been checked previously in the stack) and you want to extract values from it. + - python + message: Detected `os` function with argument tainted by `event` object. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security confidence: MEDIUM cwe: - - 'CWE-345: Insufficient Verification of Data Authenticity' - impact: LOW - likelihood: LOW + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A08:2021 - Software and Data Integrity Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html subcategory: - - audit + - vuln technology: - - jwt - patterns: - - pattern-inside: | - import "github.com/dgrijalva/jwt-go" - ... - - pattern: | - $JWT.ParseUnverified(...) - severity: WARNING - - id: go.jwt-go.security.jwt-none-alg.jwt-go-none-algorithm + - python + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $CMD + - pattern-either: + - patterns: + - pattern: os.$METHOD($MODE, $CMD, ...) + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) + - patterns: + - pattern-inside: os.$METHOD($MODE, $BASH, ["-c", $CMD,...],...) + - metavariable-regex: + metavariable: $METHOD + regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-inside: os.$METHOD($MODE, $BASH, "-c", $CMD,...) + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... + severity: ERROR + - id: python.aws-lambda.security.dangerous-subprocess-use.dangerous-subprocess-use languages: - - go - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. + - python + message: Detected subprocess function with argument tainted by an `event` object. If this data can be controlled by a malicious actor, it may be an instance of command injection. The default option for `shell` is False, and this is secure by default. Consider removing the `shell=True` or setting it to False explicitely. Using `shell=False` means you have to split the command string into an array of strings for the command and its arguments. You may consider using 'shlex.split()' for this purpose. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - confidence: HIGH + confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW - likelihood: LOW + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + - https://docs.python.org/3/library/subprocess.html + - https://docs.python.org/3/library/shlex.html subcategory: - - audit + - vuln technology: - - jwt - patterns: - - pattern-either: - - pattern-inside: | - import "github.com/golang-jwt/jwt" - ... + - python + - aws-lambda + mode: taint + pattern-sanitizers: + - pattern: shlex.split(...) + - pattern: pipes.quote(...) + - pattern: shlex.quote(...) + pattern-sinks: + - patterns: + - pattern: subprocess.$FUNC(..., shell=True, ...) + pattern-sources: + - patterns: + - pattern: event - pattern-inside: | - import "github.com/dgrijalva/jwt-go" - ... - - pattern-either: - - pattern: | - jwt.SigningMethodNone - - pattern: jwt.UnsafeAllowNoneSignatureType + def $HANDLER(event, context): + ... severity: ERROR - - id: go.jwt-go.security.jwt.hardcoded-jwt-key + - id: python.aws-lambda.security.dangerous-system-call.dangerous-system-call languages: - - go - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + - python + message: Detected `os` function with argument tainted by `event` object. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. metadata: + asvs: + control_id: 5.2.4 Dyanmic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security confidence: MEDIUM cwe: - - 'CWE-798: Use of Hard-coded Credentials' + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true likelihood: HIGH owasp: - - A07:2021 - Identification and Authentication Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + - https://owasp.org/Top10/A03_2021-Injection + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html subcategory: - vuln technology: - - jwt - - secrets + - python mode: taint - options: - interfile: true pattern-sinks: - patterns: + - focus-metavariable: $CMD - pattern-either: - - pattern-inside: | - $TOKEN.SignedString($F) - - focus-metavariable: $F + - pattern: os.system($CMD,...) + - pattern: os.popen($CMD,...) + - pattern: os.popen2($CMD,...) + - pattern: os.popen3($CMD,...) + - pattern: os.popen4($CMD,...) pattern-sources: - patterns: + - pattern: event - pattern-inside: | - []byte("$F") - severity: WARNING - - id: go.lang.best-practice.channel-guarded-with-mutex.channel-guarded-with-mutex + def $HANDLER(event, context): + ... + severity: ERROR + - id: python.aws-lambda.security.dynamodb-filter-injection.dynamodb-filter-injection languages: - - go - message: Detected a channel guarded with a mutex. Channels already have an internal mutex, so this is unnecessary. Remove the mutex. See https://hackmongo.com/page/golang-antipatterns/#guarded-channel for more information. + - python + message: Detected DynamoDB query filter that is tainted by `$EVENT` object. This could lead to NoSQL injection if the variable is user-controlled and not properly sanitized. Explicitly assign query params instead of passing data from `$EVENT` directly to DynamoDB client. metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-943: Improper Neutralization of Special Elements in Data Query Logic' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + references: + - https://medium.com/appsecengineer/dynamodb-injection-1db99c2454ac + subcategory: + - vuln technology: - - go - pattern-either: - - pattern: | - $MUX.Lock() - $VALUE <- $CHANNEL - $MUX.Unlock() - - pattern: | - $MUX.Lock() - $VALUE = <- $CHANNEL - $MUX.Unlock() - severity: WARNING - - id: go.lang.best-practice.hidden-goroutine.hidden-goroutine + - python + - boto3 + - aws-lambda + - dynamodb + mode: taint + pattern-sanitizers: + - patterns: + - pattern: | + {...} + pattern-sinks: + - patterns: + - focus-metavariable: $SINK + - pattern-either: + - pattern: $TABLE.scan(..., ScanFilter = $SINK, ...) + - pattern: $TABLE.query(..., QueryFilter = $SINK, ...) + - pattern-either: + - patterns: + - pattern-inside: | + $TABLE = $DB.Table(...) + ... + - pattern-inside: | + $DB = boto3.resource('dynamodb', ...) + ... + - pattern-inside: | + $TABLE = boto3.client('dynamodb', ...) + ... + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... + severity: ERROR + - id: python.aws-lambda.security.mysql-sqli.mysql-sqli languages: - - go - message: Detected a hidden goroutine. Function invocations are expected to synchronous, and this function will execute asynchronously because all it does is call a goroutine. Instead, remove the internal goroutine and call the function using 'go'. + - python + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute(''SELECT * FROM projects WHERE status = %s'', (''active''))`' metadata: - category: best-practice + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html + - https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-executemany.html + subcategory: + - vuln technology: - - go - patterns: - - pattern-not: | - func $FUNC(...) { - go func() { - ... - }(...) - $MORE - } - - pattern: | - func $FUNC(...) { - go func() { - ... - }(...) - } - severity: WARNING - - id: go.lang.correctness.looppointer.exported_loop_pointer - languages: - - go - message: '`$VALUE` is a loop pointer that may be exported from the loop. This pointer is shared between loop iterations, so the exported reference will always point to the last loop value, which is likely unintentional. To fix, copy the pointer to a new pointer within the loop.' - metadata: - category: correctness - references: - - https://github.com/kyoh86/looppointer - technology: - - go - pattern-either: - - pattern: | - for _, $VALUE := range $SOURCE { - <... &($VALUE) ...> - } - - pattern: | - for _, $VALUE := range $SOURCE { - <... func() { <... &$VALUE ...> } ...> - } - - pattern: | - for _, $VALUE := range $SOURCE { - <... $ANYTHING(..., <... &$VALUE ...>, ...) ...> - } - severity: WARNING - - id: go.lang.correctness.overflow.overflow.integer-overflow-int16 - languages: - - go - message: Detected conversion of the result of a strconv.Atoi command to an int16. This could lead to an integer overflow, which could possibly result in unexpected behavior and even privilege escalation. Instead, use `strconv.ParseInt`. - metadata: - category: correctness - technology: - - go - patterns: - - pattern: | - $F, $ERR := strconv.Atoi($NUM) - ... - int16($F) - - metavariable-comparison: - comparison: $NUM > 32767 or $NUM < -32768 - metavariable: $NUM - strip: true - severity: WARNING - - id: go.lang.correctness.overflow.overflow.integer-overflow-int32 - languages: - - go - message: Detected conversion of the result of a strconv.Atoi command to an int32. This could lead to an integer overflow, which could possibly result in unexpected behavior and even privilege escalation. Instead, use `strconv.ParseInt`. - metadata: - category: correctness - technology: - - go - patterns: - - pattern: | - $F, $ERR := strconv.Atoi($NUM) - ... - int32($F) - - metavariable-comparison: - comparison: $NUM > 2147483647 or $NUM < -2147483648 - metavariable: $NUM - strip: true - severity: WARNING - - fix: | - 0600 - id: go.lang.correctness.permissions.file_permission.incorrect-default-permission - languages: - - go - message: Detected file permissions that are set to more than `0600` (user/owner can read and write). Setting file permissions to higher than `0600` is most likely unnecessary and violates the principle of least privilege. Instead, set permissions to be `0600` or less for os.Chmod, os.Mkdir, os.OpenFile, os.MkdirAll, and ioutil.WriteFile - metadata: - category: correctness - cwe: 'CWE-276: Incorrect Default Permissions' - references: - - https://github.com/securego/gosec/blob/master/rules/fileperms.go - source_rule_url: https://github.com/securego/gosec - technology: - - go - patterns: - - pattern-either: - - pattern: os.Chmod($NAME, $PERM) - - pattern: os.Mkdir($NAME, $PERM) - - pattern: os.OpenFile($NAME, $FLAG, $PERM) - - pattern: os.MkdirAll($NAME, $PERM) - - pattern: ioutil.WriteFile($NAME, $DATA, $PERM) - - metavariable-comparison: - base: 8 - comparison: $PERM > 0o600 - metavariable: $PERM - - focus-metavariable: - - $PERM + - aws-lambda + - mysql + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern: $CURSOR.execute($QUERY,...) + - pattern: $CURSOR.executemany($QUERY,...) + - pattern-either: + - pattern-inside: | + import mysql + ... + - pattern-inside: | + import mysql.cursors + ... + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... severity: WARNING - - id: go.lang.correctness.use-filepath-join.use-filepath-join + - id: python.aws-lambda.security.psycopg-sqli.psycopg-sqli languages: - - go - message: '`path.Join(...)` always joins using a forward slash. This may cause issues on Windows or other systems using a different delimiter. Use `filepath.Join(...)` instead which uses OS-specific path separators.' + - python + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute(''SELECT * FROM projects WHERE status = %s'', ''active'')`' metadata: - category: correctness - confidence: LOW - impact: HIGH - likelihood: LOW + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://parsiya.net/blog/2019-03-09-path.join-considered-harmful/ - - https://go.dev/src/path/path.go?s=4034:4066#L145 + - https://www.psycopg.org/docs/cursor.html#cursor.execute + - https://www.psycopg.org/docs/cursor.html#cursor.executemany + - https://www.psycopg.org/docs/cursor.html#cursor.mogrify subcategory: - - audit + - vuln technology: - - go + - aws-lambda + - psycopg + - psycopg2 mode: taint - pattern-sanitizers: - - pattern: | - url.Parse(...) - ... pattern-sinks: - - pattern: path.Join(...) - pattern-sources: - - patterns: - - pattern: | - ($STR : string) - - pattern-not: | - "..." - patterns: + - focus-metavariable: $QUERY + - pattern-either: + - pattern: $CURSOR.execute($QUERY,...) + - pattern: $CURSOR.executemany($QUERY,...) + - pattern: $CURSOR.mogrify($QUERY,...) - pattern-inside: | - import "path" + import psycopg2 ... - - pattern: path.$FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: ^(Base|Clean|Dir|Split)$ + pattern-sources: - patterns: + - pattern: event - pattern-inside: | - import "path/filepath" - ... - - pattern: filepath.$FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: ^(Base|Clean|Dir|FromSlash|Glob|Rel|Split|SplitList|ToSlash|VolumeName)$ - severity: WARNING - - id: go.lang.correctness.useless-eqeq.eqeq-is-bad - languages: - - go - message: Detected useless comparison operation `$X == $X` or `$X != $X`. This will always return 'True' or 'False' and therefore is not necessary. Instead, remove this comparison operation or use another comparison expression that is not deterministic. - metadata: - category: correctness - technology: - - go - patterns: - - pattern-not-inside: assert(...) - - pattern-either: - - pattern: $X == $X - - pattern: $X != $X - - pattern-not: 1 == 1 - severity: INFO - - id: go.lang.correctness.useless-eqeq.hardcoded-eq-true-or-false - languages: - - go - message: Detected useless if statement. 'if (True)' and 'if (False)' always result in the same behavior, and therefore is not necessary in the code. Remove the 'if (False)' expression completely or just the 'if (True)' comparison depending on which expression is in the code. - metadata: - category: correctness - technology: - - go - pattern-either: - - pattern: if (true) { ... } - - pattern: if (false) { ... } - severity: INFO - - id: go.lang.maintainability.useless-ifelse.useless-if-conditional - languages: - - go - message: Detected an if block that checks for the same condition on both branches (`$X`). The second condition check is useless as it is the same as the first, and therefore can be removed from the code, - metadata: - category: maintainability - technology: - - go - pattern: | - if ($X) { - ... - } else if ($X) { - ... - } - severity: WARNING - - id: go.lang.maintainability.useless-ifelse.useless-if-body - languages: - - go - message: Detected identical statements in the if body and the else body of an if-statement. This will lead to the same code being executed no matter what the if-expression evaluates to. Instead, remove the if statement. - metadata: - category: maintainability - technology: - - go - pattern: | - if ($X) { - $S - } else { - $S - } + def $HANDLER(event, context): + ... severity: WARNING - - id: go.lang.security.audit.crypto.bad_imports.insecure-module-used + - id: python.aws-lambda.security.pymssql-sqli.pymssql-sqli languages: - - go - message: The package `net/http/cgi` is on the import blocklist. The package is vulnerable to httpoxy attacks (CVE-2015-5386). It is recommended to use `net/http` or a web framework to build a web application instead. + - python + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute(''SELECT * FROM projects WHERE status = %s'', ''active'')`' metadata: category: security confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: HIGH owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://godoc.org/golang.org/x/crypto/sha3 - source-rule-url: https://github.com/securego/gosec + - https://pypi.org/project/pymssql/ subcategory: - - audit + - vuln technology: - - go - pattern-either: + - aws-lambda + - pymssql + mode: taint + pattern-sinks: - patterns: + - focus-metavariable: $QUERY + - pattern: $CURSOR.execute($QUERY,...) - pattern-inside: | - import "net/http/cgi" + import pymssql ... - - pattern: | - cgi.$FUNC(...) + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... severity: WARNING - - id: go.lang.security.audit.crypto.insecure_ssh.avoid-ssh-insecure-ignore-host-key + - id: python.aws-lambda.security.pymysql-sqli.pymysql-sqli languages: - - go - message: Disabled host key verification detected. This allows man-in-the-middle attacks. Use the 'golang.org/x/crypto/ssh/knownhosts' package to do host key verification. See https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ to learn more about the problem and how to fix it. + - python + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute(''SELECT * FROM projects WHERE status = %s'', (''active''))`' metadata: category: security confidence: MEDIUM cwe: - - 'CWE-322: Key Exchange without Entity Authentication' - impact: LOW - likelihood: LOW + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A02:2021 - Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ - - https://gist.github.com/Skarlso/34321a230cf0245018288686c9e70b2d - source-rule-url: https://github.com/securego/gosec + - https://pypi.org/project/PyMySQL/#id4 subcategory: - - audit + - vuln technology: - - go - pattern: ssh.InsecureIgnoreHostKey() + - aws-lambda + - pymysql + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern: $CURSOR.execute($QUERY,...) + - pattern-either: + - pattern-inside: | + import pymysql + ... + - pattern-inside: | + import pymysql.cursors + ... + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... severity: WARNING - - fix: | - crypto/rand - id: go.lang.security.audit.crypto.math_random.math-random-used + - id: python.aws-lambda.security.sqlalchemy-sqli.sqlalchemy-sqli languages: - - go - message: Do not use `math/rand`. Use `crypto/rand` instead. + - python + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute(''SELECT * FROM projects WHERE status = ?'', ''active'')`' metadata: category: security confidence: MEDIUM cwe: - - 'CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)' + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: HIGH owasp: - - A02:2021 - Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#secure-random-number-generation + - https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Connection.execute subcategory: - vuln technology: - - go - patterns: - - pattern-either: - - pattern: | - import $RAND "$MATH" - - pattern: | - import "$MATH" - - metavariable-regex: - metavariable: $MATH - regex: ^(math/rand(\/v[0-9]+)*)$ - - pattern-either: + - aws-lambda + - sqlalchemy + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $QUERY + - pattern: $CURSOR.execute($QUERY,...) - pattern-inside: | + import sqlalchemy ... - rand.$FUNC(...) + pattern-sources: + - patterns: + - pattern: event - pattern-inside: | - ... - $RAND.$FUNC(...) - - focus-metavariable: - - $MATH - severity: WARNING - - fix: | - tls.Config{ $...CONF, MinVersion: tls.VersionTLS13 } - id: go.lang.security.audit.crypto.missing-ssl-minversion.missing-ssl-minversion - languages: - - go - message: '`MinVersion` is missing from this TLS configuration. By default, TLS 1.2 is currently used as the minimum when acting as a client, and TLS 1.0 when acting as a server. General purpose web applications should default to TLS 1.3 with all other protocols disabled. Only where it is known that a web server must support legacy clients with unsupported an insecure browsers (such as Internet Explorer 10), it may be necessary to enable TLS 1.0 to provide support. Add `MinVersion: tls.VersionTLS13'' to the TLS configuration to bump the minimum version to TLS 1.3.' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://golang.org/doc/go1.14#crypto/tls - - https://golang.org/pkg/crypto/tls/#:~:text=MinVersion - - https://www.us-cert.gov/ncas/alerts/TA14-290A - source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go - subcategory: - - guardrail - technology: - - go - patterns: - - pattern: | - tls.Config{ $...CONF } - - pattern-not: | - tls.Config{..., MinVersion: ..., ...} + def $HANDLER(event, context): + ... severity: WARNING - - fix-regex: - regex: VersionSSL30 - replacement: VersionTLS13 - id: go.lang.security.audit.crypto.ssl.ssl-v3-is-insecure + - id: python.aws-lambda.security.tainted-code-exec.tainted-code-exec languages: - - go - message: SSLv3 is insecure because it has known vulnerabilities. Starting with go1.14, SSLv3 will be removed. Instead, use 'tls.VersionTLS13'. + - python + message: Detected the use of `exec/eval`.This can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources. metadata: + asvs: + control_id: 5.2.4 Dyanmic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - confidence: HIGH + confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: MEDIUM owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A03:2021 - Injection references: - - https://golang.org/doc/go1.14#crypto/tls - - https://www.us-cert.gov/ncas/alerts/TA14-290A - source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - go - pattern: 'tls.Config{..., MinVersion: $TLS.VersionSSL30, ...}' + - python + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: eval($CODE, ...) + - pattern: exec($CODE, ...) + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... severity: WARNING - - id: go.lang.security.audit.crypto.tls.tls-with-insecure-cipher + - id: python.aws-lambda.security.tainted-html-response.tainted-html-response languages: - - go - message: Detected an insecure CipherSuite via the 'tls' module. This suite is considered weak. Use the function 'tls.CipherSuites()' to get a list of good cipher suites. See https://golang.org/pkg/crypto/tls/#InsecureCipherSuites for why and what other cipher suites to use. + - python + message: Detected user input flowing into an HTML response. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. metadata: category: security - confidence: HIGH + confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM likelihood: HIGH owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://golang.org/pkg/crypto/tls/#InsecureCipherSuites - source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls.go + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - go - pattern-either: - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_RC4_128_SHA, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_AES_128_CBC_SHA256, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ...}} - - pattern: | - tls.CipherSuite{..., TLS_RSA_WITH_RC4_128_SHA, ...} - - pattern: | - tls.CipherSuite{..., TLS_RSA_WITH_3DES_EDE_CBC_SHA, ...} - - pattern: | - tls.CipherSuite{..., TLS_RSA_WITH_AES_128_CBC_SHA256, ...} - - pattern: | - tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, ...} - - pattern: | - tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_RC4_128_SHA, ...} - - pattern: | - tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, ...} - - pattern: | - tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, ...} - - pattern: | - tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ...} + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern: $BODY + - pattern-inside: | + {..., "headers": {..., "Content-Type": "text/html", ...}, "body": $BODY, ... } + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... severity: WARNING - - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-md5 + - id: python.aws-lambda.security.tainted-html-string.tainted-html-string languages: - - go - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - python + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates which will safely render HTML instead. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-328: Use of Weak Hash' + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: HIGH owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://github.com/securego/gosec#available-rules + - https://owasp.org/Top10/A03_2021-Injection subcategory: - vuln technology: - - go - patterns: - - pattern-inside: | - import "crypto/md5" - ... - - pattern-either: - - pattern: | - md5.New() - - pattern: | - md5.Sum(...) + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: '"$HTMLSTR" % ...' + - pattern: '"$HTMLSTR".format(...)' + - pattern: '"$HTMLSTR" + ...' + - pattern: f"$HTMLSTR{...}..." + - patterns: + - pattern-inside: | + $HTML = "$HTMLSTR" + ... + - pattern-either: + - pattern: $HTML % ... + - pattern: $HTML.format(...) + - pattern: $HTML + ... + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... + - pattern-not-inside: | + print(...) + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... severity: WARNING - - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-sha1 + - id: python.aws-lambda.security.tainted-pickle-deserialization.tainted-pickle-deserialization languages: - - go - message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + - python + message: Avoid using `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-328: Use of Weak Hash' + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM likelihood: MEDIUM owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://github.com/securego/gosec#available-rules + - https://docs.python.org/3/library/pickle.html + - https://davidhamann.de/2020/04/05/exploiting-python-pickle/ subcategory: - vuln technology: - - go - patterns: - - pattern-inside: | - import "crypto/sha1" - ... - - pattern-either: - - pattern: | - sha1.New() - - pattern: | - sha1.Sum(...) + - python + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - focus-metavariable: $SINK + - pattern-either: + - pattern: pickle.load($SINK,...) + - pattern: pickle.loads($SINK,...) + - pattern: _pickle.load($SINK,...) + - pattern: _pickle.loads($SINK,...) + - pattern: cPickle.load($SINK,...) + - pattern: cPickle.loads($SINK,...) + - pattern: dill.load($SINK,...) + - pattern: dill.loads($SINK,...) + - pattern: shelve.open($SINK,...) + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... severity: WARNING - - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-des + - id: python.aws-lambda.security.tainted-sql-string.tainted-sql-string languages: - - go - message: Detected DES cipher algorithm which is insecure. The algorithm is considered weak and has been deprecated. Use AES instead. + - python + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/SQL_Injection + subcategory: + - vuln + technology: + - aws-lambda + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR" % ... + - pattern: | + "$SQLSTR".format(...) + - pattern: | + f"$SQLSTR{...}..." + - metavariable-regex: + metavariable: $SQLSTR + regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*= + - pattern-not-inside: | + print(...) + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context): + ... + severity: ERROR + - id: python.boto3.security.hardcoded-token.hardcoded-token + languages: + - python + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + - https://bento.dev/checks/boto3/hardcoded-access-token/ + - https://aws.amazon.com/blogs/security/what-to-do-if-you-inadvertently-expose-an-aws-access-key/ + subcategory: + - vuln + technology: + - boto3 + - secrets + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $W(...,$TOKEN="$VALUE",...) + - pattern: $BOTO. ... .$W(...,$TOKEN="$VALUE",...) + - metavariable-regex: + metavariable: $TOKEN + regex: (aws_session_token|aws_access_key_id|aws_secret_access_key) + - metavariable-pattern: + language: generic + metavariable: $VALUE + patterns: + - pattern-either: + - pattern-regex: ^AKI + - pattern-regex: ^[A-Za-z0-9/+=]+$ + - metavariable-analysis: + analyzer: entropy + metavariable: $VALUE + pattern-sources: + - pattern: | + "..." + severity: WARNING + - id: python.cryptography.security.empty-aes-key.empty-aes-key + languages: + - python + message: Potential empty AES encryption key. Using an empty key in AES encryption can result in weak encryption and may allow attackers to easily decrypt sensitive data. Ensure that a strong, non-empty key is used for AES encryption. metadata: category: security confidence: MEDIUM cwe: - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-310: Cryptographic Issues' + functional-categories: + - crypto::search::key-length::pycrypto + - crypto::search::key-length::pycryptodome + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: A6:2017 misconfiguration + references: + - https://cwe.mitre.org/data/definitions/327.html + - https://cwe.mitre.org/data/definitions/310.html + subcategory: + - vuln + technology: + - python + - pycrypto + - pycryptodome + patterns: + - pattern: AES.new("",...) + severity: WARNING + - fix: AES + id: python.cryptography.security.insecure-cipher-algorithms-arc4.insecure-cipher-algorithm-arc4 + languages: + - python + message: ARC4 (Alleged RC4) is a stream cipher with serious weaknesses in its initial stream output. Its use is strongly discouraged. ARC4 does not use mode constructions. Use a strong symmetric cipher such as EAS instead. With the `cryptography` package it is recommended to use the `Fernet` which is a secure implementation of AES in CBC mode with a 128-bit key. Alternatively, keep using the `Cipher` class from the hazmat primitives but use the AES algorithm instead. + metadata: + bandit-code: B304 + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::cryptography impact: MEDIUM likelihood: MEDIUM owasp: - A03:2017 - Sensitive Data Exposure - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://github.com/securego/gosec#available-rules + - https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#weak-ciphers + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L98 subcategory: - vuln technology: - - go + - cryptography patterns: - - pattern-inside: | - import "crypto/des" - ... - - pattern-either: - - pattern: | - des.NewTripleDESCipher(...) - - pattern: | - des.NewCipher(...) + - pattern: cryptography.hazmat.primitives.ciphers.algorithms.$ARC4($KEY) + - pattern-inside: cryptography.hazmat.primitives.ciphers.Cipher(...) + - metavariable-regex: + metavariable: $ARC4 + regex: ^(ARC4)$ + - focus-metavariable: $ARC4 severity: WARNING - - id: go.lang.security.audit.crypto.use_of_weak_crypto.use-of-rc4 + - fix: AES + id: python.cryptography.security.insecure-cipher-algorithms-blowfish.insecure-cipher-algorithm-blowfish languages: - - go - message: Detected RC4 cipher algorithm which is insecure. The algorithm has many known vulnerabilities. Use AES instead. + - python + message: Blowfish is a block cipher developed by Bruce Schneier. It is known to be susceptible to attacks when using weak keys. The author has recommended that users of Blowfish move to newer algorithms such as AES. With the `cryptography` package it is recommended to use `Fernet` which is a secure implementation of AES in CBC mode with a 128-bit key. Alternatively, keep using the `Cipher` class from the hazmat primitives but use the AES algorithm instead. metadata: + bandit-code: B304 category: security confidence: MEDIUM cwe: - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::cryptography impact: MEDIUM likelihood: MEDIUM owasp: - A03:2017 - Sensitive Data Exposure - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://github.com/securego/gosec#available-rules + - https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#weak-ciphers + - https://tools.ietf.org/html/rfc5469 + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L98 subcategory: - vuln technology: - - go + - cryptography patterns: - - pattern-inside: | - import "crypto/rc4" - ... - - pattern: rc4.NewCipher(...) + - pattern: cryptography.hazmat.primitives.ciphers.algorithms.$BLOWFISH($KEY) + - metavariable-regex: + metavariable: $BLOWFISH + regex: ^(Blowfish)$ + - focus-metavariable: $BLOWFISH severity: WARNING - - fix: | - 2048 - id: go.lang.security.audit.crypto.use_of_weak_rsa_key.use-of-weak-rsa-key + - fix: AES + id: python.cryptography.security.insecure-cipher-algorithms.insecure-cipher-algorithm-idea languages: - - go - message: RSA keys should be at least 2048 bits + - python + message: IDEA (International Data Encryption Algorithm) is a block cipher created in 1991. It is an optional component of the OpenPGP standard. This cipher is susceptible to attacks when using weak keys. It is recommended that you do not use this cipher for new applications. Use a strong symmetric cipher such as EAS instead. With the `cryptography` package it is recommended to use `Fernet` which is a secure implementation of AES in CBC mode with a 128-bit key. Alternatively, keep using the `Cipher` class from the hazmat primitives but use the AES algorithm instead. metadata: + bandit-code: B304 category: security - confidence: HIGH + confidence: MEDIUM cwe: - - 'CWE-326: Inadequate Encryption Strength' + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::cryptography impact: MEDIUM - likelihood: HIGH + likelihood: MEDIUM owasp: - A03:2017 - Sensitive Data Exposure - A02:2021 - Cryptographic Failures references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms - source-rule-url: https://github.com/securego/gosec/blob/master/rules/rsa.go + - https://tools.ietf.org/html/rfc5469 + - https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#cryptography.hazmat.primitives.ciphers.algorithms.IDEA + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L98 subcategory: - - audit + - vuln technology: - - go + - cryptography patterns: - - pattern-either: - - pattern: | - rsa.GenerateKey(..., $BITS) - - pattern: | - rsa.GenerateMultiPrimeKey(..., $BITS) - - metavariable-comparison: - comparison: $BITS < 2048 - metavariable: $BITS - - focus-metavariable: - - $BITS + - pattern: cryptography.hazmat.primitives.ciphers.algorithms.$IDEA($KEY) + - metavariable-regex: + metavariable: $IDEA + regex: ^(IDEA)$ + - focus-metavariable: $IDEA severity: WARNING - - id: go.lang.security.audit.dangerous-command-write.dangerous-command-write + - fix: cryptography.hazmat.primitives.ciphers.modes.GCM($IV) + id: python.cryptography.security.insecure-cipher-mode-ecb.insecure-cipher-mode-ecb languages: - - go - message: Detected non-static command inside Write. Audit the input to '$CW.Write'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + - python + message: ECB (Electronic Code Book) is the simplest mode of operation for block ciphers. Each block of data is encrypted in the same way. This means identical plaintext blocks will always result in identical ciphertext blocks, which can leave significant patterns in the output. Use a different, cryptographically strong mode instead, such as GCM. metadata: + bandit-code: B305 category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::mode::cryptography + impact: LOW likelihood: LOW owasp: - - A01:2017 - Injection - - A03:2021 - Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#insecure-modes + - https://crypto.stackexchange.com/questions/20941/why-shouldnt-i-use-ecb-encryption + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L101 subcategory: - audit technology: - - go - patterns: - - pattern: | - $CW.Write($BYTE) - - pattern-inside: | - $CW,$ERR := $CMD.StdinPipe() - ... - - pattern-not: | - $CW.Write("...") - - pattern-not: | - $CW.Write([]byte("...")) - - pattern-not: | - $CW.Write([]byte("..."+"...")) - - pattern-not-inside: | - $BYTE = []byte("..."); - ... - - pattern-not-inside: | - $BYTE = []byte("..."+"..."); - ... - - pattern-inside: | - import "os/exec" - ... - severity: ERROR - - id: go.lang.security.audit.dangerous-exec-cmd.dangerous-exec-cmd + - cryptography + pattern: cryptography.hazmat.primitives.ciphers.modes.ECB($IV) + severity: WARNING + - fix: SHA256 + id: python.cryptography.security.insecure-hash-algorithms-md5.insecure-hash-algorithm-md5 languages: - - go - message: Detected non-static command inside exec.Cmd. Audit the input to 'exec.Cmd'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + - python + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: + bandit-code: B303 category: security confidence: MEDIUM cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::cryptography + impact: MEDIUM likelihood: LOW owasp: - - A03:2021 - Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/#md5 + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 subcategory: - - audit + - vuln technology: - - go + - cryptography patterns: - - pattern-either: - - patterns: - - pattern: | - exec.Cmd {...,Path: $CMD,...} - - pattern-not: | - exec.Cmd {...,Path: "...",...} - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - - pattern-not-inside: | - $CMD = "..."; - ... - - patterns: - - pattern: | - exec.Cmd {...,Args: $ARGS,...} - - pattern-not: | - exec.Cmd {...,Args: []string{...},...} - - pattern-not-inside: | - $ARGS = []string{"...",...}; - ... - - pattern-not-inside: | - $CMD = "..."; - ... - $ARGS = []string{$CMD,...}; - ... - - pattern-not-inside: | - $CMD = exec.LookPath("..."); - ... - $ARGS = []string{$CMD,...}; - ... - - patterns: - - pattern: | - exec.Cmd {...,Args: []string{$CMD,...},...} - - pattern-not: | - exec.Cmd {...,Args: []string{"...",...},...} - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - - pattern-not-inside: | - $CMD = "..."; - ... - - patterns: - - pattern-either: - - pattern: | - exec.Cmd {...,Args: []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...} - - patterns: - - pattern: | - exec.Cmd {...,Args: []string{$CMD,"-c",$EXE,...},...} - - pattern-inside: | - $CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/"); - ... - - pattern-not: | - exec.Cmd {...,Args: []string{"...","...","...",...},...} - - pattern-not-inside: | - $EXE = "..."; - ... - - pattern-inside: | - import "os/exec" - ... - severity: ERROR - - id: go.lang.security.audit.dangerous-exec-command.dangerous-exec-command + - pattern: cryptography.hazmat.primitives.hashes.$MD5() + - metavariable-regex: + metavariable: $MD5 + regex: ^(MD5)$ + - focus-metavariable: $MD5 + severity: WARNING + - fix: | + SHA256 + id: python.cryptography.security.insecure-hash-algorithms.insecure-hash-algorithm-sha1 languages: - - go - message: Detected non-static command inside Command. Audit the input to 'exec.Command'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + - python + message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: + bandit-code: B303 category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + functional-categories: + - crypto::search::symmetric-algorithm::cryptography + impact: MEDIUM likelihood: LOW owasp: - - A03:2021 - Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/#sha-1 + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 subcategory: - - audit + - vuln technology: - - go + - cryptography + patterns: + - pattern: cryptography.hazmat.primitives.hashes.$SHA(...) + - metavariable-pattern: + metavariable: $SHA + pattern: | + SHA1 + - focus-metavariable: $SHA + severity: WARNING + - fix: | + 2048 + id: python.cryptography.security.insufficient-dsa-key-size.insufficient-dsa-key-size + languages: + - python + message: Detected an insufficient key size for DSA. NIST recommends a key size of 2048 or higher. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::key-length::cryptography + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.cosic.esat.kuleuven.be/ecrypt/ecrypt2/documents/D.SPA.20.pdf + - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/dsa/ + - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py + subcategory: + - vuln + technology: + - cryptography patterns: - pattern-either: - - patterns: - - pattern-either: - - pattern: | - exec.Command($CMD,...) - - pattern: | - exec.CommandContext($CTX,$CMD,...) - - pattern-not: | - exec.Command("...",...) - - pattern-not: | - exec.CommandContext($CTX,"...",...) - - patterns: - - pattern-either: - - pattern: | - exec.Command("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) - - pattern: | - exec.CommandContext($CTX,"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) - - pattern-not: | - exec.Command("...","...","...",...) - - pattern-not: | - exec.CommandContext($CTX,"...","...","...",...) - - pattern-either: - - pattern: | - exec.Command("=~/\/bin\/env/","=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) - - pattern: | - exec.CommandContext($CTX,"=~/\/bin\/env/","=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) - - pattern-inside: | - import "os/exec" - ... - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - - pattern-not-inside: | - $CMD = "..."; - ... - severity: ERROR - - id: go.lang.security.audit.dangerous-syscall-exec.dangerous-syscall-exec + - pattern: cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key(..., key_size=$SIZE, ...) + - pattern: cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key($SIZE, ...) + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE + - focus-metavariable: $SIZE + severity: WARNING + - fix: | + SECP256R1 + id: python.cryptography.security.insufficient-ec-key-size.insufficient-ec-key-size languages: - - go - message: Detected non-static command inside Exec. Audit the input to 'syscall.Exec'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + - python + message: Detected an insufficient curve size for EC. NIST recommends a key size of 224 or higher. For example, use 'ec.SECP256R1'. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::key-length::cryptography + impact: MEDIUM + likelihood: MEDIUM owasp: - - A03:2021 - Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A03_2021-Injection + - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf + - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/#elliptic-curves + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py subcategory: - audit technology: - - go + - cryptography patterns: - - pattern-either: - - patterns: - - pattern: | - syscall.$METHOD($BIN,...) - - pattern-not: | - syscall.$METHOD("...",...) - - pattern-not-inside: | - $BIN,$ERR := exec.LookPath("..."); - ... - - pattern-not-inside: | - $BIN = "..."; - ... - - patterns: - - pattern: | - syscall.$METHOD($BIN,$ARGS,...) - - pattern-not: | - syscall.$METHOD($BIN,[]string{"...",...},...) - - pattern-not-inside: | - $ARGS := []string{"...",...}; - ... - - pattern-not-inside: | - $CMD = "..."; - ... - $ARGS = []string{$CMD,...}; - ... - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - $ARGS = []string{$CMD,...}; - ... - - patterns: - - pattern: | - syscall.$METHOD($BIN,[]string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...) - - pattern-not: | - syscall.$METHOD($BIN,[]string{"...","...","...",...},...) - - patterns: - - pattern: | - syscall.$METHOD($BIN,$ARGS,...) - - pattern-either: - - pattern-inside: | - $ARGS := []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...}; - ... - - pattern-inside: | - $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/"; - ... - $ARGS = []string{$CMD,"-c",$EXE,...}; - ... - - pattern-inside: | - $CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/"); - ... - $ARGS = []string{$CMD,"-c",$EXE,...}; - ... - - pattern-not-inside: | - $ARGS := []string{"...","...","...",...}; - ... - - pattern-not-inside: | - $CMD = "..."; - ... - $ARGS = []string{$CMD,"...","...",...}; - ... - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - $ARGS = []string{$CMD,"...","...",...}; - ... - - pattern-inside: | - import "syscall" - ... - - metavariable-regex: - metavariable: $METHOD - regex: (Exec|ForkExec) - severity: ERROR - - id: go.lang.security.audit.database.string-formatted-query.string-formatted-query - languages: - - go - message: String-formatted SQL query detected. This could lead to SQL injection if the string is not sanitized properly. Audit this call to ensure the SQL is not manipulable by external data. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://github.com/securego/gosec - subcategory: - - audit - technology: - - go - patterns: - - metavariable-regex: - metavariable: $OBJ - regex: (?i).*(db|database) - - pattern-not-inside: | - $VAR = "..." + "..." - ... - $OBJ.$SINK(..., $VAR, ...) - - pattern-not: $OBJ.Exec("...") - - pattern-not: $OBJ.ExecContext($CTX, "...") - - pattern-not: $OBJ.Query("...") - - pattern-not: $OBJ.QueryContext($CTX, "...") - - pattern-not: $OBJ.QueryRow("...") - - pattern-not: $OBJ.QueryRow($CTX, "...") - - pattern-not: $OBJ.QueryRowContext($CTX, "...") - - pattern-either: - - pattern: $OBJ.Exec($X + ...) - - pattern: $OBJ.ExecContext($CTX, $X + ...) - - pattern: $OBJ.Query($X + ...) - - pattern: $OBJ.QueryContext($CTX, $X + ...) - - pattern: $OBJ.QueryRow($X + ...) - - pattern: $OBJ.QueryRow($CTX, $X + ...) - - pattern: $OBJ.QueryRowContext($CTX, $X + ...) - - pattern: $OBJ.Exec(fmt.$P("...", ...)) - - pattern: $OBJ.ExecContext($CTX, fmt.$P("...", ...)) - - pattern: $OBJ.Query(fmt.$P("...", ...)) - - pattern: $OBJ.QueryContext($CTX, fmt.$P("...", ...)) - - pattern: $OBJ.QueryRow(fmt.$P("...", ...)) - - pattern: $OBJ.QueryRow($CTX, fmt.$U("...", ...)) - - pattern: $OBJ.QueryRowContext($CTX, fmt.$P("...", ...)) - - patterns: - - pattern-either: - - pattern: $QUERY = fmt.Fprintf($F, "$SQLSTR", ...) - - pattern: $QUERY = fmt.Sprintf("$SQLSTR", ...) - - pattern: $QUERY = fmt.Printf("$SQLSTR", ...) - - pattern: $QUERY = $X + ... - - pattern-either: - - pattern-inside: | - func $FUNC(...) { - ... - $OBJ.Query($QUERY, ...) - ... - } - - pattern-inside: | - func $FUNC(...) { - ... - $OBJ.ExecContext($CTX, $QUERY, ...) - ... - } - - pattern-inside: | - func $FUNC(...) { - ... - $OBJ.Exec($QUERY, ...) - ... - } - - pattern-inside: | - func $FUNC(...) { - ... - $OBJ.QueryRow($CTX, $QUERY) - ... - } - - pattern-inside: | - func $FUNC(...) { - ... - $OBJ.QueryRow($QUERY) - ... - } - - pattern-inside: | - func $FUNC(...) { - ... - $OBJ.QueryContext($CTX, $QUERY) - ... - } - - pattern-inside: | - func $FUNC(...) { - ... - $OBJ.QueryRowContext($CTX, $QUERY, ...) - ... - } + - pattern-inside: cryptography.hazmat.primitives.asymmetric.ec.generate_private_key(...) + - pattern: cryptography.hazmat.primitives.asymmetric.ec.$SIZE + - metavariable-pattern: + metavariable: $SIZE + pattern-either: + - pattern: SECP192R1 + - pattern: SECT163K1 + - pattern: SECT163R2 + - focus-metavariable: $SIZE severity: WARNING - - id: go.lang.security.audit.md5-used-as-password.md5-used-as-password + - fix: | + 2048 + id: python.cryptography.security.insufficient-rsa-key-size.insufficient-rsa-key-size languages: - - go - message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as bcrypt. You can use the `golang.org/x/crypto/bcrypt` package. + - python + message: Detected an insufficient key size for RSA. NIST recommends a key size of 2048 or higher. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + - 'CWE-326: Inadequate Encryption Strength' + functional-categories: + - crypto::search::key-length::cryptography impact: MEDIUM - interfile: true likelihood: MEDIUM owasp: - A03:2017 - Sensitive Data Exposure - A02:2021 - Cryptographic Failures references: - - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html - - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords - - https://github.com/returntocorp/semgrep-rules/issues/1609 - - https://pkg.go.dev/golang.org/x/crypto/bcrypt - subcategory: - - vuln - technology: - - md5 - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern: $FUNCTION(...) - - metavariable-regex: - metavariable: $FUNCTION - regex: (?i)(.*password.*) - pattern-sources: - - patterns: - - pattern-either: - - pattern: md5.New - - pattern: md5.Sum - severity: WARNING - - id: go.lang.security.audit.net.bind_all.avoid-bind-to-all-interfaces - languages: - - go - message: Detected a network listener listening on 0.0.0.0 or an empty string. This could unexpectedly expose the server publicly as it binds to all available interfaces. Instead, specify another IP address that is not 0.0.0.0 nor the empty string. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://github.com/securego/gosec + - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/ + - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py subcategory: - audit technology: - - go - pattern-either: - - pattern: tls.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) - - pattern: net.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) - - pattern: tls.Listen($NETWORK, "=~/^:.*$/", ...) - - pattern: net.Listen($NETWORK, "=~/^:.*$/", ...) + - cryptography + patterns: + - pattern-either: + - pattern: cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key(..., key_size=$SIZE, ...) + - pattern: cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key($EXP, $SIZE, ...) + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE + - focus-metavariable: $SIZE severity: WARNING - - fix-regex: - regex: (HttpOnly\s*:\s+)false - replacement: \1true - id: go.lang.security.audit.net.cookie-missing-httponly.cookie-missing-httponly + - id: python.cryptography.security.mode-without-authentication.crypto-mode-without-authentication languages: - - go - message: A session cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie which mitigates XSS attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' in the Cookie. + - python + message: 'An encryption mode of operation is being used without proper message authentication. This can potentially result in the encrypted content to be decrypted by an attacker. Consider instead use an AEAD mode of operation like GCM. ' metadata: category: security confidence: MEDIUM cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM likelihood: LOW owasp: - - A05:2021 - Security Misconfiguration + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go - - https://golang.org/src/net/http/cookie.go + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures subcategory: - - vuln + - audit technology: - - go + - cryptography patterns: - - pattern-not-inside: | - http.Cookie{ - ..., - HttpOnly: true, - ..., - } - - pattern: | - http.Cookie{ - ..., - } - severity: WARNING - - fix-regex: - regex: (Secure\s*:\s+)false - replacement: \1true - id: go.lang.security.audit.net.cookie-missing-secure.cookie-missing-secure + - pattern-either: + - patterns: + - pattern: | + Cipher(..., $HAZMAT_MODE(...),...) + - pattern-not-inside: | + Cipher(..., $HAZMAT_MODE(...),...) + ... + HMAC(...) + - pattern-not-inside: | + Cipher(..., $HAZMAT_MODE(...),...) + ... + hmac.HMAC(...) + - metavariable-pattern: + metavariable: $HAZMAT_MODE + patterns: + - pattern-either: + - pattern: modes.CTR + - pattern: modes.CBC + - pattern: modes.CFB + - pattern: modes.OFB + severity: ERROR + - fix: | + True + id: python.distributed.security.require-encryption languages: - - go - message: A session cookie was detected without setting the 'Secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'Secure' flag by setting 'Secure' to 'true' in the Options struct. + - python + message: Initializing a security context for Dask (`distributed`) without "require_encryption" keyword argument may silently fail to provide security. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A05:2021 - Security Misconfiguration + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go - - https://golang.org/src/net/http/cookie.go + - https://distributed.dask.org/en/latest/tls.html?highlight=require_encryption#parameters subcategory: - vuln technology: - - go + - distributed patterns: - - pattern-not-inside: | - http.Cookie{ - ..., - Secure: true, - ..., - } - pattern: | - http.Cookie{ - ..., - } + distributed.security.Security(..., require_encryption=$VAL, ...) + - metavariable-pattern: + metavariable: $VAL + pattern: | + False + - focus-metavariable: $VAL severity: WARNING - - id: go.lang.security.audit.net.dynamic-httptrace-clienttrace.dynamic-httptrace-clienttrace + - id: python.django.security.audit.avoid-insecure-deserialization.avoid-insecure-deserialization languages: - - go - message: Detected a potentially dynamic ClientTrace. This occurred because semgrep could not find a static definition for '$TRACE'. Dynamic ClientTraces are dangerous because they deserialize function code to run when certain Request events occur, which could lead to code being run without your knowledge. Ensure that your ClientTrace is statically defined. + - python + message: Avoid using insecure deserialization library, backed by `pickle`, `_pickle`, `cpickle`, `dill`, `shelve`, or `yaml`, which are known to lead to remote code execution vulnerabilities. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-913: Improper Control of Dynamically-Managed Code Resources' - impact: LOW - likelihood: LOW + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A01:2021 - Broken Access Control + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures references: - - https://github.com/returntocorp/semgrep-rules/issues/518 + - https://docs.python.org/3/library/pickle.html subcategory: - vuln technology: - - go - patterns: - - pattern-not-inside: | - package $PACKAGE - ... - &httptrace.ClientTrace { ... } - ... - - pattern: httptrace.WithClientTrace($ANY, $TRACE) - severity: WARNING - - id: go.lang.security.audit.net.formatted-template-string.formatted-template-string + - django + mode: taint + pattern-sinks: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + pickle.$PICKLEFUNC(...) + - pattern: | + _pickle.$PICKLEFUNC(...) + - pattern: | + cPickle.$PICKLEFUNC(...) + - pattern: | + shelve.$PICKLEFUNC(...) + - metavariable-regex: + metavariable: $PICKLEFUNC + regex: dumps|dump|load|loads + - patterns: + - pattern: dill.$DILLFUNC(...) + - metavariable-regex: + metavariable: $DILLFUNC + regex: dump|dump_session|dumps|load|load_session|loads + - patterns: + - pattern: yaml.$YAMLFUNC(...) + - pattern-not: yaml.$YAMLFUNC(..., Dumper=SafeDumper, ...) + - pattern-not: yaml.$YAMLFUNC(..., Dumper=yaml.SafeDumper, ...) + - pattern-not: yaml.$YAMLFUNC(..., Loader=SafeLoader, ...) + - pattern-not: yaml.$YAMLFUNC(..., Loader=yaml.SafeLoader, ...) + - metavariable-regex: + metavariable: $YAMLFUNC + regex: dump|dump_all|load|load_all + pattern-sources: + - pattern-either: + - patterns: + - pattern-inside: | + def $INSIDE(..., $PARAM, ...): + ... + - pattern-either: + - pattern: request.$REQFUNC(...) + - pattern: request.$REQFUNC.get(...) + - pattern: request.$REQFUNC[...] + severity: ERROR + - id: python.django.security.django-no-csrf-token.django-no-csrf-token languages: - - go - message: Found a formatted template string passed to 'template.HTML()'. 'template.HTML()' does not escape contents. Be absolutely sure there is no user-controlled data in this template. If user data can reach this template, you may have a XSS vulnerability. + - generic + message: Manually-created forms in django templates should specify a csrf_token to prevent CSRF attacks metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true + cwe: 'CWE-352: Cross-Site Request Forgery (CSRF)' impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + likelihood: MEDIUM references: - - https://golang.org/pkg/html/template/#HTML + - https://docs.djangoproject.com/en/4.2/howto/csrf/ subcategory: - - audit + - guardrail technology: - - go + - django + paths: + include: + - '*.html' patterns: - - pattern-not: template.HTML("..." + "...") + - pattern: ... - pattern-either: - - pattern: template.HTML($T + $X, ...) - - pattern: template.HTML(fmt.$P("...", ...), ...) - - pattern: | - $T = "..." - ... - $T = $FXN(..., $T, ...) - ... - template.HTML($T, ...) - pattern: | - $T = fmt.$P("...", ...) - ... - template.HTML($T, ...) +
    ...
    - pattern: | - $T, $ERR = fmt.$P("...", ...) - ... - template.HTML($T, ...) +
    ...
    - pattern: | - $T = $X + $Y - ... - template.HTML($T, ...) - - pattern: |- - $T = "..." - ... - $OTHER, $ERR = fmt.$P(..., $T, ...) - ... - template.HTML($OTHER, ...) +
    ...
    + - metavariable-regex: + metavariable: $METHOD + regex: (?i)(post|put|delete|patch) + - pattern-not-inside: ...{% csrf_token %}... + - pattern-not-inside: ...{{ $VAR.csrf_token }}... severity: WARNING - - id: go.lang.security.audit.net.fs-directory-listing.fs-directory-listing + - id: python.django.security.django-using-request-post-after-is-valid.django-using-request-post-after-is-valid languages: - - go - message: 'Detected usage of ''http.FileServer'' as handler: this allows directory listing and an attacker could navigate through directories looking for sensitive files. Be sure to disable directory listing or restrict access to specific directories/files.' + - python + message: Use $FORM.cleaned_data[] instead of request.POST[] after form.is_valid() has been executed to only access sanitized data metadata: category: security confidence: MEDIUM - cwe: - - 'CWE-548: Exposure of Information Through Directory Listing' + cwe: 'CWE-20: Improper Input Validation' impact: MEDIUM likelihood: MEDIUM - owasp: - - A06:2017 - Security Misconfiguration - - A01:2021 - Broken Access Control references: - - https://github.com/OWASP/Go-SCP - - https://cwe.mitre.org/data/definitions/548.html + - https://docs.djangoproject.com/en/4.2/ref/forms/api/#accessing-clean-data subcategory: - - vuln + - guardrail technology: - - go + - django patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-inside: | + if $FORM.is_valid(): + ... - pattern-either: - - patterns: - - pattern-inside: | - $FS := http.FileServer(...) - ... - - pattern-either: - - pattern: | - http.ListenAndServe(..., $FS) - - pattern: | - http.ListenAndServeTLS(..., $FS) - - pattern: | - http.Handle(..., $FS) - - pattern: | - http.HandleFunc(..., $FS) - - patterns: - - pattern: | - http.$FN(..., http.FileServer(...)) - - metavariable-regex: - metavariable: $FN - regex: (ListenAndServe|ListenAndServeTLS|Handle|HandleFunc) + - pattern: request.POST[...] + - pattern: request.POST.get(...) severity: WARNING - - id: go.lang.security.audit.net.pprof.pprof-debug-exposure + - id: python.django.security.hashids-with-django-secret.hashids-with-django-secret languages: - - go - message: The profiling 'pprof' endpoint is automatically exposed on /debug/pprof. This could leak information about the server. Instead, use `import "net/http/pprof"`. See https://www.farsightsecurity.com/blog/txt-record/go-remote-profiling-20161028/ for more information and mitigation. + - python + message: The Django 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 Django secret key can be obtained by attackers, through the HashIDs. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-489: Active Debug Code' - impact: LOW + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: HIGH likelihood: LOW - owasp: A06:2017 - Security Misconfiguration + owasp: + - A02:2021 – Cryptographic Failures references: - - https://www.farsightsecurity.com/blog/txt-record/go-remote-profiling-20161028/ - source-rule-url: https://github.com/securego/gosec#available-rules + - https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-SECRET_KEY + - http://carnage.github.io/2015/08/cryptanalysis-of-hashids subcategory: - - audit + - vuln technology: - - go - patterns: - - pattern-inside: | - import _ "net/http/pprof" - ... - - pattern-inside: | - func $ANY(...) { - ... - } - - pattern-not-inside: | - $MUX = http.NewServeMux(...) - ... - http.ListenAndServe($ADDR, $MUX) - - pattern-not: http.ListenAndServe("=~/^localhost.*/", ...) - - pattern-not: http.ListenAndServe("=~/^127[.]0[.]0[.]1.*/", ...) - - pattern: http.ListenAndServe(...) - severity: WARNING - - id: go.lang.security.audit.net.unescaped-data-in-htmlattr.unescaped-data-in-htmlattr + - django + pattern-either: + - pattern: hashids.Hashids(..., salt=django.conf.settings.SECRET_KEY, ...) + - pattern: hashids.Hashids(django.conf.settings.SECRET_KEY, ...) + severity: ERROR + - id: python.django.security.injection.code.user-eval-format-string.user-eval-format-string languages: - - go - message: Found a formatted template string passed to 'template. HTMLAttr()'. 'template.HTMLAttr()' does not escape contents. Be absolutely sure there is no user-controlled data in this template or validate and sanitize the data before passing it into the template. + - python + message: Found user data in a call to 'eval'. This is extremely dangerous because it can enable an attacker to execute remote code. See https://owasp.org/www-community/attacks/Code_Injection for more information. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2017 - Cross-Site Scripting (XSS) - A03:2021 - Injection references: - - https://golang.org/pkg/html/template/#HTMLAttr + - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html subcategory: - - audit + - vuln technology: - - go - pattern-either: - - pattern: template.HTMLAttr($T + $X, ...) - - pattern: template.HTMLAttr(fmt.$P("...", ...), ...) - - pattern: | - $T = "..." - ... - $T = $FXN(..., $T, ...) - ... - template.HTMLAttr($T, ...) - - pattern: | - $T = fmt.$P("...", ...) - ... - template.HTMLAttr($T, ...) - - pattern: | - $T, $ERR = fmt.$P("...", ...) - ... - template.HTMLAttr($T, ...) - - pattern: | - $T = $X + $Y - ... - template.HTMLAttr($T, ...) - - pattern: |- - $T = "..." - ... - $OTHER, $ERR = fmt.$P(..., $T, ...) - ... - template.HTMLAttr($OTHER, ...) - severity: WARNING - - id: go.lang.security.audit.net.unescaped-data-in-js.unescaped-data-in-js - languages: - - go - message: Found a formatted template string passed to 'template.JS()'. 'template.JS()' does not escape contents. Be absolutely sure there is no user-controlled data in this template. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://golang.org/pkg/html/template/#JS - subcategory: - - audit - technology: - - go - pattern-either: - - pattern: template.JS($T + $X, ...) - - pattern: template.JS(fmt.$P("...", ...), ...) - - pattern: | - $T = "..." - ... - $T = $FXN(..., $T, ...) - ... - template.JS($T, ...) - - pattern: | - $T = fmt.$P("...", ...) - ... - template.JS($T, ...) - - pattern: | - $T, $ERR = fmt.$P("...", ...) - ... - template.JS($T, ...) - - pattern: | - $T = $X + $Y - ... - template.JS($T, ...) - - pattern: | - $T = "..." - ... - $OTHER, $ERR = fmt.$P(..., $T, ...) - ... - template.JS($OTHER, ...) + - django + patterns: + - pattern-inside: | + def $F(...): + ... + - pattern-either: + - pattern: eval(..., $STR % request.$W.get(...), ...) + - pattern: | + $V = request.$W.get(...) + ... + eval(..., $STR % $V, ...) + - pattern: | + $V = request.$W.get(...) + ... + $S = $STR % $V + ... + eval(..., $S, ...) + - pattern: eval(..., "..." % request.$W(...), ...) + - pattern: | + $V = request.$W(...) + ... + eval(..., $STR % $V, ...) + - pattern: | + $V = request.$W(...) + ... + $S = $STR % $V + ... + eval(..., $S, ...) + - pattern: eval(..., $STR % request.$W[...], ...) + - pattern: | + $V = request.$W[...] + ... + eval(..., $STR % $V, ...) + - pattern: | + $V = request.$W[...] + ... + $S = $STR % $V + ... + eval(..., $S, ...) + - pattern: eval(..., $STR.format(..., request.$W.get(...), ...), ...) + - pattern: | + $V = request.$W.get(...) + ... + eval(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W.get(...) + ... + $S = $STR.format(..., $V, ...) + ... + eval(..., $S, ...) + - pattern: eval(..., $STR.format(..., request.$W(...), ...), ...) + - pattern: | + $V = request.$W(...) + ... + eval(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W(...) + ... + $S = $STR.format(..., $V, ...) + ... + eval(..., $S, ...) + - pattern: eval(..., $STR.format(..., request.$W[...], ...), ...) + - pattern: | + $V = request.$W[...] + ... + eval(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W[...] + ... + $S = $STR.format(..., $V, ...) + ... + eval(..., $S, ...) + - pattern: | + $V = request.$W.get(...) + ... + eval(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W.get(...) + ... + $S = f"...{$V}..." + ... + eval(..., $S, ...) + - pattern: | + $V = request.$W(...) + ... + eval(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W(...) + ... + $S = f"...{$V}..." + ... + eval(..., $S, ...) + - pattern: | + $V = request.$W[...] + ... + eval(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W[...] + ... + $S = f"...{$V}..." + ... + eval(..., $S, ...) severity: WARNING - - fix: http.ListenAndServeTLS($ADDR, certFile, keyFile, $HANDLER) - id: go.lang.security.audit.net.use-tls.use-tls + - id: python.django.security.injection.code.user-eval.user-eval languages: - - go - message: Found an HTTP server without TLS. Use 'http.ListenAndServeTLS' instead. See https://golang.org/pkg/net/http/#ListenAndServeTLS for more information. + - python + message: Found user data in a call to 'eval'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: LOW + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures + - A03:2021 - Injection references: - - https://golang.org/pkg/net/http/#ListenAndServeTLS + - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html + - https://owasp.org/www-community/attacks/Code_Injection subcategory: - - audit + - vuln technology: - - go - pattern: http.ListenAndServe($ADDR, $HANDLER) + - django + patterns: + - pattern-inside: | + def $F(...): + ... + - pattern-either: + - pattern: eval(..., request.$W.get(...), ...) + - pattern: | + $V = request.$W.get(...) + ... + eval(..., $V, ...) + - pattern: eval(..., request.$W(...), ...) + - pattern: | + $V = request.$W(...) + ... + eval(..., $V, ...) + - pattern: eval(..., request.$W[...], ...) + - pattern: | + $V = request.$W[...] + ... + eval(..., $V, ...) severity: WARNING - - id: go.lang.security.audit.net.wip-xss-using-responsewriter-and-printf.wip-xss-using-responsewriter-and-printf + - id: python.django.security.injection.code.user-exec-format-string.user-exec-format-string languages: - - go - message: Found data going from url query parameters into formatted data written to ResponseWriter. This could be XSS and should not be done. If you must do this, ensure your data is sanitized or escaped. + - python + message: Found user data in a call to 'exec'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. metadata: category: security confidence: MEDIUM cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM owasp: - - A07:2017 - Cross-Site Scripting (XSS) - A03:2021 - Injection references: - - https://owasp.org/Top10/A03_2021-Injection + - https://owasp.org/www-community/attacks/Code_Injection subcategory: - vuln technology: - - go + - django patterns: - pattern-inside: | - func $FUNC(..., $W http.ResponseWriter, ...) { - ... - var $TEMPLATE = "..." - ... - $W.Write([]byte(fmt.$PRINTF($TEMPLATE, ...)), ...) + def $F(...): ... - } - pattern-either: + - pattern: exec(..., $STR % request.$W.get(...), ...) - pattern: | - $PARAMS = r.URL.Query() + $V = request.$W.get(...) ... - $DATA, $ERR := $PARAMS[...] + exec(..., $STR % $V, ...) + - pattern: | + $V = request.$W.get(...) ... - $INTERM = $ANYTHING(..., $DATA, ...) + $S = $STR % $V ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + exec(..., $S, ...) + - pattern: exec(..., "..." % request.$W(...), ...) - pattern: | - $PARAMS = r.URL.Query() + $V = request.$W(...) ... - $DATA, $ERR := $PARAMS[...] + exec(..., $STR % $V, ...) + - pattern: | + $V = request.$W(...) ... - $INTERM = $DATA[...] + $S = $STR % $V ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + exec(..., $S, ...) + - pattern: exec(..., $STR % request.$W[...], ...) - pattern: | - $DATA, $ERR := r.URL.Query()[...] + $V = request.$W[...] ... - $INTERM = $DATA[...] + exec(..., $STR % $V, ...) + - pattern: | + $V = request.$W[...] ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + $S = $STR % $V + ... + exec(..., $S, ...) + - pattern: exec(..., $STR.format(..., request.$W.get(...), ...), ...) - pattern: | - $DATA, $ERR := r.URL.Query()[...] + $V = request.$W.get(...) ... - $INTERM = $ANYTHING(..., $DATA, ...) + exec(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W.get(...) ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + $S = $STR.format(..., $V, ...) + ... + exec(..., $S, ...) + - pattern: exec(..., $STR.format(..., request.$W(...), ...), ...) - pattern: | - $PARAMS = r.URL.Query() + $V = request.$W(...) ... - $DATA, $ERR := $PARAMS[...] + exec(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W(...) ... - $W.Write([]byte(fmt.$PRINTF(..., $DATA, ...))) + $S = $STR.format(..., $V, ...) + ... + exec(..., $S, ...) + - pattern: exec(..., $STR.format(..., request.$W[...], ...), ...) + - pattern: | + $V = request.$W[...] + ... + exec(..., $STR.format(..., $V, ...), ...) + - pattern: | + $V = request.$W[...] + ... + $S = $STR.format(..., $V, ...) + ... + exec(..., $S, ...) + - pattern: | + $V = request.$W.get(...) + ... + exec(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W.get(...) + ... + $S = f"...{$V}..." + ... + exec(..., $S, ...) + - pattern: | + $V = request.$W(...) + ... + exec(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W(...) + ... + $S = f"...{$V}..." + ... + exec(..., $S, ...) + - pattern: | + $V = request.$W[...] + ... + exec(..., f"...{$V}...", ...) + - pattern: | + $V = request.$W[...] + ... + $S = f"...{$V}..." + ... + exec(..., $S, ...) + - pattern: exec(..., base64.decodestring($S.format(..., request.$W.get(...), ...), ...), ...) + - pattern: exec(..., base64.decodestring($S % request.$W.get(...), ...), ...) + - pattern: exec(..., base64.decodestring(f"...{request.$W.get(...)}...", ...), ...) + - pattern: exec(..., base64.decodestring(request.$W.get(...), ...), ...) + - pattern: exec(..., base64.decodestring(bytes($S.format(..., request.$W.get(...), ...), ...), ...), ...) + - pattern: exec(..., base64.decodestring(bytes($S % request.$W.get(...), ...), ...), ...) + - pattern: exec(..., base64.decodestring(bytes(f"...{request.$W.get(...)}...", ...), ...), ...) + - pattern: exec(..., base64.decodestring(bytes(request.$W.get(...), ...), ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + exec(..., base64.decodestring($DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = base64.decodestring($DATA, ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = base64.decodestring(bytes($DATA, ...), ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + exec(..., base64.decodestring($DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = base64.decodestring($DATA, ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = base64.decodestring(bytes($DATA, ...), ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + exec(..., base64.decodestring($DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = base64.decodestring($DATA, ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = base64.decodestring(bytes($DATA, ...), ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + exec(..., base64.decodestring($DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = base64.decodestring($DATA, ...) + ... + exec(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = base64.decodestring(bytes($DATA, ...), ...) + ... + exec(..., $INTERM, ...) severity: WARNING - - id: go.lang.security.audit.reflect-makefunc.reflect-makefunc - languages: - - go - message: '''reflect.MakeFunc'' detected. This will sidestep protections that are normally afforded by Go''s type system. Audit this call and be sure that user input cannot be used to affect the code generated by MakeFunc; otherwise, you will have a serious security vulnerability.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-913: Improper Control of Dynamically-Managed Code Resources' - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - go - pattern: reflect.MakeFunc(...) - severity: ERROR - - id: go.lang.security.audit.sqli.gosql-sqli.gosql-sqli + - id: python.django.security.injection.code.user-exec.user-exec languages: - - go - message: Detected string concatenation with a non-literal variable in a "database/sql" Go SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use prepared statements with the 'Prepare' and 'PrepareContext' calls. + - python + message: Found user data in a call to 'exec'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' impact: HIGH - likelihood: LOW + likelihood: MEDIUM owasp: - - A01:2017 - Injection - A03:2021 - Injection references: - - https://golang.org/pkg/database/sql/ + - https://owasp.org/www-community/attacks/Code_Injection subcategory: - vuln technology: - - go + - django patterns: + - pattern-inside: | + def $F(...): + ... - pattern-either: - - patterns: - - pattern: $DB.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = fmt.Sprintf("...", $PARAM1, ...) - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern: $DB.$METHOD(..., $X + $Y, ...) - - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) - - pattern-either: - - pattern-inside: | - $DB, ... = sql.Open(...) + - pattern: exec(..., request.$W.get(...), ...) + - pattern: | + $V = request.$W.get(...) ... - - pattern-inside: | - func $FUNCNAME(..., $DB *sql.DB, ...) { - ... - } - - pattern-not: $DB.$METHOD(..., "..." + "...", ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Exec|ExecContent|Query|QueryContext|QueryRow|QueryRowContext)$ - severity: ERROR - - id: go.lang.security.audit.sqli.pg-orm-sqli.pg-orm-sqli + exec(..., $V, ...) + - pattern: exec(..., request.$W(...), ...) + - pattern: | + $V = request.$W(...) + ... + exec(..., $V, ...) + - pattern: exec(..., request.$W[...], ...) + - pattern: | + $V = request.$W[...] + ... + exec(..., $V, ...) + - pattern: | + loop = asyncio.get_running_loop() + ... + await loop.run_in_executor(None, exec, request.$W[...]) + - pattern: | + $V = request.$W[...] + ... + loop = asyncio.get_running_loop() + ... + await loop.run_in_executor(None, exec, $V) + - pattern: | + loop = asyncio.get_running_loop() + ... + await loop.run_in_executor(None, exec, request.$W.get(...)) + - pattern: | + $V = request.$W.get(...) + ... + loop = asyncio.get_running_loop() + ... + await loop.run_in_executor(None, exec, $V) + severity: WARNING + - id: python.django.security.injection.command.command-injection-os-system.command-injection-os-system languages: - - go - message: Detected string concatenation with a non-literal variable in a go-pg ORM SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, do not use strings concatenated with user-controlled input. Instead, use parameterized statements. + - python + message: Request data detected in os.system. This could be vulnerable to a command injection and should be avoided. If this must be done, use the 'subprocess' module instead and pass the arguments as a list. See https://owasp.org/www-community/attacks/Command_Injection for more information. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' cwe2021-top25: true cwe2022-top25: true impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW + likelihood: MEDIUM owasp: - A01:2017 - Injection - A03:2021 - Injection references: - - https://pg.uptrace.dev/queries/ + - https://owasp.org/www-community/attacks/Command_Injection subcategory: - vuln technology: - - go-pg + - django patterns: - pattern-inside: | - import ( + def $FUNC(...): ... - "$IMPORT" - ) - ... - - metavariable-regex: - metavariable: $IMPORT - regex: .*go-pg - pattern-either: - - patterns: - - pattern: $DB.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = fmt.Sprintf("...", $PARAM1, ...) - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern: | - $DB.$INTFUNC1(...).$METHOD(..., $X + $Y, ...).$INTFUNC2(...) + - pattern: os.system(..., request.$W.get(...), ...) + - pattern: os.system(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: os.system(..., $S % request.$W.get(...), ...) + - pattern: os.system(..., f"...{request.$W.get(...)}...", ...) - pattern: | - $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) - - pattern-inside: | - $DB = pg.Connect(...) + $DATA = request.$W.get(...) ... - - pattern-inside: | - func $FUNCNAME(..., $DB *pg.DB, ...) { - ... - } - - pattern-not-inside: | - $QUERY = fmt.Sprintf("...", ...,"...", ...) - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not: $DB.$METHOD(...,"...",...) - - pattern-not: | - $DB.$INTFUNC1(...).$METHOD(..., "...", ...).$INTFUNC2(...) - - pattern-not-inside: | - $QUERY = "..." + "..." - - pattern-not: | - "..." - - pattern-not: path.Join(...) - - pattern-not: filepath.Join(...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Where|WhereOr|Join|GroupExpr|OrderExpr|ColumnExpr)$ + os.system(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + os.system(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + os.system(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + os.system(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + os.system(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + os.system(..., $INTERM, ...) + - pattern: $A = os.system(..., request.$W.get(...), ...) + - pattern: $A = os.system(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $A = os.system(..., $S % request.$W.get(...), ...) + - pattern: $A = os.system(..., f"...{request.$W.get(...)}...", ...) + - pattern: return os.system(..., request.$W.get(...), ...) + - pattern: return os.system(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: return os.system(..., $S % request.$W.get(...), ...) + - pattern: return os.system(..., f"...{request.$W.get(...)}...", ...) + - pattern: os.system(..., request.$W(...), ...) + - pattern: os.system(..., $S.format(..., request.$W(...), ...), ...) + - pattern: os.system(..., $S % request.$W(...), ...) + - pattern: os.system(..., f"...{request.$W(...)}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + os.system(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + os.system(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + os.system(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + os.system(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + os.system(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + os.system(..., $INTERM, ...) + - pattern: $A = os.system(..., request.$W(...), ...) + - pattern: $A = os.system(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $A = os.system(..., $S % request.$W(...), ...) + - pattern: $A = os.system(..., f"...{request.$W(...)}...", ...) + - pattern: return os.system(..., request.$W(...), ...) + - pattern: return os.system(..., $S.format(..., request.$W(...), ...), ...) + - pattern: return os.system(..., $S % request.$W(...), ...) + - pattern: return os.system(..., f"...{request.$W(...)}...", ...) + - pattern: os.system(..., request.$W[...], ...) + - pattern: os.system(..., $S.format(..., request.$W[...], ...), ...) + - pattern: os.system(..., $S % request.$W[...], ...) + - pattern: os.system(..., f"...{request.$W[...]}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + os.system(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + os.system(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + os.system(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + os.system(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + os.system(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + os.system(..., $INTERM, ...) + - pattern: $A = os.system(..., request.$W[...], ...) + - pattern: $A = os.system(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $A = os.system(..., $S % request.$W[...], ...) + - pattern: $A = os.system(..., f"...{request.$W[...]}...", ...) + - pattern: return os.system(..., request.$W[...], ...) + - pattern: return os.system(..., $S.format(..., request.$W[...], ...), ...) + - pattern: return os.system(..., $S % request.$W[...], ...) + - pattern: return os.system(..., f"...{request.$W[...]}...", ...) + - pattern: os.system(..., request.$W, ...) + - pattern: os.system(..., $S.format(..., request.$W, ...), ...) + - pattern: os.system(..., $S % request.$W, ...) + - pattern: os.system(..., f"...{request.$W}...", ...) + - pattern: | + $DATA = request.$W + ... + os.system(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + os.system(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + os.system(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + os.system(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + os.system(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + os.system(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + os.system(..., $INTERM, ...) + - pattern: $A = os.system(..., request.$W, ...) + - pattern: $A = os.system(..., $S.format(..., request.$W, ...), ...) + - pattern: $A = os.system(..., $S % request.$W, ...) + - pattern: $A = os.system(..., f"...{request.$W}...", ...) + - pattern: return os.system(..., request.$W, ...) + - pattern: return os.system(..., $S.format(..., request.$W, ...), ...) + - pattern: return os.system(..., $S % request.$W, ...) + - pattern: return os.system(..., f"...{request.$W}...", ...) severity: ERROR - - id: go.lang.security.audit.sqli.pg-sqli.pg-sqli + - id: python.django.security.injection.command.subprocess-injection.subprocess-injection languages: - - go - message: 'Detected string concatenation with a non-literal variable in a go-pg SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries instead of string concatenation. You can use parameterized queries like so: ''(SELECT ? FROM table, data1)''' + - python + message: Detected user input entering a `subprocess` call unsafely. This could result in a command injection vulnerability. An attacker could use this vulnerability to execute arbitrary commands on the host, which allows them to download malware, scan sensitive data, or run any command they wish on the server. Do not let users choose the command to run. In general, prefer to use Python API versions of system commands. If you must use subprocess, use a dictionary to allowlist a set of commands. metadata: category: security - confidence: LOW + confidence: HIGH cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' cwe2021-top25: true cwe2022-top25: true impact: HIGH - likelihood: LOW + likelihood: MEDIUM owasp: - A01:2017 - Injection - A03:2021 - Injection references: - - https://pg.uptrace.dev/ - - https://pkg.go.dev/github.com/go-pg/pg/v10 + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ subcategory: - vuln technology: - - go-pg - patterns: - - pattern-either: - - patterns: - - pattern: | - $DB.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = fmt.Sprintf("...", $PARAM1, ...) + - flask + mode: taint + options: + symbolic_propagation: true + pattern-sanitizers: + - patterns: + - pattern: $DICT[$KEY] + - focus-metavariable: $KEY + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: subprocess.$FUNC(...) + - pattern-not: subprocess.$FUNC("...", ...) + - pattern-not: subprocess.$FUNC(["...", ...], ...) + - pattern-not-inside: | + $CMD = ["...", ...] ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern: $DB.$METHOD(..., $X + $Y, ...) - - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) - - pattern-either: - - pattern-inside: | - $DB = pg.Connect(...) - ... + subprocess.$FUNC($CMD, ...) + - patterns: + - pattern: subprocess.$FUNC(["$SHELL", "-c", ...], ...) + - metavariable-regex: + metavariable: $SHELL + regex: ^(sh|bash|ksh|csh|tcsh|zsh)$ + - patterns: + - pattern: subprocess.$FUNC(["$INTERPRETER", ...], ...) + - metavariable-regex: + metavariable: $INTERPRETER + regex: ^(python|python\d)$ + pattern-sources: + - patterns: - pattern-inside: | - func $FUNCNAME(..., $DB *pg.DB, ...) { + def $FUNC(..., $REQUEST, ...): ... - } - - pattern-not: $DB.$METHOD(..., "..." + "...", ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Exec|ExecContext|ExecOne|ExecOneContext|Query|QueryOne|QueryContext|QueryOneContext)$ + - focus-metavariable: $REQUEST + - metavariable-pattern: + metavariable: $REQUEST + patterns: + - pattern: request + - pattern-not-inside: request.build_absolute_uri severity: ERROR - - id: go.lang.security.audit.sqli.pgx-sqli.pgx-sqli + - id: python.django.security.injection.csv-writer-injection.csv-writer-injection languages: - - go - message: 'Detected string concatenation with a non-literal variable in a pgx Go SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries instead. You can use parameterized queries like so: (`SELECT $1 FROM table`, `data1)' + - python + message: Detected user input into a generated CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW + - 'CWE-1236: Improper Neutralization of Formula Elements in a CSV File' + impact: MEDIUM + likelihood: MEDIUM owasp: - A01:2017 - Injection - A03:2021 - Injection references: - - https://github.com/jackc/pgx - - https://pkg.go.dev/github.com/jackc/pgx/v4#hdr-Connection_Pool + - https://github.com/raphaelm/defusedcsv + - https://owasp.org/www-community/attacks/CSV_Injection + - https://web.archive.org/web/20220516052229/https://www.contextis.com/us/blog/comma-separated-vulnerabilities subcategory: - vuln technology: - - pgx - patterns: - - pattern-either: - - patterns: - - pattern: $DB.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = fmt.Sprintf("...", $PARAM1, ...) - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern: $DB.$METHOD(..., $X + $Y, ...) - - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) - - pattern-either: - - pattern-inside: | - $DB, ... = pgx.Connect(...) - ... - - pattern-inside: | - $DB, ... = pgx.NewConnPool(...) - ... + - django + - python + mode: taint + pattern-sinks: + - patterns: - pattern-inside: | - $DB, ... = pgx.ConnectConfig(...) + $WRITER = csv.writer(...) + ... + + $WRITER.$WRITE(...) + - pattern: $WRITER.$WRITE(...) + - metavariable-regex: + metavariable: $WRITE + regex: ^(writerow|writerows|writeheader)$ + pattern-sources: + - patterns: - pattern-inside: | - func $FUNCNAME(..., $DB *pgx.Conn, ...) { + def $FUNC(..., $REQUEST, ...): ... - } - - pattern-not: $DB.$METHOD(..., "..." + "...", ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Exec|ExecEx|Query|QueryEx|QueryRow|QueryRowEx)$ + - focus-metavariable: $REQUEST + - metavariable-pattern: + metavariable: $REQUEST + patterns: + - pattern: request + - pattern-not-inside: request.build_absolute_uri severity: ERROR - - id: go.lang.security.audit.unsafe-reflect-by-name.unsafe-reflect-by-name + - id: python.django.security.injection.email.xss-html-email-body.xss-html-email-body languages: - - go - message: If an attacker can supply values that the application then uses to determine which method or field to invoke, the potential exists for the attacker to create control flow paths through the application that were not intended by the application developers. This attack vector may allow the attacker to bypass authentication or access control checks or otherwise cause the application to behave in an unexpected manner. + - python + message: Found request data in an EmailMessage that is set to use HTML. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-470: Use of Externally-Controlled Input to Select Classes or Code (''Unsafe Reflection'')' - impact: LOW - likelihood: LOW + - 'CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component (''Injection'')' + impact: MEDIUM + likelihood: MEDIUM owasp: - A03:2021 - Injection references: - - https://owasp.org/Top10/A03_2021-Injection + - https://www.damonkohler.com/2008/12/email-injection.html subcategory: - - audit + - vuln technology: - - go + - django patterns: + - pattern-inside: | + def $FUNC(...): + ... + $EMAIL.content_subtype = "html" + ... - pattern-either: + - pattern: django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) - pattern: | - $SMTH.MethodByName($NAME,...) + $DATA = request.$W.get(...) + ... + django.core.mail.EmailMessage($SUBJ, $DATA, ...) - pattern: | - $SMTH.FieldByName($NAME,...) - - pattern-not: | - $SMTH.MethodByName("...",...) - - pattern-not: | - $SMTH.FieldByName("...",...) - - pattern-inside: | - import "reflect" - ... - severity: WARNING - - id: go.lang.security.audit.unsafe.use-of-unsafe-block - languages: - - go - message: Using the unsafe package in Go gives you low-level memory management and many of the strengths of the C language, but also steps around the type safety of Go and can lead to buffer overflows and possible arbitrary code execution by an attacker. Only use this package if you absolutely know what you're doing. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-242: Use of Inherently Dangerous Function' - impact: LOW - likelihood: LOW - references: - - https://cwe.mitre.org/data/definitions/242.html - source_rule_url: https://github.com/securego/gosec/blob/master/rules/unsafe.go - subcategory: - - audit - technology: - - go - pattern: unsafe.$FUNC(...) - severity: WARNING - - fix: | - html/template - id: go.lang.security.audit.xss.import-text-template.import-text-template - languages: - - go - message: When working with web applications that involve rendering user-generated content, it's important to properly escape any HTML content to prevent Cross-Site Scripting (XSS) attacks. In Go, the `text/template` package does not automatically escape HTML content, which can leave your application vulnerable to these types of attacks. To mitigate this risk, it's recommended to use the `html/template` package instead, which provides built-in functionality for HTML escaping. By using `html/template` to render your HTML content, you can help to ensure that your web application is more secure and less susceptible to XSS vulnerabilities. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://www.veracode.com/blog/secure-development/use-golang-these-mistakes-could-compromise-your-apps-security - subcategory: - - audit - technology: - - go - patterns: - - pattern: | - import "$IMPORT" - - metavariable-regex: - metavariable: $IMPORT - regex: ^(text/template)$ - - focus-metavariable: $IMPORT - severity: WARNING - - id: go.lang.security.audit.xss.no-direct-write-to-responsewriter.no-direct-write-to-responsewriter - languages: - - go - message: Detected directly writing or similar in 'http.ResponseWriter.write()'. This bypasses HTML escaping that prevents cross-site scripting vulnerabilities. Instead, use the 'html/template' package and render data using 'template.Execute()'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - subcategory: - - audit - technology: - - go - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-inside: | - func $HANDLER(..., $WRITER *http.ResponseWriter, ...) { - ... - } - - pattern-inside: | - func(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-either: - - pattern: $WRITER.Write(...) - - pattern: (*$WRITER).Write(...) - - pattern-not: $WRITER.Write([]byte("...")) - severity: WARNING - - id: go.lang.security.audit.xss.no-fprintf-to-responsewriter.no-fprintf-to-responsewriter - languages: - - go - message: Detected 'Fprintf' or similar writing to 'http.ResponseWriter'. This bypasses HTML escaping that prevents cross-site scripting vulnerabilities. Instead, use the 'html/template' package to render data to users. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - subcategory: - - audit - technology: - - go - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-inside: | - func(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-not: fmt.$PRINTF($WRITER, "...") - - pattern: fmt.$PRINTF($WRITER, ...) - severity: WARNING - - id: go.lang.security.audit.xss.no-interpolation-in-tag.no-interpolation-in-tag - languages: - - generic - message: Detected template variable interpolation in an HTML tag. This is potentially vulnerable to cross-site scripting (XSS) attacks because a malicious actor has control over HTML but without the need to use escaped characters. Use explicit tags instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://github.com/golang/go/issues/19669 - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - subcategory: - - audit - technology: - - generic - paths: - include: - - '*.html' - - '*.thtml' - - '*.gohtml' - - '*.tmpl' - - '*.tpl' - pattern: <{{ ... }} ... > - severity: WARNING - - id: go.lang.security.audit.xss.no-interpolation-js-template-string.no-interpolation-js-template-string - languages: - - generic - message: Detected template variable interpolation in a JavaScript template string. This is potentially vulnerable to cross-site scripting (XSS) attacks because a malicious actor has control over JavaScript but without the need to use escaped characters. Instead, obtain this variable outside of the template string and ensure your template is properly escaped. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://github.com/golang/go/issues/9200#issuecomment-66100328 - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - subcategory: - - audit - technology: - - generic - paths: - include: - - '*.html' - - '*.thtml' - - '*.gohtml' - - '*.tmpl' - - '*.tpl' - patterns: - - pattern-inside: - - pattern: '` ... {{ ... }} ...`' + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) + - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) + - pattern: django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.EmailMessage($SUBJ, $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) + - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) + - pattern: django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.EmailMessage($SUBJ, $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) + - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) + - pattern: django.core.mail.EmailMessage($SUBJ, request.$W, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.EmailMessage($SUBJ, $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.EmailMessage($SUBJ, $INTERM, ...) + - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W, ...) + - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W, ...) severity: WARNING - - id: go.lang.security.audit.xss.no-io-writestring-to-responsewriter.no-io-writestring-to-responsewriter + - id: python.django.security.injection.email.xss-send-mail-html-message.xss-send-mail-html-message languages: - - go - message: Detected 'io.WriteString()' writing directly to 'http.ResponseWriter'. This bypasses HTML escaping that prevents cross-site scripting vulnerabilities. Instead, use the 'html/template' package to render data to users. + - python + message: Found request data in 'send_mail(...)' that uses 'html_message'. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component (''Injection'')' impact: MEDIUM - likelihood: LOW + likelihood: MEDIUM owasp: - - A07:2017 - Cross-Site Scripting (XSS) - A03:2021 - Injection references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - - https://golang.org/pkg/io/#WriteString + - https://www.damonkohler.com/2008/12/email-injection.html subcategory: - - audit + - vuln technology: - - go + - django patterns: + - pattern-inside: | + def $FUNC(...): + ... - pattern-either: - - pattern-inside: | - func $HANDLER(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-inside: | - func(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-not: io.WriteString($WRITER, "...") - - pattern: io.WriteString($WRITER, $STRING) + - pattern: django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.send_mail(..., html_message=$DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) + - pattern: return django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) + - pattern: django.core.mail.send_mail(..., html_message=request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.send_mail(..., html_message=$DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W(...), ...) + - pattern: return django.core.mail.send_mail(..., html_message=request.$W(...), ...) + - pattern: django.core.mail.send_mail(..., html_message=request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.send_mail(..., html_message=$DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W[...], ...) + - pattern: return django.core.mail.send_mail(..., html_message=request.$W[...], ...) + - pattern: django.core.mail.send_mail(..., html_message=request.$W, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.send_mail(..., html_message=$DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + django.core.mail.send_mail(..., html_message=$INTERM, ...) + - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W, ...) + - pattern: return django.core.mail.send_mail(..., html_message=request.$W, ...) severity: WARNING - - id: go.lang.security.audit.xss.no-printf-in-responsewriter.no-printf-in-responsewriter + - id: python.django.security.injection.open-redirect.open-redirect languages: - - go - message: Detected 'printf' or similar in 'http.ResponseWriter.write()'. This bypasses HTML escaping that prevents cross-site scripting vulnerabilities. Instead, use the 'html/template' package to render data to users. + - python + message: Data from request ($DATA) is passed to redirect(). This is an open redirect and could be exploited. Ensure you are redirecting to safe URLs by using django.utils.http.is_safe_url(). See https://cwe.mitre.org/data/definitions/601.html for more information. metadata: category: security - confidence: LOW + confidence: MEDIUM cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' impact: MEDIUM likelihood: LOW owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection + - A01:2021 - Broken Access Control references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + - https://www.djm.org.uk/posts/djangos-little-protections-word-redirect-dangers/ + - https://github.com/django/django/blob/d1b7bd030b1db111e1a3505b1fc029ab964382cc/django/utils/http.py#L231 subcategory: - - audit + - vuln technology: - - go + - django patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-not-inside: | + def $FUNC(...): + ... + django.utils.http.is_safe_url(...) + ... + - pattern-not-inside: | + def $FUNC(...): + ... + if <... django.utils.http.is_safe_url(...) ...>: + ... + - pattern-not-inside: | + def $FUNC(...): + ... + django.utils.http.url_has_allowed_host_and_scheme(...) + ... + - pattern-not-inside: | + def $FUNC(...): + ... + if <... django.utils.http.url_has_allowed_host_and_scheme(...) ...>: + ... - pattern-either: - - pattern-inside: | - func $HANDLER(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-inside: | - func(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern: | - $WRITER.Write(<... fmt.$PRINTF(...) ...>, ...) - severity: WARNING - - id: go.lang.security.audit.xss.template-html-does-not-escape.unsafe-template-type - languages: - - go - message: Semgrep could not determine that the argument to 'template.HTML()' is a constant. 'template.HTML()' and similar does not escape contents. Be absolutely sure there is no user-controlled data in this template. If user data can reach this template, you may have a XSS vulnerability. Instead, do not use this function and use 'template.Execute()'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://golang.org/pkg/html/template/#HTML - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/vulnerability/xss/xss.go#L33 - subcategory: - - audit - technology: - - go - patterns: - - pattern-not: template.$ANY("..." + "...") - - pattern-not: template.$ANY("...") - - pattern-either: - - pattern: template.HTML(...) - - pattern: template.CSS(...) - - pattern: template.HTMLAttr(...) - - pattern: template.JS(...) - - pattern: template.JSStr(...) - - pattern: template.Srcset(...) - - pattern: template.URL(...) - severity: WARNING - - id: go.lang.security.audit.xxe.parsing-external-entities-enabled.parsing-external-entities-enabled - languages: - - go - message: Detected enabling of "XMLParseNoEnt", which allows parsing of external entities and can lead to XXE if user controlled data is parsed by the library. Instead, do not enable "XMLParseNoEnt" or be sure to adequately sanitize user-controlled data when it is being parsed by this library. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://knowledge-base.secureflag.com/vulnerabilities/xml_injection/xml_entity_expansion_go_lang.html - - https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing - subcategory: - - audit - technology: - - libxml2 - patterns: - - pattern-inside: | - import ("github.com/lestrrat-go/libxml2/parser") - ... - - pattern: $PARSER := parser.New(parser.XMLParseNoEnt) - severity: WARNING - - id: go.lang.security.bad_tmp.bad-tmp-file-creation - languages: - - go - message: File creation in shared tmp directory without using ioutil.Tempfile - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-377: Insecure Temporary File' - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://github.com/securego/gosec - subcategory: - - audit - technology: - - go - pattern-either: - - pattern: ioutil.WriteFile("=~//tmp/.*$/", ...) - - pattern: os.Create("=~//tmp/.*$/", ...) - severity: WARNING - - fix-regex: - regex: (.*)(Copy|CopyBuffer)\((.*?),(.*?)(\)|,.*\)) - replacement: \1CopyN(\3, \4, 1024*1024*256) - id: go.lang.security.decompression_bomb.potential-dos-via-decompression-bomb - languages: - - go - message: 'Detected a possible denial-of-service via a zip bomb attack. By limiting the max bytes read, you can mitigate this attack. `io.CopyN()` can specify a size. ' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-400: Uncontrolled Resource Consumption' - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - references: - - https://golang.org/pkg/io/#CopyN - - https://github.com/securego/gosec/blob/master/rules/decompression-bomb.go - source-rule-url: https://github.com/securego/gosec - subcategory: - - audit - technology: - - go - patterns: - - pattern-either: - - pattern: io.Copy(...) - - pattern: io.CopyBuffer(...) - - pattern-either: - - pattern-inside: | - gzip.NewReader(...) + - pattern: django.shortcuts.redirect(..., request.$W.get(...), ...) + - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: django.shortcuts.redirect(..., $S % request.$W.get(...), ...) + - pattern: django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: | + $DATA = request.$W.get(...) ... - - pattern-inside: | - zlib.NewReader(...) + django.shortcuts.redirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) ... - - pattern-inside: | - zlib.NewReaderDict(...) + $INTERM = $DATA ... - - pattern-inside: | - bzip2.NewReader(...) + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) ... - - pattern-inside: | - flate.NewReader(...) + django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) ... - - pattern-inside: | - flate.NewReaderDict(...) + $INTERM = $STR.format(..., $DATA, ...) ... - - pattern-inside: | - lzw.NewReader(...) + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) ... - - pattern-inside: | - tar.NewReader(...) + django.shortcuts.redirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) ... - - pattern-inside: | - zip.NewReader(...) + $INTERM = $STR % $DATA ... - - pattern-inside: | - zip.OpenReader(...) + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) ... - severity: WARNING - - fix: filepath.FromSlash(filepath.Clean("/"+strings.Trim($...INNER, "/"))) - id: go.lang.security.filepath-clean-misuse.filepath-clean-misuse - languages: - - go - message: '`Clean` is not intended to sanitize against path traversal attacks. This function is for finding the shortest path name equivalent to the given input. Using `Clean` to sanitize file reads may expose this application to path traversal attacks, where an attacker could access arbitrary files on the server. To fix this easily, write this: `filepath.FromSlash(path.Clean("/"+strings.Trim(req.URL.Path, "/")))` However, a better solution is using the `SecureJoin` function in the package `filepath-securejoin`. See https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://pkg.go.dev/path#Clean - - http://technosophos.com/2016/03/31/go-quickly-cleaning-filepaths.html - - https://labs.detectify.com/2021/12/15/zero-day-path-traversal-grafana/ - - https://dzx.cz/2021/04/02/go_path_traversal/ - - https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme - subcategory: - - vuln - technology: - - go - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern-either: + django.shortcuts.redirect(..., f"...{$DATA}...", ...) - pattern: | - "/" + ... - pattern-sinks: - - patterns: - - pattern-either: - - pattern: filepath.Clean($...INNER) - - pattern: path.Clean($...INNER) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - severity: ERROR - - id: go.lang.security.injection.open-redirect.open-redirect - languages: - - go - message: An HTTP redirect was found to be crafted from user-input `$REQUEST`. This can lead to open redirect vulnerabilities, potentially allowing attackers to redirect users to malicious web sites. It is recommend where possible to not allow user-input to craft the redirect URL. When user-input is necessary to craft the request, it is recommended to follow OWASP best practices to restrict the URL to domains in an allowlist. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - description: An HTTP redirect was found to be crafted from user-input leading to an open redirect vulnerability - impact: MEDIUM - interfile: true - likelihood: MEDIUM - references: - - https://knowledge-base.secureflag.com/vulnerabilities/unvalidated_redirects___forwards/open_redirect_go_lang.html - subcategory: - - vuln - technology: - - go - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern: http.Redirect($W, $REQ, $URL, ...) - - focus-metavariable: $URL - requires: INPUT and not CLEAN - pattern-sources: - - label: INPUT - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - - label: CLEAN - patterns: - - pattern-either: - - pattern: | - "$URLSTR" + $INPUT - - patterns: - - pattern-either: - - pattern: fmt.Fprintf($F, "$URLSTR", $INPUT, ...) - - pattern: fmt.Sprintf("$URLSTR", $INPUT, ...) - - pattern: fmt.Printf("$URLSTR", $INPUT, ...) - - metavariable-regex: - metavariable: $URLSTR - regex: .*//[a-zA-Z0-10]+\..* - requires: INPUT - severity: WARNING - - id: go.lang.security.injection.raw-html-format.raw-html-format - languages: - - go - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. Use the `html/template` package which will safely render HTML instead, or inspect that the HTML is rendered safely. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - subcategory: - - vuln - technology: - - go - mode: taint - pattern-sanitizers: - - pattern: html.EscapeString(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: fmt.Printf("$HTMLSTR", ...) - - pattern: fmt.Sprintf("$HTMLSTR", ...) - - pattern: fmt.Fprintf($W, "$HTMLSTR", ...) - - pattern: '"$HTMLSTR" + ...' - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - severity: WARNING - - id: go.lang.security.injection.tainted-sql-string.tainted-sql-string - languages: - - go - message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`db.Query("SELECT * FROM t WHERE id = ?", id)`) or a safe library. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://golang.org/doc/database/sql-injection - - https://www.stackhawk.com/blog/golang-sql-injection-guide-examples-and-prevention/ - subcategory: - - vuln - technology: - - go - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern-either: - - pattern: strconv.Atoi(...) + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - ($X: bool) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - patterns: - - pattern-inside: | - $VAR = "$SQLSTR"; - ... - - pattern: $VAR += ... - - patterns: - - pattern-inside: | - var $SB strings.Builder - ... - - pattern-inside: | - $SB.WriteString("$SQLSTR") - ... - $SB.String(...) - - pattern: | - $SB.WriteString(...) - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop).* - - patterns: - - pattern-either: - - pattern: fmt.Fprintf($F, "$SQLSTR", ...) - - pattern: fmt.Sprintf("$SQLSTR", ...) - - pattern: fmt.Printf("$SQLSTR", ...) - - metavariable-regex: - metavariable: $SQLSTR - regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).* - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - severity: ERROR - - id: go.lang.security.injection.tainted-url-host.tainted-url-host - languages: - - go - message: A request was found to be crafted from user-input `$REQUEST`. This can lead to Server-Side Request Forgery (SSRF) vulnerabilities, potentially exposing sensitive data. It is recommend where possible to not allow user-input to craft the base request, but to be treated as part of the path or query parameter. When user-input is necessary to craft the request, it is recommended to follow OWASP best practices to prevent abuse, including using an allowlist. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://goteleport.com/blog/ssrf-attacks/ - subcategory: - - vuln - technology: - - go - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $CLIENT := &http.Client{...} - ... - - pattern: $CLIENT.$METHOD($URL, ...) - - pattern: http.$METHOD($URL, ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Get|Head|Post|PostForm)$ - - patterns: - - pattern: | - http.NewRequest("$METHOD", $URL, ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(GET|HEAD|POST|POSTFORM)$ - - focus-metavariable: $URL - requires: INPUT and not CLEAN - pattern-sources: - - label: INPUT - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$ANYTHING - - pattern: | - ($REQUEST : http.Request).$ANYTHING - - metavariable-regex: - metavariable: $ANYTHING - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - - label: CLEAN - patterns: - - pattern-either: - - pattern: | - "$URLSTR" + $INPUT - - patterns: - - pattern-either: - - pattern: fmt.Fprintf($F, "$URLSTR", $INPUT, ...) - - pattern: fmt.Sprintf("$URLSTR", $INPUT, ...) - - pattern: fmt.Printf("$URLSTR", $INPUT, ...) - - metavariable-regex: - metavariable: $URLSTR - regex: .*//[a-zA-Z0-10]+\..* - requires: INPUT - severity: WARNING - - id: go.lang.security.zip.path-traversal-inside-zip-extraction - languages: - - go - message: File traversal when extracting zip archive - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source_rule_url: https://github.com/securego/gosec/issues/205 - subcategory: - - audit - technology: - - go - pattern: | - reader, $ERR := zip.OpenReader($ARCHIVE) - ... - for _, $FILE := range reader.File { - ... - path := filepath.Join($TARGET, $FILE.Name) - ... - } - severity: WARNING - - id: go.otto.security.audit.dangerous-execution.dangerous-execution - languages: - - go - message: Detected non-static script inside otto VM. Audit the input to 'VM.Run'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - otto - - vm - patterns: - - pattern-inside: | - $VM = otto.New(...) - ... - - pattern-not: $VM.Run("...", ...) - - pattern: $VM.Run(...) - severity: ERROR - - id: go.template.security.insecure-types.go-insecure-templates - languages: - - go - message: usage of insecure template types. They are documented as a security risk. See https://golang.org/pkg/html/template/#HTML. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://golang.org/pkg/html/template/#HTML - - https://twitter.com/empijei/status/1275177219011350528 - subcategory: - - audit - technology: - - template - patterns: - - pattern-inside: | - import "html/template" - ... - - pattern-either: - - pattern: var $VAR template.HTML = $EXP - - pattern: var $VAR template.CSS = $EXP - - pattern: var $VAR template.HTMLAttr = $EXP - - pattern: var $VAR template.JS = $EXP - - pattern: var $VAR template.JSStr = $EXP - - pattern: var $VAR template.Srcset = $EXP - severity: WARNING - - id: go.template.security.ssti.go-ssti - languages: - - go - message: A server-side template injection occurs when an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side. When using "html/template" always check that user inputs are validated and sanitized before included within the template. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine' - impact: HIGH - likelihood: LOW - references: - - https://www.onsecurity.io/blog/go-ssti-method-research/ - - http://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html - subcategory: - - vuln - technology: - - go - patterns: - - pattern-inside: | - import ("html/template") - ... - - pattern: $TEMPLATE = fmt.Sprintf("...", $ARG, ...) - - patterns: - - pattern-either: - - pattern-inside: | - func $FN(..., $REQ *http.Request, ...){ - ... - } - - pattern-inside: | - func $FN(..., $REQ http.Request, ...){ - ... - } - - pattern-inside: | - func(..., $REQ *http.Request, ...){ - ... - } - - patterns: - - pattern-either: - - pattern-inside: | - $ARG := $REQ.URL.Query().Get(...) - ... - $T, $ERR := $TMPL.Parse($TEMPLATE) - - pattern-inside: | - $ARG := $REQ.Form.Get(...) - ... - $T, $ERR := $TMPL.Parse($TEMPLATE) - - pattern-inside: | - $ARG := $REQ.PostForm.Get(...) - ... - $T, $ERR := $TMPL.Parse($TEMPLATE) - severity: ERROR - - id: java.android.best-practice.manifest-security-features.manifest-usescleartexttraffic-true - languages: - - generic - message: The Android manifest is configured to allow non-encrypted connections. Evaluate if this is necessary for your app, and disable it if appropriate. This flag is ignored on Android 7 (API 24) and above if a Network Security Config is present. - metadata: - category: best-practice - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://developer.android.com/guide/topics/manifest/application-element#usesCleartextTraffic - - https://developer.android.com/training/articles/security-config - technology: - - android - paths: - include: - - '*.xml' - patterns: - - pattern: | - android:usesCleartextTraffic="true" - - pattern-not-inside: | - - severity: INFO - - id: java.android.best-practice.manifest-security-features.manifest-usescleartexttraffic-ignored-by-nsc - languages: - - generic - message: Manifest uses both `android:usesCleartextTraffic` and Network Security Config. The `usesCleartextTraffic` directive is ignored on Android 7 (API 24) and above if a Network Security Config is present. - metadata: - category: best-practice - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://developer.android.com/guide/topics/manifest/application-element#usesCleartextTraffic - - https://developer.android.com/training/articles/security-config - technology: - - android - paths: - include: - - '*.xml' - patterns: - - pattern-either: + $DATA = request.$W.get(...) + ... + django.shortcuts.redirect(..., $STR + $DATA, ...) - pattern: | - android:usesCleartextTraffic ... android:networkSecurityConfig + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: $A = django.shortcuts.redirect(..., request.$W.get(...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S % request.$W.get(...), ...) + - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: return django.shortcuts.redirect(..., request.$W.get(...), ...) + - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: return django.shortcuts.redirect(..., $S % request.$W.get(...), ...) + - pattern: return django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: django.shortcuts.redirect(..., request.$W(...), ...) + - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: django.shortcuts.redirect(..., $S % request.$W(...), ...) + - pattern: django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) - pattern: | - android:networkSecurityConfig ... android:usesCleartextTraffic - - pattern-not-inside: | - - severity: INFO - - id: java.android.best-practice.network-security-config.nsc-allows-plaintext-traffic - languages: - - generic - message: The Network Security Config is set to allow non-encrypted connections. Evaluate if this is necessary for your app, and disable it if appropriate. (To hide this warning, set `xmlns:tools="http://schemas.android.com/tools" tools:ignore="InsecureBaseConfiguration"` as parameters to your ``) - metadata: - category: best-practice - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://developer.android.com/training/articles/security-config - - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/ - technology: - - android - paths: - include: - - '*.xml' - patterns: - - pattern: | - - - pattern-not-inside: | - - - pattern-not-inside: | - ... ... ... ... ... ... ... ... ... ... - severity: INFO - - id: java.android.best-practice.network-security-config.nsc-pinning-without-backup - languages: - - generic - message: Your app uses TLS public key pinning without specifying a backup key. If you are forced to change TLS keys or CAs on short notice, not having a backup pin can lead to connectivity issues until you can push out an update. It is considered best practice to add at least one additional pin as a backup. - metadata: - category: best-practice - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://developer.android.com/training/articles/security-config#CertificatePinning - - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/ - technology: - - android - paths: - include: - - '*.xml' - patterns: - - pattern: | - ... - - pattern-not-inside: | - ......... - - pattern-inside: | - ... ... - - pattern-inside: | - ... ... ... ... ... - - pattern-not-inside: | - - severity: INFO - - id: java.android.best-practice.network-security-config.nsc-pinning-without-expiration - languages: - - generic - message: Your app uses TLS public key pinning without specifying an expiration date. If your users do not update the app to receive new pins in time, expired or replaced certificates can lead to connectivity issues until they install an update. It is considered best practice to set an expiration time, after which the system will default to trusting system CAs and disregard the pin. - metadata: - category: best-practice - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://developer.android.com/training/articles/security-config#CertificatePinning - - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/ - technology: - - android - paths: - include: - - '*.xml' - patterns: - - pattern: | - ... ... ... - - pattern-not-inside: | - ... ... ... - - pattern-inside: | - ... ... ... ... ... - - pattern-not-inside: | - - severity: INFO - - id: java.android.best-practice.network-security-config.nsc-allows-user-ca-certs - languages: - - generic - message: The Network Security Config is set to accept user-installed CAs. Evaluate if this is necessary for your app, and disable it if appropriate. (To hide this warning, set `xmlns:tools="http://schemas.android.com/tools" tools:ignore="AcceptsUserCertificates"` as parameters to your ``) - metadata: - category: best-practice - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://developer.android.com/training/articles/security-config - - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/ - technology: - - android - paths: - include: - - '*.xml' - patterns: - - pattern: | - - - pattern-inside: | - ... ... ... ... - - pattern-not-inside: | - - - pattern-not-inside: | - ... ... ... ... ... ... ... ... ... ... - severity: WARNING - - id: java.android.best-practice.network-security-config.nsc-allows-user-ca-certs-for-domain - languages: - - generic - message: The Network Security Config is set to accept user-installed CAs for the domain `$DOMAIN`. Evaluate if this is necessary for your app, and disable it if appropriate. (To hide this warning, set `xmlns:tools="http://schemas.android.com/tools" tools:ignore="AcceptsUserCertificates"` as parameters to your ``) - metadata: - category: best-practice - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://developer.android.com/training/articles/security-config - - https://www.nowsecure.com/blog/2018/08/15/a-security-analysts-guide-to-network-security-configuration-in-android-p/ - technology: - - android - paths: - include: - - '*.xml' - patterns: - - pattern: | - - - pattern-inside: | - ... ... ... - - pattern-inside: | - ... $DOMAIN ... ... ... - - pattern-not-inside: | - - - pattern-not-inside: | - ... ... ... ... ... ... ... ... ... ... - severity: WARNING - - id: java.android.security.exported_activity.exported_activity - languages: - - generic - message: The application exports an activity. Any application on the device can launch the exported activity which may compromise the integrity of your application or its data. Ensure that any exported activities do not have privileged access to your application's control plane. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-926: Improper Export of Android Application Components' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A5:2021 Security Misconfiguration - references: - - https://cwe.mitre.org/data/definitions/926.html - subcategory: - - vuln - technology: - - Android - paths: - exclude: - - sources/ - - classes3.dex - - '*.so' - include: - - '*AndroidManifest.xml' - patterns: - - pattern-not-inside: - - pattern-inside: " \n" - - pattern-either: + $DATA = request.$W(...) + ... + django.shortcuts.redirect(..., $DATA, ...) - pattern: | - + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - ... /> - severity: WARNING - - id: java.aws-lambda.security.tainted-sql-string.tainted-sql-string - languages: - - java - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - interfile: true - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/SQL_Injection - subcategory: - - vuln - technology: - - aws-lambda - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR".concat(...) - - patterns: - - pattern-inside: | - StringBuilder $SB = new StringBuilder("$SQLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$SQLSTR"; - ... - - pattern: $VAR += ... - - pattern: String.format("$SQLSTR", ...) - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b - - pattern-not-inside: | - System.out.$PRINTLN(...) - pattern-sources: - - patterns: - - focus-metavariable: $EVENT - - pattern-either: - - pattern: | - $HANDLERTYPE $HANDLER($TYPE $EVENT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { - ... - } - - pattern: | - $HANDLERTYPE $HANDLER(InputStream $EVENT, OutputStream $OUT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { - ... - } - severity: ERROR - - id: java.aws-lambda.security.tainted-sqli.tainted-sqli - languages: - - java - message: Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use parameterized SQL queries or properly sanitize user input instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - interfile: true - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - sql - - java - - aws-lambda - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: "(java.sql.CallableStatement $STMT) = ...; \n" - - pattern: | - (java.sql.Statement $STMT) = ...; - - pattern: | - (java.sql.PreparedStatement $STMT) = ...; - - pattern: | - $VAR = $CONN.prepareStatement(...) - - pattern: | - $PATH.queryForObject(...); - - pattern: | - (java.util.Map $STMT) = $PATH.queryForMap(...); - - pattern: | - (org.springframework.jdbc.support.rowset.SqlRowSet $STMT) = ...; - - patterns: - - pattern-inside: | - (String $SQL) = "$SQLSTR" + ...; - ... - - pattern: $PATH.$SQLCMD(..., $SQL, ...); - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(^SELECT.* | ^INSERT.* | ^UPDATE.*) - - metavariable-regex: - metavariable: $SQLCMD - regex: (execute|query|executeUpdate|batchUpdate) - pattern-sources: - - patterns: - - focus-metavariable: $EVENT - - pattern-either: - - pattern: | - $HANDLERTYPE $HANDLER($TYPE $EVENT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { - ... - } - - pattern: | - $HANDLERTYPE $HANDLER(InputStream $EVENT, OutputStream $OUT, com.amazonaws.services.lambda.runtime.Context $CONTEXT) { - ... - } - severity: WARNING - - id: java.java-jwt.security.audit.jwt-decode-without-verify.java-jwt-decode-without-verify - languages: - - java - message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-345: Insufficient Verification of Data Authenticity' - impact: HIGH - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - vuln - technology: - - jwt - patterns: - - pattern: | - com.auth0.jwt.JWT.decode(...); - - pattern-not-inside: |- - class $CLASS { - ... - $RETURNTYPE $FUNC (...) { + $DATA = request.$W(...) ... - $VERIFIER.verify(...); + django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) ... - } - } - severity: WARNING - - id: java.java-jwt.security.jwt-hardcode.java-jwt-hardcoded-secret - languages: - - java - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - subcategory: - - vuln - technology: - - java - - secrets - - jwt - patterns: - - pattern-either: + $INTERM = $STR.format(..., $DATA, ...) + ... + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - (Algorithm $ALG) = $ALGO.$HMAC("$Y"); + $DATA = request.$W(...) + ... + django.shortcuts.redirect(..., $STR % $DATA, ...) - pattern: | - $SECRET = "$Y"; + $DATA = request.$W(...) ... - (Algorithm $ALG) = $ALGO.$HMAC($SECRET); + $INTERM = $STR % $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - class $CLASS { - ... - $TYPE $SECRET = "$Y"; - ... - $RETURNTYPE $FUNC (...) { - ... - (Algorithm $ALG) = $ALGO.$HMAC($SECRET); - ... - } - ... - } - - focus-metavariable: $Y - - metavariable-regex: - metavariable: $HMAC - regex: (HMAC384|HMAC256|HMAC512) - severity: WARNING - - id: java.java-jwt.security.jwt-none-alg.java-jwt-none-alg - languages: - - java - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - vuln - technology: - - jwt - pattern-either: - - pattern: | - $JWT.sign(com.auth0.jwt.algorithms.Algorithm.none()); - - pattern: | - $NONE = com.auth0.jwt.algorithms.Algorithm.none(); - ... - $JWT.sign($NONE); - - pattern: |- - class $CLASS { - ... - $TYPE $NONE = com.auth0.jwt.algorithms.Algorithm.none(); - ... - $RETURNTYPE $FUNC (...) { + $DATA = request.$W(...) ... - $JWT.sign($NONE); + django.shortcuts.redirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) ... - } - ... - } - severity: ERROR - - id: java.jax-rs.security.insecure-resteasy.insecure-resteasy-deserialization - languages: - - java - message: When a Restful webservice endpoint is configured to use wildcard mediaType {*/*} as a value for the @Consumes annotation, an attacker could abuse the SerializableProvider by sending a HTTP Request with a Content-Type of application/x-java-serialized-object. The body of that request would be processed by the SerializationProvider and could contain a malicious payload, which may lead to arbitrary code execution when calling the $Y.getObject method. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://access.redhat.com/blogs/766093/posts/3162112 - subcategory: - - audit - technology: - - jax-rs - pattern-either: - - pattern: | - @Consumes({"application/x-java-serialized-object"}) - - pattern: | - @Consumes({"*/*"}) - - pattern: | - @Consumes("*/*") - - pattern: | - @Consumes({MediaType.WILDCARD_TYPE}) - severity: WARNING - - id: java.jax-rs.security.insecure-resteasy.default-resteasy-provider-abuse - languages: - - java - message: When a Restful webservice endpoint isn't configured with a @Consumes annotation, an attacker could abuse the SerializableProvider by sending a HTTP Request with a Content-Type of application/x-java-serialized-object. The body of that request would be processed by the SerializationProvider and could contain a malicious payload, which may lead to arbitrary code execution. Instead, add a @Consumes annotation to the function or class. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://access.redhat.com/blogs/766093/posts/3162112 - subcategory: - - audit - technology: - - jax-rs - patterns: - - pattern: | - @Path("...") - public $RETURNTYPE $METHOD(...) { ...} - - pattern-not-inside: | - @GET - public $RETURNTYPE $METHOD(...) { ...} - - pattern-not-inside: | - @Path("...") - @Consumes(...) - public $RETURNTYPE $METHOD(...) { ...} - - pattern-not-inside: | - @Consumes(...) - public class $CLASSNAME { ... } - severity: WARNING - - id: java.jax-rs.security.jax-rs-path-traversal.jax-rs-path-traversal - languages: - - java - message: Detected a potential path traversal. A malicious actor could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://www.owasp.org/index.php/Path_Traversal - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN - subcategory: - - vuln - technology: - - jax-rs - pattern-either: - - pattern: | - $RETURNTYPE $FUNC (..., @PathParam(...) $TYPE $VAR, ...) { - ... - new File(..., $VAR, ...); - ... - } - - pattern: |- - $RETURNTYPE $FUNC (..., @javax.ws.rs.PathParam(...) $TYPE $VAR, ...) { - ... - new File(..., $VAR, ...); - ... - } - severity: WARNING - - id: java.jboss.security.session_sqli.find-sql-string-concatenation - languages: - - java - message: In $METHOD, $X is used to construct a SQL query via string concatenation. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - jboss - pattern-either: - - pattern: | - $RETURN $METHOD(...,String $X,...){ - ... - Session $SESSION = ...; - ... - String $QUERY = ... + $X + ...; - ... - PreparedStatement $PS = $SESSION.connection().prepareStatement($QUERY); - ... - ResultSet $RESULT = $PS.executeQuery(); - ... - } - - pattern: | - $RETURN $METHOD(...,String $X,...){ - ... - String $QUERY = ... + $X + ...; - ... - Session $SESSION = ...; - ... - PreparedStatement $PS = $SESSION.connection().prepareStatement($QUERY); - ... - ResultSet $RESULT = $PS.executeQuery(); - ... - } - severity: ERROR - - id: java.jjwt.security.jwt-none-alg.jjwt-none-alg - languages: - - java - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. - metadata: - asvs: - control_id: 3.5.3 Insecue Stateless Session Tokens - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - patterns: - - pattern: | - io.jsonwebtoken.Jwts.builder(); - - pattern-not-inside: |- - $RETURNTYPE $FUNC(...) { - ... - $JWTS.signWith(...); - ... - } - severity: ERROR - - id: java.lang.correctness.assignment-comparison.assignment-comparison - languages: - - java - message: The value of `$X` is being ignored and will be used in the conditional test - metadata: - category: correctness - technology: - - java - pattern-either: - - pattern: if ($X=true) { ... } - - pattern: if ($X=false) { ... } - severity: ERROR - - id: java.lang.correctness.eqeq.eqeq - languages: - - java - message: '`$X == $X` or `$X != $X` is always true. (Unless the value compared is a float or double). To test if `$X` is not-a-number, use `Double.isNaN($X)`.' - metadata: - category: correctness - technology: - - java - patterns: - - pattern-not-inside: assert $X; - - pattern-not-inside: | - assert $X : $Y; - - pattern-either: - - pattern: $X == $X - - pattern: $X != $X - - pattern-not: 1 == 1 - severity: ERROR - - id: java.lang.correctness.hardcoded-conditional.hardcoded-conditional - languages: - - java - message: This if statement will always have the same behavior and is therefore unnecessary. - metadata: - category: correctness - technology: - - java - patterns: - - pattern-either: - - pattern: if (true) { ... } - - pattern: if (false) { ... } - - pattern: if ($VAR = true) { ... } - - pattern: if ($VAR = false) { ... } - - pattern: if ($EXPR && false) { ... } - - pattern: if (false && $EXPR) { ... } - - pattern: if ($EXPR || true) { ... } - - pattern: if (true || $EXPR) { ... } - severity: ERROR - - id: java.lang.correctness.no-string-eqeq.no-string-eqeq - languages: - - java - message: Strings should not be compared with '=='. This is a reference comparison operator. Use '.equals()' instead. - metadata: - category: correctness - technology: - - java - patterns: - - pattern-not: null == (String $Y) - - pattern: $X == (String $Y) - severity: WARNING - - id: java.lang.security.audit.anonymous-ldap-bind.anonymous-ldap-bind - languages: - - java - message: Detected anonymous LDAP bind. This permits anonymous users to execute LDAP statements. Consider enforcing authentication for LDAP. See https://docs.oracle.com/javase/tutorial/jndi/ldap/auth_mechs.html for more information. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-287: Improper Authentication' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#LDAP_ANONYMOUS - subcategory: - - audit - technology: - - java - pattern: | - $ENV.put($CTX.SECURITY_AUTHENTICATION, "none"); - ... - $DCTX = new InitialDirContext($ENV, ...); - severity: WARNING - - id: java.lang.security.audit.bad-hexa-conversion.bad-hexa-conversion - languages: - - java - message: '''Integer.toHexString()'' strips leading zeroes from each byte if read byte-by-byte. This mistake weakens the hash value computed since it introduces more collisions. Use ''String.format("%02X", ...)'' instead.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-704: Incorrect Type Conversion or Cast' - impact: LOW - likelihood: LOW - owasp: A03:2017 - Sensitive Data Exposure - references: - - https://cwe.mitre.org/data/definitions/704.html - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#BAD_HEXA_CONVERSION - subcategory: - - audit - technology: - - java - pattern: |- - $X $METHOD(...) { - ... - MessageDigest $MD = ...; - ... - $MD.digest(...); - ... - Integer.toHexString(...); - } - severity: WARNING - - id: java.lang.security.audit.blowfish-insufficient-key-size.blowfish-insufficient-key-size - languages: - - java - message: Using less than 128 bits for Blowfish is considered insecure. Use 128 bits or more, or switch to use AES instead. - metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#BLOWFISH_KEY_SIZE - subcategory: - - audit - technology: - - java - patterns: - - pattern: | - $KEYGEN = KeyGenerator.getInstance("Blowfish"); - ... - $KEYGEN.init($SIZE); - - metavariable-comparison: - comparison: $SIZE < 128 - metavariable: $SIZE - severity: WARNING - - fix: | - "AES/GCM/NoPadding" - id: java.lang.security.audit.cbc-padding-oracle.cbc-padding-oracle - languages: - - java - message: Using CBC with PKCS5Padding is susceptible to padding oracle attacks. A malicious actor could discern the difference between plaintext with valid or invalid padding. Further, CBC mode does not include any integrity checks. Use 'AES/GCM/NoPadding' instead. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://capec.mitre.org/data/definitions/463.html - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#cipher-modes - - https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PADDING_ORACLE - subcategory: - - audit - technology: - - java - patterns: - - pattern-inside: Cipher.getInstance("=~/.*\/CBC\/PKCS5Padding/") - - pattern: | - "=~/.*\/CBC\/PKCS5Padding/" - severity: WARNING - - id: java.lang.security.audit.command-injection-formatted-runtime-call.command-injection-formatted-runtime-call - languages: - - java - message: A formatted or concatenated string was detected as input to a java.lang.Runtime call. This is dangerous if a variable is controlled by user input and could result in a command injection. Ensure your variables are not controlled by users or sufficiently sanitized. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#COMMAND_INJECTION. - subcategory: - - audit - technology: - - java - patterns: - - metavariable-pattern: - metavariable: $RUNTIME - patterns: - - pattern-either: - - pattern: (java.lang.Runtime $R) - - pattern: java.lang.Runtime.getRuntime(...) - - pattern-either: - - pattern: $RUNTIME.exec($X + $Y); - - pattern: $RUNTIME.exec(String.format(...)); - - pattern: $RUNTIME.loadLibrary($X + $Y); - - pattern: $RUNTIME.loadLibrary(String.format(...)); - - patterns: - - pattern-either: - - pattern: | - $RUNTIME.exec("=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", $ARG,...) - - pattern: | - $RUNTIME.exec(Arrays.asList("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...),...) - - pattern: | - $RUNTIME.exec(new String[]{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...},...) - - patterns: - - pattern-either: - - pattern: | - $RUNTIME.exec($CMD,"-c",$ARG,...) - - pattern: | - $RUNTIME.exec(Arrays.asList($CMD,"-c",$ARG,...),...) - - pattern: | - $RUNTIME.exec(new String[]{$CMD,"-c",$ARG,...},...) - - pattern-inside: | - $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/"; - ... - - patterns: - - pattern-either: - - pattern: | - $RUNTIME.exec($CMD, $EXECUTE, $ARG, ...) - - pattern-inside: | - $CMD = new String[]{"=~/(sh|bash|ksh|csh|tcsh|zsh)/", ...}; - ... - - patterns: - - pattern-either: - - pattern: | - $RUNTIME.exec("=~/(sh|bash|ksh|csh|tcsh|zsh)/", $BASH, $ARG,...) - - pattern: | - $RUNTIME.exec(Arrays.asList("=~/(sh|bash|ksh|csh|tcsh|zsh)/",$BASH,$ARG,...),...) - - pattern: | - $RUNTIME.exec(new String[]{"=~/(sh|bash|ksh|csh|tcsh|zsh)/",$BASH,$ARG,...},...) - - pattern-inside: | - $BASH = new String[]{"=~/(-c)/", ...}; - ... - - pattern-not-inside: | - $ARG = "..."; - ... - - pattern-not: | - $RUNTIME.exec("...","...","...",...) - - pattern-not: | - $RUNTIME.exec(new String[]{"...","...","...",...},...) - - pattern-not: | - $RUNTIME.exec(Arrays.asList("...","...","...",...),...) - severity: ERROR - - id: java.lang.security.audit.command-injection-process-builder.command-injection-process-builder - languages: - - java - message: A formatted or concatenated string was detected as input to a ProcessBuilder call. This is dangerous if a variable is controlled by user input and could result in a command injection. Ensure your variables are not controlled by users or sufficiently sanitized. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - java - pattern-either: - - patterns: + $INTERM = f"...{$DATA}..." + ... + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - new ProcessBuilder($CMD,...) - - pattern-not-inside: | - $CMD = "..."; + $DATA = request.$W(...) ... - - pattern-not-inside: | - $CMD = Arrays.asList("...",...); + django.shortcuts.redirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) ... - - pattern-not-inside: | - $CMD = new String[]{"...",...}; + $INTERM = $STR + $DATA ... - - pattern-not: | - new ProcessBuilder("...",...) - - pattern-not: | - new ProcessBuilder(new String[]{"...",...},...) - - pattern-not: | - new ProcessBuilder(Arrays.asList("...",...),...) - - patterns: + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: $A = django.shortcuts.redirect(..., request.$W(...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S % request.$W(...), ...) + - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) + - pattern: return django.shortcuts.redirect(..., request.$W(...), ...) + - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: return django.shortcuts.redirect(..., $S % request.$W(...), ...) + - pattern: return django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) + - pattern: django.shortcuts.redirect(..., request.$W[...], ...) + - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: django.shortcuts.redirect(..., $S % request.$W[...], ...) + - pattern: django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) - pattern: | - $PB.command($CMD,...) - - pattern-inside: | - $TYPE $PB = new ProcessBuilder(...); - ... - - pattern-not-inside: | - $CMD = "..."; + $DATA = request.$W[...] ... - - pattern-not-inside: | - $CMD = Arrays.asList("...",...); + django.shortcuts.redirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] ... - - pattern-not-inside: | - $CMD = new String[]{"...",...}; + $INTERM = $DATA ... - - pattern-not: | - $PB.command("...",...) - - pattern-not: | - $PB.command(new String[]{"...",...},...) - - pattern-not: | - $PB.command(Arrays.asList("...",...),...) - - patterns: - - pattern-either: - - pattern: | - new ProcessBuilder("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...) - - pattern: | - new ProcessBuilder("cmd","/c",$ARG,...) - - pattern: | - new ProcessBuilder(Arrays.asList("cmd","/c",$ARG,...),...) - - pattern: | - new ProcessBuilder(new String[]{"cmd","/c",$ARG,...},...) - - patterns: - - pattern-either: - - pattern: | - new ProcessBuilder($CMD,"/c",$ARG,...) - - pattern: | - new ProcessBuilder(Arrays.asList($CMD,"/c",$ARG,...),...) - - pattern: | - new ProcessBuilder(new String[]{$CMD,"/c",$ARG,...},...) - - pattern-inside: | - $CMD = "cmd"; - ... - - pattern-not-inside: | - $ARG = "..."; + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] ... - - pattern-not: | - new ProcessBuilder("...","...","...",...) - - pattern-not: | - new ProcessBuilder(new String[]{"...","...","...",...},...) - - pattern-not: | - new ProcessBuilder(Arrays.asList("...","...","...",...),...) - - patterns: - - pattern-either: - - pattern: | - $PB.command("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...) - - pattern: | - $PB.command("cmd","/c",$ARG,...) - - pattern: | - $PB.command(Arrays.asList("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...),...) - - pattern: | - $PB.command(Arrays.asList("cmd","/c",$ARG,...),...) - - pattern: | - $PB.command(new String[]{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$ARG,...},...) - - pattern: | - $PB.command(new String[]{"cmd","/c",$ARG,...},...) - - patterns: - - pattern-either: - - pattern: | - $PB.command($CMD,"-c",$ARG,...) - - pattern: | - $PB.command(Arrays.asList($CMD,"-c",$ARG,...),...) - - pattern: | - $PB.command(new String[]{$CMD,"-c",$ARG,...},...) - - pattern-inside: | - $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/"; - ... - - patterns: - - pattern-either: - - pattern: | - $PB.command($CMD,"/c",$ARG,...) - - pattern: | - $PB.command(Arrays.asList($CMD,"/c",$ARG,...),...) - - pattern: | - $PB.command(new String[]{$CMD,"/c",$ARG,...},...) - - pattern-inside: | - $CMD = "cmd"; - ... - - pattern-inside: | - $TYPE $PB = new ProcessBuilder(...); + django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] ... - - pattern-not-inside: | - $ARG = "..."; + $INTERM = $STR.format(..., $DATA, ...) ... - - pattern-not: | - $PB.command("...","...","...",...) - - pattern-not: | - $PB.command(new String[]{"...","...","...",...},...) - - pattern-not: | - $PB.command(Arrays.asList("...","...","...",...),...) - severity: ERROR - - id: java.lang.security.audit.cookie-missing-httponly.cookie-missing-httponly - languages: - - java - message: A cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie. Set the 'HttpOnly' flag by calling 'cookie.setHttpOnly(true);' - metadata: - asvs: - control_id: 3.4.2 Missing Cookie Attribute - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v34-cookie-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#HTTPONLY_COOKIE - subcategory: - - audit - technology: - - java - patterns: - - pattern-not-inside: $COOKIE.setValue(""); ... - - pattern-either: - - pattern: $COOKIE.setHttpOnly(false); - - patterns: - - pattern-not-inside: $COOKIE.setHttpOnly(...); ... - - pattern-not-inside: $COOKIE = ResponseCookie.from(...). ...; ... - - pattern: $RESPONSE.addCookie($COOKIE); - severity: WARNING - - id: java.lang.security.audit.cookie-missing-secure-flag.cookie-missing-secure-flag - languages: - - java - message: A cookie was detected without setting the 'secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'secure' flag by calling '$COOKIE.setSecure(true);' - metadata: - asvs: - control_id: 3.4.1 Missing Cookie Attribute - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v34-cookie-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#INSECURE_COOKIE - subcategory: - - audit - technology: - - java - patterns: - - pattern-not-inside: $COOKIE.setValue(""); ... - - pattern-either: - - pattern: $COOKIE.setSecure(false); - - patterns: - - pattern-not-inside: $COOKIE.setSecure(...); ... - - pattern-not-inside: $COOKIE = ResponseCookie.from(...). ...; ... - - pattern: $RESPONSE.addCookie($COOKIE); - severity: WARNING - - id: java.lang.security.audit.crlf-injection-logs.crlf-injection-logs - languages: - - java - message: When data from an untrusted source is put into a logger and not neutralized correctly, an attacker could forge log entries or include malicious content. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-93: Improper Neutralization of CRLF Sequences (''CRLF Injection'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#CRLF_INJECTION_LOGS - subcategory: - - vuln - technology: - - java - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - class $CLASS { - ... - Logger $LOG = ...; - ... - } - - pattern-either: - - pattern-inside: | - $X $METHOD(...,HttpServletRequest $REQ,...) { - ... - } - - pattern-inside: | - $X $METHOD(...,ServletRequest $REQ,...) { - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - HttpServletRequest $REQ = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - ServletRequest $REQ = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - Logger $LOG = ...; - ... - HttpServletRequest $REQ = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - Logger $LOG = ...; - ... - ServletRequest $REQ = ...; - ... - } - - pattern-either: + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - String $VAL = $REQ.getParameter(...); + $DATA = request.$W[...] ... - $LOG.$LEVEL(<... $VAL ...>); + django.shortcuts.redirect(..., $STR % $DATA, ...) - pattern: | - String $VAL = $REQ.getParameter(...); + $DATA = request.$W[...] ... - $LOG.log($LEVEL,<... $VAL ...>); + $INTERM = $STR % $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - $LOG.$LEVEL(<... $REQ.getParameter(...) ...>); + $DATA = request.$W[...] + ... + django.shortcuts.redirect(..., f"...{$DATA}...", ...) - pattern: | - $LOG.log($LEVEL,<... $REQ.getParameter(...) ...>); - severity: WARNING - - fix: | - "AES/GCM/NoPadding" - id: java.lang.security.audit.crypto.des-is-deprecated.des-is-deprecated - languages: - - java - - kt - message: DES is considered deprecated. AES is the recommended cipher. Upgrade to use AES. See https://www.nist.gov/news-events/news/2005/06/nist-withdraws-outdated-data-encryption-standard for more information. - metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::symmetric-algorithm::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.nist.gov/news-events/news/2005/06/nist-withdraws-outdated-data-encryption-standard - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#DES_USAGE - subcategory: - - vuln - technology: - - java - patterns: - - pattern-either: - - pattern-inside: $CIPHER.getInstance("=~/DES/.*/") - - pattern-inside: $CIPHER.getInstance("DES") - - pattern-either: + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - "=~/DES/.*/" + $DATA = request.$W[...] + ... + django.shortcuts.redirect(..., $STR + $DATA, ...) - pattern: | - "DES" - severity: WARNING - - id: java.lang.security.audit.crypto.desede-is-deprecated.desede-is-deprecated - languages: - - java - - kt - message: Triple DES (3DES or DESede) is considered deprecated. AES is the recommended cipher. Upgrade to use AES. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::symmetric-algorithm::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#TDES_USAGE - subcategory: - - vuln - technology: - - java - patterns: - - pattern-either: + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: $A = django.shortcuts.redirect(..., request.$W[...], ...) + - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S % request.$W[...], ...) + - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) + - pattern: return django.shortcuts.redirect(..., request.$W[...], ...) + - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: return django.shortcuts.redirect(..., $S % request.$W[...], ...) + - pattern: return django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) + - pattern: django.shortcuts.redirect(..., request.$W, ...) + - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) + - pattern: django.shortcuts.redirect(..., $S % request.$W, ...) + - pattern: django.shortcuts.redirect(..., f"...{request.$W}...", ...) - pattern: | - $CIPHER.getInstance("=~/DESede.*/") + $DATA = request.$W + ... + django.shortcuts.redirect(..., $DATA, ...) - pattern: | - $CRYPTO.KeyGenerator.getInstance("DES") - severity: WARNING - - id: java.lang.security.audit.crypto.ecb-cipher.ecb-cipher - languages: - - java - message: Cipher in ECB mode is detected. ECB mode produces the same output for the same input each time which allows an attacker to intercept and replay the data. Further, ECB mode does not provide any integrity checking. See https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::mode::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#ECB_MODE - subcategory: - - vuln - technology: - - java - patterns: - - pattern: | - Cipher $VAR = $CIPHER.getInstance($MODE); - - metavariable-regex: - metavariable: $MODE - regex: .*ECB.* - severity: WARNING - - id: java.lang.security.audit.crypto.gcm-detection.gcm-detection - languages: - - java - message: GCM detected, please check that IV/nonce is not reused, an Initialization Vector (IV) is a nonce used to randomize the encryption, so that even if multiple messages with identical plaintext are encrypted, the generated corresponding ciphertexts are different. Unlike the Key, the IV usually does not need to be secret, rather it is important that it is random and unique. Certain encryption schemes the IV is exchanged in public as part of the ciphertext. Reusing same Initialization Vector with the same Key to encrypt multiple plaintext blocks allows an attacker to compare the ciphertexts and then, with some assumptions on the content of the messages, to gain important information about the data being encrypted. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-323: Reusing a Nonce, Key Pair in Encryption' - functional-categories: - - crypto::search::randomness::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A02:2021 - Cryptographic Failures - references: - - https://cwe.mitre.org/data/definitions/323.html - subcategory: - - audit - technology: - - java - patterns: - - pattern-either: - - pattern: $METHOD.getInstance("AES/GCM/NoPadding",...); - - pattern: new GCMParameterSpec(...); - severity: INFO - - id: java.lang.security.audit.crypto.gcm-nonce-reuse.gcm-nonce-reuse - languages: - - java - message: 'GCM IV/nonce is reused: encryption can be totally useless' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-323: Reusing a Nonce, Key Pair in Encryption' - functional-categories: - - crypto::search::randomness::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://www.youtube.com/watch?v=r1awgAl90wM - subcategory: - - vuln - technology: - - java - patterns: - - pattern-either: - - pattern: new GCMParameterSpec(..., "...".getBytes(...), ...); - - pattern: byte[] $NONCE = "...".getBytes(...); ... new GCMParameterSpec(..., $NONCE, ...); - severity: ERROR - - id: java.lang.security.audit.crypto.no-null-cipher.no-null-cipher - languages: - - java - message: 'NullCipher was detected. This will not encrypt anything; the cipher text will be the same as the plain text. Use a valid, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' - metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#NULL_CIPHER - subcategory: - - vuln - technology: - - java - patterns: - - pattern-either: - - pattern: new NullCipher(...); - - pattern: new javax.crypto.NullCipher(...); - severity: WARNING - - id: java.lang.security.audit.crypto.no-static-initialization-vector.no-static-initialization-vector - languages: - - java - message: Initialization Vectors (IVs) for block ciphers should be randomly generated each time they are used. Using a static IV means the same plaintext encrypts to the same ciphertext every time, weakening the strength of the encryption. - metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-329: Generation of Predictable IV with CBC Mode' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A02:2021 - Cryptographic Failures - references: - - https://cwe.mitre.org/data/definitions/329.html - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#STATIC_IV - subcategory: - - vuln - technology: - - java - pattern-either: - - pattern: | - byte[] $IV = { + $DATA = request.$W ... - }; - ... - new IvParameterSpec($IV, ...); - - pattern: | - class $CLASS { - byte[] $IV = { - ... - }; + $INTERM = $DATA ... - $METHOD(...) { - ... - new IvParameterSpec($IV, ...); - ... - } - } - severity: WARNING - - id: java.lang.security.audit.crypto.rsa-no-padding.rsa-no-padding - languages: - - java - - kt - message: Using RSA without OAEP mode weakens the encryption. - metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::mode::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://rdist.root.org/2009/10/06/why-rsa-encryption-padding-is-critical/ - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#RSA_NO_PADDING - subcategory: - - vuln - technology: - - java - - kotlin - pattern: $CIPHER.getInstance("=~/RSA/[Nn][Oo][Nn][Ee]/NoPadding/") - severity: WARNING - - id: java.lang.security.audit.crypto.ssl.avoid-implementing-custom-digests.avoid-implementing-custom-digests - languages: - - java - message: 'Cryptographic algorithms are notoriously difficult to get right. By implementing a custom message digest, you risk introducing security issues into your program. Use one of the many sound message digests already available to you: MessageDigest sha256Digest = MessageDigest.getInstance("SHA256");' - metadata: - asvs: - control_id: 6.2.2 Insecure Custom Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#custom-algorithms - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#CUSTOM_MESSAGE_DIGEST - subcategory: - - audit - technology: - - java - pattern: |- - class $CLASS extends MessageDigest { - ... - } - severity: WARNING - - fix-regex: - regex: DefaultHttpClient - replacement: HttpClientBuilder - id: java.lang.security.audit.crypto.ssl.defaulthttpclient-is-deprecated.defaulthttpclient-is-deprecated - languages: - - java - message: DefaultHttpClient is deprecated. Further, it does not support connections using TLS1.2, which makes using DefaultHttpClient a security hazard. Use HttpClientBuilder instead. - metadata: - asvs: - control_id: 9.1.3 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v91-client-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#DEFAULT_HTTP_CLIENT - subcategory: - - audit - technology: - - java - pattern: new DefaultHttpClient(...); - severity: WARNING - - id: java.lang.security.audit.crypto.ssl.insecure-hostname-verifier.insecure-hostname-verifier - languages: - - java - message: Insecure HostnameVerifier implementation detected. This will accept any SSL certificate with any hostname, which creates the possibility for man-in-the-middle attacks. - metadata: - asvs: - control_id: 9.2.1 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_HOSTNAME_VERIFIER - subcategory: - - audit - technology: - - java - pattern-either: - - pattern: | - class $CLASS implements HostnameVerifier { - ... - public boolean verify(...) { return true; } - } - - pattern: |- - new HostnameVerifier(...){ - public boolean verify(...) { - return true; - } - } - - pattern: import org.apache.http.conn.ssl.NoopHostnameVerifier; - severity: WARNING - - id: java.lang.security.audit.crypto.ssl.insecure-trust-manager.insecure-trust-manager - languages: - - java - message: Detected empty trust manager implementations. This is dangerous because it accepts any certificate, enabling man-in-the-middle attacks. Consider using a KeyStore and TrustManagerFactory instead. See https://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https for more information. - metadata: - asvs: - control_id: 9.2.1 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures - references: - - https://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_TRUST_MANAGER - subcategory: - - audit - technology: - - java - patterns: - - pattern-either: - - pattern-inside: | - class $CLASS implements X509TrustManager { - ... - } - - pattern-inside: | - new X509TrustManager() { - ... - } - - pattern-inside: | - class $CLASS implements X509ExtendedTrustManager { - ... - } - - pattern-inside: | - new X509ExtendedTrustManager() { - ... - } - - pattern-not: public void checkClientTrusted(...) { $SOMETHING; } - - pattern-not: public void checkServerTrusted(...) { $SOMETHING; } - - pattern-either: - - pattern: public void checkClientTrusted(...) {} - - pattern: public void checkServerTrusted(...) {} - - pattern: public X509Certificate[] getAcceptedIssuers(...) { return null; } - severity: WARNING - - id: java.lang.security.audit.crypto.unencrypted-socket.unencrypted-socket - languages: - - java - message: Detected use of a Java socket that is not encrypted. As a result, the traffic could be read by an attacker intercepting the network traffic. Use an SSLSocket created by 'SSLSocketFactory' or 'SSLServerSocketFactory' instead. - metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - functional-categories: - - net::search::crypto-config::java.net - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNENCRYPTED_SOCKET - subcategory: - - vuln - technology: - - java - pattern-either: - - pattern: new ServerSocket(...) - - pattern: new Socket(...) - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-aes-ecb.use-of-aes-ecb - languages: - - java - message: 'Use of AES with ECB mode detected. ECB doesn''t provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::mode::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html - subcategory: - - vuln - technology: - - java - pattern: $CIPHER.getInstance("=~/AES/ECB.*/") - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-blowfish.use-of-blowfish - languages: - - java - message: 'Use of Blowfish was detected. Blowfish uses a 64-bit block size that makes it vulnerable to birthday attacks, and is therefore considered non-compliant. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html - subcategory: - - vuln - technology: - - java - pattern: $CIPHER.getInstance("Blowfish") - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-default-aes.use-of-default-aes - languages: - - java - message: 'Use of AES with no settings detected. By default, java.crypto.Cipher uses ECB mode. ECB doesn''t provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: java.crypto.Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::mode::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html - subcategory: - - vuln - technology: - - java - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - import javax; - ... - - pattern-either: - - pattern: javax.crypto.Cipher.getInstance("AES") - - pattern: (javax.crypto.Cipher $CIPHER).getInstance("AES") - - patterns: - - pattern-either: - - pattern-inside: | - import javax.*; - ... - - pattern-inside: | - import javax.crypto; - ... - - pattern-either: - - pattern: crypto.Cipher.getInstance("AES") - - pattern: (crypto.Cipher $CIPHER).getInstance("AES") - - patterns: - - pattern-either: - - pattern-inside: | - import javax.crypto.*; - ... - - pattern-inside: | - import javax.crypto.Cipher; - ... - - pattern-either: - - pattern: Cipher.getInstance("AES") - - pattern: (Cipher $CIPHER).getInstance("AES") - severity: WARNING - - fix: | - getSha512Digest - id: java.lang.security.audit.crypto.use-of-md5-digest-utils.use-of-md5-digest-utils - languages: - - java - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use HMAC instead. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-328: Use of Weak Hash' - functional-categories: - - crypto::search::hash-algorithm::org.apache.commons - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_MD5 - subcategory: - - vuln - technology: - - java - patterns: - - pattern: | - $DU.$GET_ALGO().digest(...) - - metavariable-pattern: - metavariable: $GET_ALGO - pattern: getMd5Digest - - metavariable-pattern: - metavariable: $DU - pattern: DigestUtils - - focus-metavariable: $GET_ALGO - severity: WARNING - - fix: | - "SHA-512" - id: java.lang.security.audit.crypto.use-of-md5.use-of-md5 - languages: - - java - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use HMAC instead. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-328: Use of Weak Hash' - functional-categories: - - crypto::search::hash-algorithm::java.security - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_MD5 - subcategory: - - vuln - technology: - - java - patterns: - - pattern: | - java.security.MessageDigest.getInstance($ALGO, ...); - - metavariable-regex: - metavariable: $ALGO - regex: (.MD5.) - - focus-metavariable: $ALGO - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-rc2.use-of-rc2 - languages: - - java - message: 'Use of RC2 was detected. RC2 is vulnerable to related-key attacks, and is therefore considered non-compliant. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html - subcategory: - - vuln - technology: - - java - pattern: $CIPHER.getInstance("RC2") - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-rc4.use-of-rc4 - languages: - - java - message: 'Use of RC4 was detected. RC4 is vulnerable to several attacks, including stream cipher attacks and bit flipping attacks. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - functional-categories: - - crypto::search::symmetric-algorithm::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html - subcategory: - - vuln - technology: - - java - pattern: $CIPHER.getInstance("RC4") - severity: WARNING - - id: java.lang.security.audit.crypto.use-of-sha1.use-of-sha1 - languages: - - java - message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Instead, use PBKDF2 for password hashing or SHA256 or SHA512 for other hash function applications. - metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-328: Use of Weak Hash' - functional-categories: - - crypto::search::hash-algorithm::javax.crypto - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#WEAK_MESSAGE_DIGEST_SHA1 - subcategory: - - vuln - technology: - - java - pattern-either: - - patterns: - - pattern: | - java.security.MessageDigest.getInstance("$ALGO", ...); - - metavariable-regex: - metavariable: $ALGO - regex: (SHA1|SHA-1) - - pattern: | - $DU.getSha1Digest().digest(...) - severity: WARNING - - id: java.lang.security.audit.crypto.weak-random.weak-random - languages: - - java - message: Detected use of the functions `Math.random()` or `java.util.Random()`. These are both not cryptographically strong random number generators (RNGs). If you are using these RNGs to create passwords or secret tokens, use `java.security.SecureRandom` instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-330: Use of Insufficiently Random Values' - functional-categories: - - crypto::search::randomness::java.security - impact: MEDIUM - likelihood: LOW - owasp: - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - java - pattern-either: - - pattern: | - new java.util.Random(...).$FUNC(...) - - pattern: | - java.lang.Math.random(...) - severity: WARNING - - id: java.lang.security.audit.crypto.weak-rsa.use-of-weak-rsa-key - languages: - - java - message: RSA keys should be at least 2048 bits based on NIST recommendation. - metadata: - asvs: - control_id: 6.2.5 Insecure Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - functional-categories: - - crypto::search::key-length::java.security - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#RSA_KEY_SIZE - subcategory: - - vuln - technology: - - java - patterns: - - pattern: | - KeyPairGenerator $KEY = $G.getInstance("RSA"); - ... - $KEY.initialize($BITS); - - metavariable-comparison: - comparison: $BITS < 2048 - metavariable: $BITS - severity: WARNING - - id: java.lang.security.audit.dangerous-groovy-shell.dangerous-groovy-shell - languages: - - java - message: A expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#GROOVY_SHELL - subcategory: - - audit - technology: - - groovy - patterns: - - pattern-either: - - pattern: | - $SHELL.parse(...) + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - $SHELL.evaluate(...) + $DATA = request.$W + ... + django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) - pattern: | - $SHELL.parseClass(...) - - pattern-either: - - pattern-inside: | - groovy.lang.GroovyShell $SHELL = ...; + $DATA = request.$W ... - - pattern-inside: | - groovy.lang.GroovyClassLoader $SHELL = ...; + $INTERM = $STR.format(..., $DATA, ...) ... - - pattern-not: | - $SHELL.parse("...",...) - - pattern-not: | - $SHELL.evaluate("...",...) - - pattern-not: | - $SHELL.parseClass("...",...) - severity: WARNING - - id: java.lang.security.audit.el-injection.el-injection - languages: - - java - message: An expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#EL_INJECTION - subcategory: - - audit - technology: - - java - patterns: - - pattern-either: - - pattern: | - class $CLASS { - ... - ExpressionFactory $EF; - ... - $X $METHOD(...) { - ... - $EF.createValueExpression($CTX,$INPUT,...); - ... - } - ... - } + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - class $CLASS { - ... - ExpressionFactory $EF = ...; - ... - $X $METHOD(...) { - ... - $EF.createValueExpression($CTX,$INPUT,...); - ... - } - ... - } + $DATA = request.$W + ... + django.shortcuts.redirect(..., $STR % $DATA, ...) - pattern: | - $X $METHOD(...) { - ... - ExpressionFactory $EF = ...; - ... - $EF.createValueExpression($CTX,$INPUT,...); - ... - } + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - $X $METHOD(...,ExpressionFactory $EF,...) { - ... - $EF.createValueExpression($CTX,$INPUT,...); - ... - } + $DATA = request.$W + ... + django.shortcuts.redirect(..., f"...{$DATA}...", ...) - pattern: | - class $CLASS { - ... - ExpressionFactory $EF; - ... - $X $METHOD(...) { - ... - $EF.createMethodExpression($CTX,$INPUT,...); - ... - } - ... - } + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.shortcuts.redirect(..., $INTERM, ...) - pattern: | - class $CLASS { - ... - ExpressionFactory $EF = ...; - ... - $X $METHOD(...) { - ... - $EF.createMethodExpression($CTX,$INPUT,...); - ... - } - ... - } + $DATA = request.$W + ... + django.shortcuts.redirect(..., $STR + $DATA, ...) - pattern: | - $X $METHOD(...) { - ... - ExpressionFactory $EF = ...; - ... - $EF.createMethodExpression($CTX,$INPUT,...); - ... - } + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + django.shortcuts.redirect(..., $INTERM, ...) + - pattern: $A = django.shortcuts.redirect(..., request.$W, ...) + - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) + - pattern: $A = django.shortcuts.redirect(..., $S % request.$W, ...) + - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W}...", ...) + - pattern: return django.shortcuts.redirect(..., request.$W, ...) + - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) + - pattern: return django.shortcuts.redirect(..., $S % request.$W, ...) + - pattern: return django.shortcuts.redirect(..., f"...{request.$W}...", ...) + - pattern: django.http.HttpResponseRedirect(..., request.$W.get(...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) + - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) - pattern: | - $X $METHOD(...,ExpressionFactory $EF,...) { - ... - $EF.createMethodExpression($CTX,$INPUT,...); - ... - } + $DATA = request.$W.get(...) + ... + django.http.HttpResponseRedirect(..., $DATA, ...) - pattern: | - $X $METHOD(String $INPUT, ...) { - ... - $OBJECT.buildConstraintViolationWithTemplate($INPUT, ...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $EF.createValueExpression($CTX,"...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $EF.createValueExpression($CTX,$S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $EF.createMethodExpression($CTX,"...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $EF.createMethodExpression($CTX,$S,...); - ... - } - severity: WARNING - - id: java.lang.security.audit.formatted-sql-string.formatted-sql-string - languages: - - java - message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. - metadata: - asvs: - control_id: 5.3.5 Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html - - https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html#create_ps - - https://software-security.sans.org/developer-how-to/fix-sql-injection-in-java-using-prepared-callable-statement - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SQL_INJECTION - subcategory: - - vuln - technology: - - java - mode: taint - options: - taint_assume_safe_booleans: true - taint_assume_safe_numbers: true - pattern-propagators: - - from: $X - pattern: (StringBuffer $S).append($X) - to: $S - - from: $X - pattern: (StringBuilder $S).append($X) - to: $S - pattern-sanitizers: - - patterns: - - pattern: (CriteriaBuilder $CB).$ANY(...) - pattern-sinks: - - patterns: - - pattern-not: $S.$SQLFUNC(<... "=~/.*TABLE *$/" ...>) - - pattern-not: $S.$SQLFUNC(<... "=~/.*TABLE %s$/" ...>) - - pattern-either: - - pattern: (Statement $S).$SQLFUNC(...) - - pattern: (PreparedStatement $P).$SQLFUNC(...) - - pattern: (Connection $C).createStatement(...).$SQLFUNC(...) - - pattern: (Connection $C).prepareStatement(...).$SQLFUNC(...) - - pattern: (EntityManager $EM).$SQLFUNC(...) - - metavariable-regex: - metavariable: $SQLFUNC - regex: execute|executeQuery|createQuery|query|addBatch|nativeSQL|create|prepare - requires: CONCAT - pattern-sources: - - label: INPUT - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - $ANNOT $FUNC (..., $INPUT, ...) { - ... - } - - pattern: (String $INPUT) - - focus-metavariable: $INPUT - - label: CONCAT - patterns: - - pattern-either: - - pattern: $X + $INPUT - - pattern: $X += $INPUT - - pattern: $STRB.append($INPUT) - - pattern: String.format(..., $INPUT, ...) - - pattern: String.join(..., $INPUT, ...) - - pattern: (String $STR).concat($INPUT) - - pattern: $INPUT.concat(...) - - pattern: new $STRB(..., $INPUT, ...) - requires: INPUT - severity: ERROR - - id: java.lang.security.audit.http-response-splitting.http-response-splitting - languages: - - java - message: Older Java application servers are vulnerable to HTTP response splitting, which may occur if an HTTP request can be injected with CRLF characters. This finding is reported for completeness; it is recommended to ensure your environment is not affected by testing this yourself. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers (''HTTP Request/Response Splitting'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://www.owasp.org/index.php/HTTP_Response_Splitting - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#HTTP_RESPONSE_SPLITTING - subcategory: - - vuln - technology: - - java - pattern-either: - - pattern: | - $VAR = $REQ.getParameter(...); - ... - $COOKIE = new Cookie(..., $VAR, ...); - ... - $RESP.addCookie($COOKIE, ...); - - patterns: - - pattern-inside: | - $RETTYPE $FUNC(...,@PathVariable $TYPE $VAR, ...) { - ... - } - - pattern: | - $COOKIE = new Cookie(..., $VAR, ...); - ... - $RESP.addCookie($COOKIE, ...); - severity: INFO - - id: java.lang.security.audit.insecure-smtp-connection.insecure-smtp-connection - languages: - - java - message: Insecure SMTP connection detected. This connection will trust any SSL certificate. Enable certificate verification by setting 'email.setSSLCheckServerIdentity(true)'. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-297: Improper Validation of Certificate with Host Mismatch' - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#INSECURE_SMTP_SSL - subcategory: - - vuln - technology: - - java - patterns: - - pattern-not-inside: | - $EMAIL.setSSLCheckServerIdentity(true); - ... - - pattern-inside: | - $EMAIL = new SimpleEmail(...); - ... - - pattern: $EMAIL.send(...); - severity: WARNING - - id: java.lang.security.audit.java-reverse-shell.java-reverse-shell - languages: - - java - message: Semgrep found potential reverse shell behavior - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - java - patterns: - - pattern-either: - - pattern: | - Socket $S=new Socket(...); - ... - InputStream $SI = $S.getInputStream(); - ... - while(!$S.isClosed()) - { - ... - while($SI.available()>0)$PO.write($SI.read()); - ... - $SO.flush(); - ... - } - - pattern-inside: | - Process $P=new ProcessBuilder(...).redirectErrorStream(true).start(); - ... - $P.destroy(); - severity: WARNING - - id: java.lang.security.audit.jdbc-sql-formatted-string.jdbc-sql-formatted-string - languages: - - java - message: 'Possible JDBC injection detected. Use the parameterized query feature available in queryForObject instead of concatenating or formatting strings: ''jdbc.queryForObject("select * from table where name = ?", Integer.class, parameterName);''' - metadata: - asvs: - control_id: 5.3.5 Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SQL_INJECTION_SPRING_JDBC - subcategory: - - audit - technology: - - jdbc - patterns: - - pattern-inside: | - $JDBC = new JdbcTemplate(...); - ... - - pattern-either: - - pattern: $JDBC.queryForObject($STR + $VAR, ...); - - pattern: $JDBC.queryForObject(String.format(...), ...); - - pattern: | - String $Q = $STR + $VAR; - ... - $JDBC.queryForObject($Q, ...); - - pattern: | - String $Q = String.format(...); - ... - $JDBC.queryForObject($Q, ...); - - pattern: | - StringBuilder $Q = new StringBuilder(...); - ... - $Q.append($STR + $VAR); - ... - $JDBC.queryForObject($Q, ...); - - pattern: $JDBC.queryForList($STR + $VAR); - - pattern: $JDBC.queryForList(String.format(...)); - - pattern: | - String $Q = $STR + $VAR; - ... - $JDBC.queryForList($Q); - - pattern: | - String $Q = String.format(...); - ... - $JDBC.queryForList($Q); - - pattern: | - StringBuilder $Q = new StringBuilder(...); - ... - $Q.append($STR + $VAR); - ... - $JDBC.queryForList($Q, ...); - - pattern: $JDBC.update($STR + $VAR); - - pattern: $JDBC.update(String.format(...)); - - pattern: | - String $Q = $STR + $VAR; - ... - $JDBC.update($Q); - - pattern: | - String $Q = String.format(...); - ... - $JDBC.update($Q); - - pattern: | - StringBuilder $Q = new StringBuilder(...); - ... - $Q.append($STR + $VAR); - ... - $JDBC.update($Q, ...); - - pattern: $JDBC.execute($STR + $VAR); - - pattern: $JDBC.execute(String.format(...)); - - pattern: | - String $Q = $STR + $VAR; - ... - $JDBC.execute($Q); - - pattern: | - String $Q = String.format(...); - ... - $JDBC.execute($Q); - - pattern: | - StringBuilder $Q = new StringBuilder(...); - ... - $Q.append($STR + $VAR); - ... - $JDBC.execute($Q, ...); - - pattern: $JDBC.insert($STR + $VAR); - - pattern: $JDBC.insert(String.format(...)); - - pattern: | - String $Q = $STR + $VAR; - ... - $JDBC.insert($Q); - - pattern: | - String $Q = String.format(...); - ... - $JDBC.insert($Q); - - pattern: | - StringBuilder $Q = new StringBuilder(...); - ... - $Q.append($STR + $VAR); + $DATA = request.$W.get(...) ... - $JDBC.insert($Q, ...); - severity: WARNING - - id: java.lang.security.audit.ldap-entry-poisoning.ldap-entry-poisoning - languages: - - java - message: An object-returning LDAP search will allow attackers to control the LDAP response. This could lead to Remote Code Execution. - metadata: - asvs: - control_id: 5.3.7 Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf - - https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#LDAP_ENTRY_POISONING - subcategory: - - audit - technology: - - java - pattern-either: - - pattern: | - new SearchControls($S, $CL, $TL, $AT, true, $DEREF) - - pattern: | - SearchControls $VAR = new SearchControls(); - ... - $VAR.setReturningObjFlag(true); - severity: WARNING - - id: java.lang.security.audit.ldap-injection.ldap-injection - languages: - - java - message: Detected non-constant data passed into an LDAP query. If this data can be controlled by an external user, this is an LDAP injection. Ensure data passed to an LDAP query is not controllable; or properly sanitize the data. - metadata: - asvs: - control_id: 5.3.7 Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#LDAP_INJECTION - subcategory: - - audit - technology: - - java - patterns: - - pattern-either: - - pattern-inside: | - $X $METHOD(...) { - ... - InitialDirContext $CTX = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - DirContext $CTX = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - InitialLdapContext $CTX = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - LdapContext $CTX = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - LdapCtx $CTX = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - EventDirContext $CTX = ...; - ... - } - - pattern: | - $X $METHOD(...) { - ... - $CTX.search($Y,$INPUT,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $CTX.search($Y,"...",...); - ... - } - severity: WARNING - - id: java.lang.security.audit.md5-used-as-password.md5-used-as-password - languages: - - java - message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as PBKDF2 or bcrypt. You can use `javax.crypto.SecretKeyFactory` with `SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")` or, if using Spring, `org.springframework.security.crypto.bcrypt`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html - - https://github.com/returntocorp/semgrep-rules/issues/1609 - - https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory - - https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html - subcategory: - - vuln - technology: - - java - - md5 - mode: taint - pattern-sinks: - - patterns: - - pattern: $MODEL.$METHOD(...); - - metavariable-regex: - metavariable: $METHOD - regex: (?i)(.*password.*) - pattern-sources: - - patterns: - - pattern-inside: | - $TYPE $MD = MessageDigest.getInstance("MD5"); + $INTERM = $DATA ... - - pattern: $MD.digest(...); - severity: WARNING - - id: java.lang.security.audit.object-deserialization.object-deserialization - languages: - - java - message: Found object deserialization using ObjectInputStream. Deserializing entire Java objects is dangerous because malicious actors can create Java object streams with unintended consequences. Ensure that the objects being deserialized are not user-controlled. If this must be done, consider using HMACs to sign the data stream to make sure it is not tampered with, or consider only transmitting object fields and populating a new object. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://www.owasp.org/index.php/Deserialization_of_untrusted_data - - https://www.oracle.com/java/technologies/javase/seccodeguide.html#8 - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#OBJECT_DESERIALIZATION - subcategory: - - audit - technology: - - java - pattern: new ObjectInputStream(...); - severity: WARNING - - id: java.lang.security.audit.ognl-injection.ognl-injection - languages: - - java - message: A expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#OGNL_INJECTION - subcategory: - - audit - technology: - - ognl - patterns: - - pattern-either: - - pattern: | - $X $METHOD(...,OgnlReflectionProvider $P,...) { - ... - $P.getGetMethod($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlReflectionProvider $P,...) { - ... - $P.getSetMethod($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlReflectionProvider $P,...) { - ... - $P.getField($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlReflectionProvider $P,...) { - ... - $P.setProperties($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlReflectionProvider $P,...) { - ... - $P.setProperty($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlReflectionProvider $P,...) { - ... - $P.getValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlReflectionProvider $P,...) { - ... - $P.setValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ReflectionProvider $P,...) { - ... - $P.getGetMethod($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ReflectionProvider $P,...) { - ... - $P.getSetMethod($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ReflectionProvider $P,...) { - ... - $P.getField($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ReflectionProvider $P,...) { - ... - $P.setProperties($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ReflectionProvider $P,...) { - ... - $P.setProperty($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ReflectionProvider $P,...) { - ... - $P.getValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ReflectionProvider $P,...) { - ... - $P.setValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,TextParseUtil $P,...) { - ... - $P.translateVariables($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,TextParseUtil $P,...) { - ... - $P.translateVariablesCollection($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,TextParseUtil $P,...) { - ... - $P.shallBeIncluded($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,TextParseUtil $P,...) { - ... - $P.commaDelimitedStringToSet($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,TextParser $P,...) { - ... - $P.evaluate($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlTextParser $P,...) { - ... - $P.evaluate($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlUtil $P,...) { - ... - $P.setProperties($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlUtil $P,...) { - ... - $P.setProperty($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlUtil $P,...) { - ... - $P.getValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlUtil $P,...) { - ... - $P.setValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlUtil $P,...) { - ... - $P.callMethod($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlUtil $P,...) { - ... - $P.compile($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,VelocityStrutsUtil $P,...) { - ... - $P.evaluate($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,StrutsUtil $P,...) { - ... - $P.isTrue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,StrutsUtil $P,...) { - ... - $P.findString($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,StrutsUtil $P,...) { - ... - $P.findValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,StrutsUtil $P,...) { - ... - $P.getText($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,StrutsUtil $P,...) { - ... - $P.translateVariables($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,StrutsUtil $P,...) { - ... - $P.makeSelectList($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,OgnlTool $P,...) { - ... - $P.findValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ValueStack $P,...) { - ... - $P.findString($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ValueStack $P,...) { - ... - $P.findValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ValueStack $P,...) { - ... - $P.setValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...,ValueStack $P,...) { - ... - $P.setParameter($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlReflectionProvider $P = ...; - ... - $P.getGetMethod($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlReflectionProvider $P = ...; - ... - $P.getSetMethod($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlReflectionProvider $P = ...; - ... - $P.getField($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlReflectionProvider $P = ...; - ... - $P.setProperties($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlReflectionProvider $P = ...; - ... - $P.setProperty($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlReflectionProvider $P = ...; - ... - $P.getValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlReflectionProvider $P = ...; - ... - $P.setValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ReflectionProvider $P = ...; - ... - $P.getGetMethod($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ReflectionProvider $P = ...; - ... - $P.getSetMethod($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ReflectionProvider $P = ...; - ... - $P.getField($T, $INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ReflectionProvider $P = ...; - ... - $P.setProperties($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ReflectionProvider $P = ...; - ... - $P.setProperty($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ReflectionProvider $P = ...; - ... - $P.getValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ReflectionProvider $P = ...; - ... - $P.setValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - TextParseUtil $P = ...; - ... - $P.translateVariables($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - TextParseUtil $P = ...; - ... - $P.translateVariablesCollection($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - TextParseUtil $P = ...; - ... - $P.shallBeIncluded($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - TextParseUtil $P = ...; - ... - $P.commaDelimitedStringToSet($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - TextParser $P = ...; - ... - $P.evaluate($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlTextParser $P = ...; - ... - $P.evaluate($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlUtil $P = ...; - ... - $P.setProperties($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlUtil $P = ...; - ... - $P.setProperty($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlUtil $P = ...; - ... - $P.getValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlUtil $P = ...; - ... - $P.setValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlUtil $P = ...; - ... - $P.callMethod($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlUtil $P = ...; - ... - $P.compile($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - VelocityStrutsUtil $P = ...; - ... - $P.evaluate($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - StrutsUtil $P = ...; - ... - $P.isTrue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - StrutsUtil $P = ...; - ... - $P.findString($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - StrutsUtil $P = ...; - ... - $P.findValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - StrutsUtil $P = ...; - ... - $P.getText($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - StrutsUtil $P = ...; - ... - $P.translateVariables($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - StrutsUtil $P = ...; - ... - $P.makeSelectList($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - OgnlTool $P = ...; - ... - $P.findValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ValueStack $P = ...; - ... - $P.findString($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ValueStack $P = ...; - ... - $P.findValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ValueStack $P = ...; - ... - $P.setValue($INPUT,...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - ValueStack $P = ...; - ... - $P.setParameter($INPUT,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.getGetMethod($T,"...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.getSetMethod($T,"...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.getField($T,"...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.setProperties("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.setProperty("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.getValue("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.setValue("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.translateVariables("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.translateVariablesCollection("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.shallBeIncluded("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.commaDelimitedStringToSet("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.evaluate("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.callMethod("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.compile("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.isTrue("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.findString("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.findValue("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.getText("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.makeSelectList("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $P.setParameter("...",...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.getGetMethod($T,$S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.getSetMethod($T,$S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.getField($T,$S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.setProperties($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.setProperty($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.getValue($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.setValue($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.translateVariables($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.translateVariablesCollection($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.shallBeIncluded($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.commaDelimitedStringToSet($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.evaluate($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.callMethod($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.compile($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.isTrue($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.findString($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.findValue($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.getText($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.makeSelectList($S,...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $P.setParameter($S,...); - ... - } - severity: WARNING - - id: java.lang.security.audit.overly-permissive-file-permission.overly-permissive-file-permission - languages: - - java - message: Detected file permissions that are overly permissive (read, write, and execute). It is generally a bad practices to set overly permissive file permission such as read+write+exec for all users. If the file affected is a configuration, a binary, a script or sensitive data, it can lead to privilege escalation or information leakage. Instead, follow the principle of least privilege and give users only the permissions they need. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-276: Incorrect Default Permissions' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#OVERLY_PERMISSIVE_FILE_PERMISSION - subcategory: - - audit - technology: - - java - pattern-either: - - pattern: java.nio.file.Files.setPosixFilePermissions($FILE, java.nio.file.attribute.PosixFilePermissions.fromString("=~/(^......r..$)|(^.......w.$)|(^........x$)/")); - - pattern: | - $TYPE $P = java.nio.file.attribute.PosixFilePermissions.fromString("=~/(^......r..$)|(^.......w.$)|(^........x$)/"); - ... - java.nio.file.Files.setPosixFilePermissions($FILE, $P); - - pattern: | - $P.add(java.nio.file.attribute.PosixFilePermission.OTHERS_READ); - ... - java.nio.file.Files.setPosixFilePermissions($FILE, $P); - - pattern: | - $P.add(java.nio.file.attribute.PosixFilePermission.OTHERS_WRITE); - ... - java.nio.file.Files.setPosixFilePermissions($FILE, $P); - - pattern: |- - $P.add(java.nio.file.attribute.PosixFilePermission.OTHERS_EXECUTE); - ... - java.nio.file.Files.setPosixFilePermissions($FILE, $P); - severity: WARNING - - id: java.lang.security.audit.permissive-cors.permissive-cors - languages: - - java - message: https://find-sec-bugs.github.io/bugs.htm#PERMISSIVE_CORS Permissive CORS policy will allow a malicious application to communicate with the victim application in an inappropriate way, leading to spoofing, data theft, relay and other attacks. - metadata: - asvs: - control_id: 14.4.8 Permissive CORS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x22-V14-Config.md#v144-http-security-headers-requirements - section: 'V14: Configuration Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-183: Permissive List of Allowed Inputs' - impact: LOW - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit - technology: - - java - pattern-either: - - pattern: | - HttpServletResponse $RES = ...; - ... - $RES.addHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); - - pattern: | - HttpServletResponse $RES = ...; - ... - $RES.setHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); - - pattern: | - ServerHttpResponse $RES = ...; - ... - $RES.getHeaders().add("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); - - pattern: | - HttpHeaders $HEADERS = ...; - ... - $HEADERS.set("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); - - pattern: | - ServerWebExchange $SWE = ...; - ... - $SWE.getResponse().getHeaders().add("Access-Control-Allow-Origin", "*"); - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...) { - ... - $RES.addHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...) { - ... - $RES.setHeader("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); - ... - } - - pattern: | - $X $METHOD(...,ServerHttpResponse $RES,...) { - ... - $RES.getHeaders().add("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); - ... - } - - pattern: | - $X $METHOD(...,ServerWebExchange $SWE,...) { - ... - $SWE.getResponse().getHeaders().add("=~/access-control-allow-origin/i", "=~/^\*|null$/i"); - ... - } - - pattern: ResponseEntity.$RES().header("=~/access-control-allow-origin/i", "=~/^\*|null$/i") - - pattern: ServerResponse.$RES().header("=~/access-control-allow-origin/i", "=~/^\*|null$/i") - severity: WARNING - - id: java.lang.security.audit.script-engine-injection.script-engine-injection - languages: - - java - message: Detected potential code injection using ScriptEngine. Ensure user-controlled data cannot enter '.eval()', otherwise, this is a code injection vulnerability. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SCRIPT_ENGINE_INJECTION - subcategory: - - audit - technology: - - java - patterns: - - pattern-either: - - pattern-inside: | - class $CLASS { - ... - ScriptEngine $SE; - ... - } - - pattern-inside: | - class $CLASS { - ... - ScriptEngine $SE = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - ScriptEngine $SE = ...; - ... - } - - pattern: | - $X $METHOD(...) { - ... - $SE.eval(...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $SE.eval("..."); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $SE.eval($S); - ... - } - severity: WARNING - - id: java.lang.security.audit.sqli.hibernate-sqli.hibernate-sqli - languages: - - java - message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. - metadata: - asvs: - control_id: 5.3.5 Insecure Custom Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: V5 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SQL_INJECTION_HIBERNATE - subcategory: - - audit - technology: - - hibernate - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - String $SQL = $X + $Y; - ... - - pattern-inside: | - String $SQL = String.format(...); - ... - - pattern-inside: | - $VAL $FUNC(...,String $SQL,...) { - ... - } - - pattern-not-inside: | - String $SQL = "..." + "..."; - ... - - pattern: org.hibernate.criterion.Restrictions.sqlRestriction($SQL,...) - - pattern: org.hibernate.criterion.Restrictions.sqlRestriction(String.format(...),...) - - patterns: - - pattern: org.hibernate.criterion.Restrictions.sqlRestriction($X + $Y,...) - - pattern-not: org.hibernate.criterion.Restrictions.sqlRestriction("..." + "...",...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - String $SQL = $X + $Y; - ... - - pattern-inside: | - String $SQL = String.format(...); - ... - - pattern-inside: | - $TYPE $FUNC(...,String $SQL,...) { - ... - } - - pattern-not-inside: | - String $SQL = "..." + "..."; - ... - - pattern: $SESSION.$METHOD($SQL,...) - - pattern: | - $SESSION.$METHOD(String.format(...),...); - - pattern: | - $SESSION.$METHOD($X + $Y,...); - - pattern-either: - - pattern-inside: | - org.hibernate.Session $SESSION = ...; - ... - - pattern-inside: | - $TYPE $FUNC(...,org.hibernate.Session $SESSION,...) { - ... - } - - pattern-not: | - $SESSION.$METHOD("..." + "...",...); - - metavariable-regex: - metavariable: $METHOD - regex: ^(createQuery|createSQLQuery)$ - severity: WARNING - - id: java.lang.security.audit.sqli.jdbc-sqli.jdbc-sqli - languages: - - java - message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - jdbc - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - String $SQL = $X + $Y; - ... - - pattern-inside: | - String $SQL = String.format(...); - ... - - pattern-inside: | - $VAL $FUNC(...,String $SQL,...) { - ... - } - - pattern-not-inside: | - String $SQL = "..." + "..."; - ... - - pattern: $S.$METHOD($SQL,...) - - pattern: | - $S.$METHOD(String.format(...),...); - - pattern: | - $S.$METHOD($X + $Y,...); - - pattern-either: - - pattern-inside: | - java.sql.Statement $S = ...; - ... - - pattern-inside: | - $TYPE $FUNC(...,java.sql.Statement $S,...) { - ... - } - - pattern-not: | - $S.$METHOD("..." + "...",...); - - metavariable-regex: - metavariable: $METHOD - regex: ^(executeQuery|execute|executeUpdate|executeLargeUpdate|addBatch|nativeSQL)$ - severity: WARNING - - id: java.lang.security.audit.sqli.jdo-sqli.jdo-sqli - languages: - - java - message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - java - pattern-either: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - String $SQL = $X + $Y; - ... - - pattern-inside: | - String $SQL = String.format(...); - ... - - pattern-inside: | - $TYPE $FUNC(...,String $SQL,...) { - ... - } - - pattern-not-inside: | - String $SQL = "..." + "..."; - ... - - pattern: $Q.$METHOD($SQL,...) - - pattern: | - $Q.$METHOD(String.format(...),...); - - pattern: | - $Q.$METHOD($X + $Y,...); - - pattern-either: - - pattern-inside: | - javax.jdo.Query $Q = ...; - ... - - pattern-inside: | - $TYPE $FUNC(...,javax.jdo.Query $Q,...) { - ... - } - - pattern-not: | - $Q.$METHOD("..." + "...",...); - - metavariable-regex: - metavariable: $METHOD - regex: ^(setFilter|setGrouping)$ - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - String $SQL = $X + $Y; - ... - - pattern-inside: | - String $SQL = String.format(...); - ... - - pattern-inside: | - $VAL $FUNC(...,String $SQL,...) { - ... - } - - pattern-not-inside: | - String $SQL = "..." + "..."; - ... - - pattern: $PM.newQuery(...,$SQL,...) - - pattern: | - $PM.newQuery(...,String.format(...),...); - - pattern: | - $PM.newQuery(...,$X + $Y,...); - - pattern-either: - - pattern-inside: | - javax.jdo.PersistenceManager $PM = ...; - ... - - pattern-inside: | - $TYPE $FUNC(...,javax.jdo.PersistenceManager $PM,...) { - ... - } - - pattern-not: | - $PM.newQuery(...,"..." + "...",...); - severity: WARNING - - id: java.lang.security.audit.sqli.jpa-sqli.jpa-sqli - languages: - - java - message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - jpa - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - String $SQL = $X + $Y; - ... - - pattern-inside: | - String $SQL = String.format(...); - ... - - pattern-inside: | - $TYPE $FUNC(...,String $SQL,...) { - ... - } - - pattern-not-inside: | - String $SQL = "..." + "..."; - ... - - pattern: $EM.$METHOD($SQL,...) - - pattern: | - $EM.$METHOD(String.format(...),...); - - pattern: | - $EM.$METHOD($X + $Y,...); - - pattern-either: - - pattern-inside: | - EntityManager $EM = ...; - ... - - pattern-inside: | - $TYPE $FUNC(...,EntityManager $EM,...) { - ... - } - - pattern-not: | - $EM.$METHOD("..." + "...",...); - - metavariable-regex: - metavariable: $METHOD - regex: ^(createQuery|createNativeQuery)$ - severity: WARNING - - id: java.lang.security.audit.sqli.tainted-sql-from-http-request.tainted-sql-from-http-request - languages: - - java - message: Detected input from a HTTPServletRequest going into a SQL sink or statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use parameterized SQL queries or properly sanitize user input instead. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html - - https://owasp.org/www-community/attacks/SQL_Injection - subcategory: - - vuln - technology: - - sql - - java - - servlets - - spring - mode: taint - options: - taint_assume_safe_booleans: true - taint_assume_safe_numbers: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: "(java.sql.CallableStatement $STMT) = ...; \n" - - pattern: | - (java.sql.Statement $STMT) = ...; - ... - $OUTPUT = $STMT.$FUNC(...); - - pattern: | - (java.sql.PreparedStatement $STMT) = ...; - - pattern: | - $VAR = $CONN.prepareStatement(...) - - pattern: | - $PATH.queryForObject(...); - - pattern: | - (java.util.Map $STMT) = $PATH.queryForMap(...); - - pattern: | - (org.springframework.jdbc.support.rowset.SqlRowSet $STMT) = ...; - - pattern: | - (org.springframework.jdbc.core.JdbcTemplate $TEMPL).batchUpdate(...) - - patterns: - - pattern-inside: | - (String $SQL) = "$SQLSTR" + ...; - ... - - pattern: $PATH.$SQLCMD(..., $SQL, ...); - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(^SELECT.* | ^INSERT.* | ^UPDATE.*) - - metavariable-regex: - metavariable: $SQLCMD - regex: (execute|query|executeUpdate|batchUpdate) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ).$REQFUNC(...) - - pattern: "(ServletRequest $REQ).$REQFUNC(...) \n" - - metavariable-regex: - metavariable: $REQFUNC - regex: (getInputStream|getParameter|getParameterMap|getParameterValues|getReader|getCookies|getHeader|getHeaderNames|getHeaders|getPart|getParts|getQueryString) - severity: WARNING - - id: java.lang.security.audit.sqli.turbine-sqli.turbine-sqli - languages: - - java - message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - turbine - pattern-either: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - String $SQL = $X + $Y; - ... - - pattern-inside: | - String $SQL = String.format(...); - ... - - pattern-inside: | - $VAL $FUNC(...,String $SQL,...) { - ... - } - - pattern-not-inside: | - String $SQL = "..." + "..."; - ... - - pattern: $PEER.executeQuery($SQL,...) - - pattern: | - $PEER.executeQuery(String.format(...),...) - - pattern: | - $PEER.executeQuery($X + $Y,...) - - pattern-not: | - $PEER.executeQuery("..." + "...",...) - - metavariable-regex: - metavariable: $PEER - regex: (BasePeer|GroupPeer) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - String $SQL = $X + $Y; - ... - - pattern-inside: | - String $SQL = String.format(...); - ... - - pattern-inside: | - $VAL $FUNC(...,String $SQL,...) { - ... - } - - pattern-not-inside: | - String $SQL = "..." + "..."; - ... - - pattern: $P.executeQuery($SQL,...) - - pattern: | - $P.executeQuery(String.format(...),...) - - pattern: | - $P.executeQuery($X + $Y,...) - - pattern-either: - - pattern-inside: | - BasePeer $P = ...; - ... - - pattern-inside: | - GroupPeer $P = ...; - ... - - pattern-inside: | - $VAL $FUNC(...,GroupPeer $P,...) { - ... - } - - pattern-inside: | - $VAL $FUNC(...,BasePeer $P,...) { - ... - } - - pattern-not: | - $P.executeQuery("..." + "...",...) - severity: WARNING - - id: java.lang.security.audit.sqli.vertx-sqli.vertx-sqli - languages: - - java - message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - vertx - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - String $SQL = $X + $Y; - ... - - pattern-inside: | - String $SQL = String.format(...); - ... - - pattern-inside: | - $TYPE $FUNC(...,String $SQL,...) { - ... - } - - pattern-not-inside: | - String $SQL = "..." + "..."; - ... - - pattern: $SC.$METHOD($SQL,...) - - pattern: | - $SC.$METHOD(String.format(...),...); - - pattern: | - $SC.$METHOD($X + $Y,...); - - pattern-either: - - pattern-inside: | - SqlClient $SC = ...; - ... - - pattern-inside: | - SqlConnection $SC = ...; - ... - - pattern-inside: | - $TYPE $FUNC(...,SqlClient $SC,...) { - ... - } - - pattern-inside: | - $TYPE $FUNC(...,SqlConnection $SC,...) { - ... - } - - pattern-not: | - $SC.$METHOD("..." + "...",...); - - metavariable-regex: - metavariable: $METHOD - regex: ^(query|preparedQuery|prepare)$ - severity: WARNING - - id: java.lang.security.audit.tainted-cmd-from-http-request.tainted-cmd-from-http-request - languages: - - java - message: Detected input from a HTTPServletRequest going into a 'ProcessBuilder' or 'exec' command. This could lead to command injection if variables passed into the exec commands are not properly sanitized. Instead, avoid using these OS commands with user-supplied input, or, if you must use these commands, use a whitelist of specific values. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (ProcessBuilder $PB) = ...; - - patterns: - - pattern: | - (Process $P) = ...; - - pattern-not: | - (Process $P) = (java.lang.Runtime $R).exec(...); - - patterns: - - pattern: (java.lang.Runtime $R).exec($CMD, ...); - - focus-metavariable: $CMD - - patterns: - - pattern-either: - - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(ProcessBuilder $PB) = ...;\n...\n$PB.command($ARGLIST);\n" - - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(ProcessBuilder $PB) = ...;\n" - - pattern-inside: "(java.util.List<$TYPE> $ARGLIST) = ...; \n...\n(Process $P) = ...;\n" - - pattern: | - $ARGLIST.add(...); - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); - ... - for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { - ... - } - - pattern: | - $COOKIE.getValue(...) - severity: ERROR - - id: java.lang.security.audit.tainted-env-from-http-request.tainted-env-from-http-request - languages: - - java - message: Detected input from a HTTPServletRequest going into the environment variables of an 'exec' command. Instead, call the command with user-supplied arguments by using the overloaded method with one String array as the argument. `exec({"command", "arg1", "arg2"})`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-454: External Initialization of Trusted Variables or Data Stores' - cwe2021-top25: false - cwe2022-top25: false - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern: (java.lang.Runtime $R).exec($CMD, $ENV_ARGS, ...); - - focus-metavariable: $ENV_ARGS - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); - ... - for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { - ... - } - - pattern: | - $COOKIE.getValue(...) - severity: ERROR - - id: java.lang.security.audit.tainted-ldapi-from-http-request.tainted-ldapi-from-http-request - languages: - - java - message: Detected input from a HTTPServletRequest going into an LDAP query. This could lead to LDAP injection if the input is not properly sanitized, which could result in attackers modifying objects in the LDAP tree structure. Ensure data passed to an LDAP query is not controllable or properly sanitize the data. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-90: Improper Neutralization of Special Elements used in an LDAP Query (''LDAP Injection'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://sensei.securecodewarrior.com/recipes/scw%3Ajava%3ALDAP-injection - subcategory: - - vuln - technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (javax.naming.directory.InitialDirContext $IDC).search(...) - - pattern: | - (javax.naming.directory.DirContext $CTX).search(...) - - pattern-not: | - (javax.naming.directory.InitialDirContext $IDC).search($Y, "...", ...) - - pattern-not: | - (javax.naming.directory.DirContext $CTX).search($Y, "...", ...) - pattern-sources: - - patterns: - - pattern: (HttpServletRequest $REQ) - severity: WARNING - - id: java.lang.security.audit.tainted-session-from-http-request.tainted-session-from-http-request - languages: - - java - message: Detected input from a HTTPServletRequest going into a session command, like `setAttribute`. User input into such a command could lead to an attacker inputting malicious code into your session parameters, blurring the line between what's trusted and untrusted, and therefore leading to a trust boundary violation. This could lead to programmers trusting unvalidated data. Instead, thoroughly sanitize user input before passing it into such function calls. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-501: Trust Boundary Violation' - impact: MEDIUM - interfile: true - likelihood: MEDIUM - owasp: - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - vuln - technology: - - java - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern: (HttpServletRequest $REQ).getSession().$FUNC($NAME, $VALUE); - - metavariable-regex: - metavariable: $FUNC - regex: ^(putValue|setAttribute)$ - - focus-metavariable: $VALUE - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern: | - (HttpServletRequest $REQ).$FUNC(...) - - pattern-not: | - (HttpServletRequest $REQ).getSession() - - patterns: - - pattern-inside: | - (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); - ... - for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { - ... - } - - pattern: | - $COOKIE.getValue(...) - - patterns: - - pattern-inside: | - $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(... ); - ... - - pattern: | - $PARAM = $VALS[$INDEX]; - - patterns: - - pattern-inside: | - $HEADERS = (HttpServletRequest $REQ).getHeaders(...); - ... - $PARAM = $HEADERS.$FUNC(...); - ... - - pattern: | - java.net.URLDecoder.decode($PARAM, ...) - severity: WARNING - - id: java.lang.security.audit.tainted-xpath-from-http-request.tainted-xpath-from-http-request - languages: - - java - message: Detected input from a HTTPServletRequest going into a XPath evaluate or compile command. This could lead to xpath injection if variables passed into the evaluate or compile commands are not properly sanitized. Xpath injection could lead to unauthorized access to sensitive information in XML documents. Instead, thoroughly sanitize user input or use parameterized xpath queries if you can. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-643: Improper Neutralization of Data within XPath Expressions (''XPath Injection'')' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (javax.xml.xpath.XPath $XP).evaluate(...) - - pattern: | - (javax.xml.xpath.XPath $XP).compile(...).evaluate(...) - pattern-sources: - - patterns: - - pattern: | - (HttpServletRequest $REQ).$FUNC(...) - severity: WARNING - - id: java.lang.security.audit.unsafe-reflection.unsafe-reflection - languages: - - java - message: If an attacker can supply values that the application then uses to determine which class to instantiate or which method to invoke, the potential exists for the attacker to create control flow paths through the application that were not intended by the application developers. This attack vector may allow the attacker to bypass authentication or access control checks or otherwise cause the application to behave in an unexpected manner. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-470: Use of Externally-Controlled Input to Select Classes or Code (''Unsafe Reflection'')' - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://owasp.org/www-community/vulnerabilities/Unsafe_use_of_Reflection - subcategory: - - audit - technology: - - java - patterns: - - pattern: | - Class.forName($CLASS,...) - - pattern-not: | - Class.forName("...",...) - - pattern-not-inside: | - $CLASS = "..."; - ... - severity: WARNING - - id: java.lang.security.audit.unvalidated-redirect.unvalidated-redirect - languages: - - java - message: Application redirects to a destination URL specified by a user-supplied parameter that is not validated. This could direct users to malicious locations. Consider using an allowlist to validate URLs. - metadata: - asvs: - control_id: 5.1.5 Open Redirect - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: LOW - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNVALIDATED_REDIRECT - subcategory: - - vuln - technology: - - java - pattern-either: - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...,String $URL,...) { - ... - $RES.sendRedirect($URL); - ... - } - - pattern: | - $X $METHOD(...,String $URL,...,HttpServletResponse $RES,...) { - ... - $RES.sendRedirect($URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { - ... - String $URL = $REQ.getParameter(...); - ... - $RES.sendRedirect($URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { - ... - String $URL = $REQ.getParameter(...); - ... - $RES.sendRedirect($URL); - ... - } - - pattern: | - $X $METHOD(...,String $URL,...) { - ... - HttpServletResponse $RES = ...; - ... - $RES.sendRedirect($URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { - ... - $RES.sendRedirect($REQ.getParameter(...)); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { - ... - $RES.sendRedirect($REQ.getParameter(...)); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...,String $URL,...) { - ... - $RES.addHeader("Location",$URL); - ... - } - - pattern: | - $X $METHOD(...,String $URL,...,HttpServletResponse $RES,...) { - ... - $RES.addHeader("Location",$URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { - ... - String $URL = $REQ.getParameter(...); - ... - $RES.addHeader("Location",$URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { - ... - String $URL = $REQ.getParameter(...); - ... - $RES.addHeader("Location",$URL); - ... - } - - pattern: | - $X $METHOD(...,String $URL,...) { - ... - HttpServletResponse $RES = ...; - ... - $RES.addHeader("Location",$URL); - ... - } - - pattern: | - $X $METHOD(...,HttpServletRequest $REQ,...,HttpServletResponse $RES,...) { - ... - $RES.addHeader("Location",$REQ.getParameter(...)); - ... - } - - pattern: |- - $X $METHOD(...,HttpServletResponse $RES,...,HttpServletRequest $REQ,...) { - ... - $RES.addHeader("Location",$REQ.getParameter(...)); - ... - } - severity: WARNING - - id: java.lang.security.audit.url-rewriting.url-rewriting - languages: - - java - message: URL rewriting has significant security risks. Since session ID appears in the URL, it may be easily seen by third parties. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#URL_REWRITING - subcategory: - - vuln - technology: - - java - pattern-either: - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...) { - ... - $RES.encodeURL(...); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...) { - ... - $RES.encodeUrl(...); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...) { - ... - $RES.encodeRedirectURL(...); - ... - } - - pattern: | - $X $METHOD(...,HttpServletResponse $RES,...) { - ... - $RES.encodeRedirectUrl(...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - HttpServletResponse $RES = ...; - ... - $RES.encodeURL(...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - HttpServletResponse $RES = ...; - ... - $RES.encodeUrl(...); - ... - } - - pattern: | - $X $METHOD(...) { - ... - HttpServletResponse $RES = ...; - ... - $RES.encodeRedirectURL(...); - ... - } - - pattern: |- - $X $METHOD(...) { - ... - HttpServletResponse $RES = ...; - ... - $RES.encodeRedirectUrl(...); - ... - } - severity: WARNING - - fix-regex: - regex: (.*?)\.getInstance\(.*?\) - replacement: \1.getInstance("TLSv1.2") - id: java.lang.security.audit.weak-ssl-context.weak-ssl-context - languages: - - java - message: An insecure SSL context was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use SSLContext.getInstance("TLSv1.2") for the best security. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://tools.ietf.org/html/rfc7568 - - https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html - source_rule_url: https://find-sec-bugs.github.io/bugs.htm#SSL_CONTEXT - subcategory: - - audit - technology: - - java - patterns: - - pattern-not: SSLContext.getInstance("TLSv1.3") - - pattern-not: SSLContext.getInstance("TLSv1.2") - - pattern: SSLContext.getInstance("...") - severity: WARNING - - id: java.lang.security.audit.xml-decoder.xml-decoder - languages: - - java - message: XMLDecoder should not be used to parse untrusted data. Deserializing user input can lead to arbitrary code execution. Use an alternative and explicitly disable external entities. See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html for alternatives and vulnerability prevention. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#XML_DECODER - subcategory: - - audit - technology: - - java - patterns: - - pattern: | - $X $METHOD(...) { - ... - new XMLDecoder(...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - new XMLDecoder("..."); - ... - } - - pattern-not: |- - $X $METHOD(...) { - ... - String $STR = "..."; - ... - new XMLDecoder($STR); - ... - } - severity: WARNING - - id: java.lang.security.audit.xss.jsf.autoescape-disabled.autoescape-disabled - languages: - - regex - message: Detected an element with disabled HTML escaping. If external data can reach this, this is a cross-site scripting (XSS) vulnerability. Ensure no external data can reach here, or remove 'escape=false' from this element. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-150: Improper Neutralization of Escape, Meta, or Control Sequences' - impact: MEDIUM - likelihood: LOW - owasp: A07:2017 - Cross-Site Scripting (XSS) - references: - - https://stackoverflow.com/a/7442668 - subcategory: - - audit - technology: - - jsf - paths: - include: - - '*.html' - - '*.xhtml' - pattern-regex: .*escape.*?=.*?false.* - severity: WARNING - - id: java.lang.security.audit.xss.jsp.no-scriptlets.no-scriptlets - languages: - - regex - message: JSP scriptlet detected. Scriptlets are difficult to use securely and are considered bad practice. See https://stackoverflow.com/a/3180202. Instead, consider migrating to JSF or using the Expression Language '${...}' with the escapeXml function in your JSP files. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-116: Improper Encoding or Escaping of Output' - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://stackoverflow.com/a/3180202 - - https://stackoverflow.com/a/4948856 - subcategory: - - audit - technology: - - jsp - paths: - include: - - '*.jsp' - pattern-regex: \<\%[^\@].* - severity: WARNING - - id: java.lang.security.audit.xss.jsp.use-escapexml.use-escapexml - languages: - - regex - message: Detected an Expression Language segment that does not escape output. This is dangerous because if any data in this expression can be controlled externally, it is a cross-site scripting vulnerability. Instead, use the 'escapeXml' function from the JSTL taglib. See https://www.tutorialspoint.com/jsp/jstl_function_escapexml.htm for more information. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-116: Improper Encoding or Escaping of Output' - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://www.tutorialspoint.com/jsp/jstl_function_escapexml.htm - - https://stackoverflow.com/a/4948856 - - https://stackoverflow.com/a/3180202 - subcategory: - - audit - technology: - - jsp - paths: - include: - - '*.jsp' - pattern-regex: \$\{(?!.*escapeXml).*\} - severity: WARNING - - id: java.lang.security.audit.xss.jsp.use-jstl-escaping.use-jstl-escaping - languages: - - regex - message: Detected an Expression Language segment in a tag that does not escape output. This is dangerous because if any data in this expression can be controlled externally, it is a cross-site scripting vulnerability. Instead, use the 'out' tag from the JSTL taglib to escape this expression. See https://www.tutorialspoint.com/jsp/jstl_core_out_tag.htm for more information. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-116: Improper Encoding or Escaping of Output' - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://www.tutorialspoint.com/jsp/jstl_core_out_tag.htm - - https://stackoverflow.com/a/4948856 - - https://stackoverflow.com/a/3180202 - subcategory: - - audit - technology: - - jsp - paths: - include: - - '*.jsp' - pattern-regex: <(?![A-Za-z0-9]+:out).*?\$\{.*?\}.*> - severity: WARNING - - id: java.lang.security.audit.xss.no-direct-response-writer.no-direct-response-writer - languages: - - java - message: Detected a request with potential user-input going into a OutputStream or Writer object. This bypasses any view or template environments, including HTML escaping, which may expose this application to cross-site scripting (XSS) vulnerabilities. Consider using a view technology such as JavaServer Faces (JSFs) which automatically escapes HTML views. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - license: proprietary license - copyright © Semgrep, Inc. - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaServerFaces.html - subcategory: - - vuln - technology: - - java - - servlets - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern-either: - - pattern: Encode.forHtml(...) - - pattern: (PolicyFactory $POLICY).sanitize(...) - - pattern: (AntiSamy $AS).scan(...) - - pattern: JSoup.clean(...) - - pattern: org.apache.commons.lang.StringEscapeUtils.escapeHtml(...) - - pattern: org.springframework.web.util.HtmlUtils.htmlEscape(...) - - pattern: org.owasp.esapi.ESAPI.encoder().encodeForHTML(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (HttpServletResponse $RESPONSE).getWriter(...).$WRITE(...) - - pattern: | - (HttpServletResponse $RESPONSE).getOutputStream(...).$WRITE(...) - - pattern: | - (java.io.PrintWriter $WRITER).$WRITE(...) - - pattern: | - (PrintWriter $WRITER).$WRITE(...) - - pattern: | - (javax.servlet.ServletOutputStream $WRITER).$WRITE(...) - - pattern: | - (ServletOutputStream $WRITER).$WRITE(...) - - pattern: | - (java.io.OutputStream $WRITER).$WRITE(...) - - pattern: | - (OutputStream $WRITER).$WRITE(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ).$REQFUNC(...) - - pattern: "(ServletRequest $REQ).$REQFUNC(...) \n" - - metavariable-regex: - metavariable: $REQFUNC - regex: (getInputStream|getParameter|getParameterMap|getParameterValues|getReader|getCookies|getHeader|getHeaderNames|getHeaders|getPart|getParts|getQueryString) - severity: WARNING - - id: java.lang.security.audit.xssrequestwrapper-is-insecure.xssrequestwrapper-is-insecure - languages: - - java - message: It looks like you're using an implementation of XSSRequestWrapper from dzone. (https://www.javacodegeeks.com/2012/07/anti-cross-site-scripting-xss-filter.html) The XSS filtering in this code is not secure and can be bypassed by malicious actors. It is recommended to use a stack that automatically escapes in your view or templates instead of filtering yourself. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#XSS_REQUEST_WRAPPER - subcategory: - - audit - technology: - - java - pattern-either: - - pattern: | - class XSSRequestWrapper extends HttpServletRequestWrapper { - ... - } - - pattern: |- - $P = $X.compile("", $X.CASE_INSENSITIVE); - $V = $P.matcher(...).replaceAll(""); - severity: WARNING - - id: java.lang.security.audit.xxe.documentbuilderfactory-disallow-doctype-decl-false.documentbuilderfactory-disallow-doctype-decl-false - languages: - - java - message: DOCTYPE declarations are enabled for $DBFACTORY. Without prohibiting external entity declarations, this is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false. - metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html - subcategory: - - vuln - technology: - - java - - xml - patterns: - - pattern: $DBFACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false); - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - } - severity: ERROR - - fix: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - $FACTORY.newDocumentBuilder(); - id: java.lang.security.audit.xxe.documentbuilderfactory-disallow-doctype-decl-missing.documentbuilderfactory-disallow-doctype-decl-missing - languages: - - java - message: DOCTYPE declarations are enabled for this DocumentBuilderFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false. - metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html - subcategory: - - vuln - technology: - - java - - xml - mode: taint - pattern-sanitizers: - - by-side-effect: true - pattern-either: - - patterns: - - pattern-either: - - pattern: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - - focus-metavariable: $FACTORY - - patterns: - - pattern-either: - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", - true); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); - ... - } - ... - } - - pattern: $M($X) - - focus-metavariable: $X - pattern-sinks: - - patterns: - - pattern: $FACTORY.newDocumentBuilder(); - pattern-sources: - - by-side-effect: true - patterns: - - pattern-either: - - pattern: | - $FACTORY = DocumentBuilderFactory.newInstance(); - - patterns: - - pattern: $FACTORY - - pattern-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - severity: ERROR - - fix: $DBFACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - id: java.lang.security.audit.xxe.documentbuilderfactory-external-general-entities-true.documentbuilderfactory-external-general-entities-true - languages: - - java - message: External entities are allowed for $DBFACTORY. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://xml.org/sax/features/external-general-entities" to false. - metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - subcategory: - - vuln - technology: - - java - - xml - pattern: $DBFACTORY.setFeature("http://xml.org/sax/features/external-general-entities", true); - severity: ERROR - - fix: $DBFACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - id: java.lang.security.audit.xxe.documentbuilderfactory-external-parameter-entities-true.documentbuilderfactory-external-parameter-entities-true - languages: - - java - message: External entities are allowed for $DBFACTORY. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://xml.org/sax/features/external-parameter-entities" to false. - metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - subcategory: - - vuln - technology: - - java - - xml - pattern: $DBFACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", true); - severity: ERROR - - fix: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - $FACTORY.newSAXParser(); - id: java.lang.security.audit.xxe.saxparserfactory-disallow-doctype-decl-missing.saxparserfactory-disallow-doctype-decl-missing - languages: - - java - message: DOCTYPE declarations are enabled for this SAXParserFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature `http://apache.org/xml/features/disallow-doctype-decl` to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features `http://xml.org/sax/features/external-general-entities` and `http://xml.org/sax/features/external-parameter-entities` to false. NOTE - The previous links are not meant to be clicked. They are the literal config key values that are supposed to be used to disable these features. For more information, see https://semgrep.dev/docs/cheat-sheets/java-xxe/#3a-documentbuilderfactory. - metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html - subcategory: - - vuln - technology: - - java - - xml - mode: taint - pattern-sanitizers: - - by-side-effect: true - pattern-either: - - patterns: - - pattern-either: - - pattern: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - - focus-metavariable: $FACTORY - - patterns: - - pattern-either: - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", - true); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); - ... - } - ... - } - - pattern: $M($X) - - focus-metavariable: $X - pattern-sinks: - - patterns: - - pattern: $FACTORY.newSAXParser(); - pattern-sources: - - by-side-effect: true - patterns: - - pattern-either: - - pattern: | - $FACTORY = SAXParserFactory.newInstance(); - - patterns: - - pattern: $FACTORY - - pattern-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - severity: ERROR - - fix: | - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - $FACTORY.newTransformer(...); - id: java.lang.security.audit.xxe.transformerfactory-dtds-not-disabled.transformerfactory-dtds-not-disabled - languages: - - java - message: DOCTYPE declarations are enabled for this TransformerFactory. This is vulnerable to XML external entity attacks. Disable this by setting the attributes "accessExternalDTD" and "accessExternalStylesheet" to "". - metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html - subcategory: - - vuln - technology: - - java - - xml - mode: taint - pattern-sanitizers: - - by-side-effect: true - pattern-either: - - patterns: - - pattern-either: - - pattern: | - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - - pattern: | - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - - pattern: | - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - - pattern: | - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - - focus-metavariable: $FACTORY - - patterns: - - pattern-either: - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - } - ... - } - - pattern: $M($X) - - focus-metavariable: $X - pattern-sinks: - - patterns: - - pattern: $FACTORY.newTransformer(...); - pattern-sources: - - by-side-effect: true - patterns: - - pattern-either: - - pattern: | - $FACTORY = TransformerFactory.newInstance(); - - patterns: - - pattern: $FACTORY - - pattern-inside: | - class $C { - ... - $V $FACTORY = TransformerFactory.newInstance(); - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - } - ... - } - severity: ERROR - - id: java.lang.security.do-privileged-use.do-privileged-use - languages: - - java - message: Marking code as privileged enables a piece of trusted code to temporarily enable access to more resources than are available directly to the code that called it. Be very careful in your use of the privileged construct, and always remember to make the privileged code section as small as possible. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-269: Improper Privilege Management' - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://docs.oracle.com/javase/8/docs/technotes/guides/security/doprivileged.html - - https://wiki.sei.cmu.edu/confluence/display/java/Privilege+Escalation - - http://phrack.org/papers/escaping_the_java_sandbox.html - subcategory: - - audit - technology: - - java - patterns: - - pattern-inside: | - import java.security.*; - ... - - pattern-either: - - pattern: AccessController.doPrivileged(...); - - pattern: class $ACTION implements PrivilegedAction { ... } - severity: WARNING - - id: java.lang.security.httpservlet-path-traversal.httpservlet-path-traversal - languages: - - java - message: Detected a potential path traversal. A malicious actor could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://www.owasp.org/index.php/Path_Traversal - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN - subcategory: - - vuln - technology: - - java - mode: taint - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (java.io.File $FILE) = ... - - pattern: | - (java.io.FileOutputStream $FOS) = ... - - pattern: | - new java.io.FileInputStream(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); - ... - for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { - ... - } - - pattern: | - $COOKIE.getValue(...) - - patterns: - - pattern-inside: | - $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(...); - ... - - pattern: | - $PARAM = $VALS[$INDEX]; - severity: ERROR - - id: java.lang.security.insecure-jms-deserialization.insecure-jms-deserialization - languages: - - java - message: JMS Object messages depend on Java Serialization for marshalling/unmarshalling of the message payload when ObjectMessage.getObject() is called. Deserialization of untrusted data can lead to security flaws; a remote attacker could via a crafted JMS ObjectMessage to execute arbitrary code with the permissions of the application listening/consuming JMS Messages. In this case, the JMS MessageListener consume an ObjectMessage type received inside the onMessage method, which may lead to arbitrary code execution when calling the $Y.getObject method. - metadata: - asvs: - control_id: 5.5.3 Insecue Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities-wp.pdf - subcategory: - - vuln - technology: - - java - patterns: - - pattern-inside: | - public class $JMS_LISTENER implements MessageListener { - ... - public void onMessage(Message $JMS_MSG) { - ... - } - } - - pattern-either: - - pattern-inside: $X = $Y.getObject(...); - - pattern-inside: $X = ($Z) $Y.getObject(...); - severity: WARNING - - id: java.lang.security.jackson-unsafe-deserialization.jackson-unsafe-deserialization - languages: - - java - message: When using Jackson to marshall/unmarshall JSON to Java objects, enabling default typing is dangerous and can lead to RCE. If an attacker can control `$JSON` it might be possible to provide a malicious JSON which can be used to exploit unsecure deserialization. In order to prevent this issue, avoid to enable default typing (globally or by using "Per-class" annotations) and avoid using `Object` and other dangerous types for member variable declaration which creating classes for Jackson based deserialization. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - impact: HIGH - likelihood: LOW - owasp: - - A8:2017 Insecure Deserialization - - A8:2021 Software and Data Integrity Failures - references: - - https://swapneildash.medium.com/understanding-insecure-implementation-of-jackson-deserialization-7b3d409d2038 - - https://cowtowncoder.medium.com/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062 - - https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/ - subcategory: - - audit - technology: - - jackson - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - ObjectMapper $OM = new ObjectMapper(...); - ... - - pattern-inside: | - $OM.enableDefaultTyping(); - ... - - pattern: $OM.readValue($JSON, ...); - - patterns: - - pattern-inside: | - class $CLASS { - ... - @JsonTypeInfo(use = Id.CLASS,...) - $TYPE $VAR; - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: (Object|Serializable|Comparable) - - pattern: $OM.readValue($JSON, $CLASS.class); - - patterns: - - pattern-inside: | - class $CLASS { - ... - ObjectMapper $OM; - ... - $INITMETHODTYPE $INITMETHOD(...) { - ... - $OM = new ObjectMapper(); - ... - $OM.enableDefaultTyping(); - ... - } - ... - } - - pattern-inside: "$METHODTYPE $METHOD(...) {\n ... \n}\n" - - pattern: $OM.readValue($JSON, ...); - severity: WARNING - - id: java.lang.security.servletresponse-writer-xss.servletresponse-writer-xss - languages: - - java - message: 'Cross-site scripting detected in HttpServletResponse writer with variable ''$VAR''. User input was detected going directly from the HttpServletRequest into output. Ensure your data is properly encoded using org.owasp.encoder.Encode.forHtml: ''Encode.forHtml($VAR)''.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#XSS_SERVLET - subcategory: - - vuln - technology: - - java - patterns: - - pattern-inside: $TYPE $FUNC(..., HttpServletResponse $RESP, ...) { ... } - - pattern-inside: $VAR = $REQ.getParameter(...); ... - - pattern-either: - - pattern: $RESP.getWriter(...).write(..., $VAR, ...); - - pattern: | - $WRITER = $RESP.getWriter(...); - ... - $WRITER.write(..., $VAR, ...); - severity: ERROR - - id: java.lang.security.use-snakeyaml-constructor.use-snakeyaml-constructor - languages: - - java - message: Used SnakeYAML org.yaml.snakeyaml.Yaml() constructor with no arguments, which is vulnerable to deserialization attacks. Use the one-argument Yaml(...) constructor instead, with SafeConstructor or a custom Constructor as the argument. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://securitylab.github.com/research/swagger-yaml-parser-vulnerability/#snakeyaml-deserialization-vulnerability - subcategory: - - audit - technology: - - snakeyaml - patterns: - - pattern: | - $Y = new org.yaml.snakeyaml.Yaml(); - ... - $Y.load(...); - severity: WARNING - - id: java.lang.security.xmlinputfactory-external-entities-enabled.xmlinputfactory-external-entities-enabled - languages: - - java - message: XML external entities are enabled for this XMLInputFactory. This is vulnerable to XML external entity attacks. Disable external entities by setting "javax.xml.stream.isSupportingExternalEntities" to false. - metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf - subcategory: - - audit - technology: - - java - patterns: - - pattern-either: - - pattern: (javax.xml.stream.XMLInputFactory $XMLFACTORY).setProperty("javax.xml.stream.isSupportingExternalEntities", true); - - pattern: (javax.xml.stream.XMLInputFactory $XMLFACTORY).setProperty(javax.xml.stream.XMLInputFactory.SUPPORT_DTD, true); - - pattern: (javax.xml.stream.XMLInputFactory $XMLFACTORY).setProperty("javax.xml.stream.isSupportingExternalEntities", Boolean.TRUE); - - pattern: (javax.xml.stream.XMLInputFactory $XMLFACTORY).setProperty(javax.xml.stream.XMLInputFactory.SUPPORT_DTD, Boolean.TRUE); - severity: ERROR - - id: java.lang.security.xmlinputfactory-possible-xxe.xmlinputfactory-possible-xxe - languages: - - java - message: XML external entities are not explicitly disabled for this XMLInputFactory. This could be vulnerable to XML external entity vulnerabilities. Explicitly disable external entities by setting "javax.xml.stream.isSupportingExternalEntities" to false. - metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#xmlinputfactory-a-stax-parser - subcategory: - - vuln - technology: - - java - patterns: - - pattern-not-inside: | - $METHOD(...) { - ... - $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", false); - ... - } - - pattern-not-inside: | - $METHOD(...) { - ... - $XMLFACTORY.setProperty(javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); - ... - } - - pattern-not-inside: | - $METHOD(...) { - ... - $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", Boolean.FALSE); - ... - } - - pattern-not-inside: | - $METHOD(...) { - ... - $XMLFACTORY.setProperty(javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); - ... - } - - pattern-either: - - pattern: javax.xml.stream.XMLInputFactory.newFactory(...) - - pattern: new XMLInputFactory(...) - severity: WARNING - - id: java.mongodb.security.injection.audit.mongodb-nosqli.mongodb-nosqli - languages: - - java - message: Detected non-constant data passed into a NoSQL query using the 'where' evaluation operator. If this data can be controlled by an external user, this is a NoSQL injection. Ensure data passed to the NoSQL query is not user controllable, or properly sanitize the data. Ideally, avoid using the 'where' operator at all and instead use the helper methods provided by com.mongodb.client.model.Filters with comparative operators such as eq, ne, lt, gt, etc. - metadata: - asvs: - control_id: 5.3.4 Injection Prevention - control_url: https://github.com/OWASP/ASVS/blob/master/5.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "5" - category: security - confidence: LOW - cwe: - - 'CWE-943: Improper Neutralization of Special Elements in Data Query Logic' - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - - https://www.mongodb.com/docs/manual/tutorial/query-documents/ - - https://www.mongodb.com/docs/manual/reference/operator/query/where/ - subcategory: - - audit - technology: - - nosql - - mongodb - patterns: - - pattern-either: - - pattern: (com.mongodb.BasicDBObject $QUERY).put("$where", $INPUT); - - pattern: | - (HashMap $MAP).put("$where", $INPUT); - ... - (com.mongodb.BasicDBObject $QUERY).putAll($MAP); - - pattern: (com.mongodb.BasicDBObject $QUERY).append("$where", $INPUT); - - pattern: new com.mongodb.BasicDBObject("$where", $INPUT); - - pattern: | - (HashMap $MAP).put("$where", $INPUT); - ... - new com.mongodb.BasicDBObject($MAP); - - pattern: | - (HashMap $MAP).put("$where", $INPUT); - ... - String json = new JSONObject($MAP).toString(); - ... - (com.mongodb.BasicDBObject $QUERY).parse((String $JSON)); - - pattern: com.mongodb.BasicDBObjectBuilder.start().add("$where", $INPUT); - - pattern: com.mongodb.BasicDBObjectBuilder.start().append("$where", $INPUT); - - pattern: com.mongodb.BasicDBObjectBuilder.start("$where", $INPUT); - - pattern: | - (HashMap $MAP).put("$where", $INPUT); - ... - com.mongodb.BasicDBObjectBuilder.start($MAP); - - metavariable-pattern: - metavariable: $INPUT - patterns: - - pattern: | - ... - - pattern-not: | - "..." - severity: WARNING - - id: java.rmi.security.server-dangerous-class-deserialization.server-dangerous-class-deserialization - languages: - - java - message: Using a non-primitive class with Java RMI may be an insecure deserialization vulnerability. Depending on the underlying implementation. This object could be manipulated by a malicious actor allowing them to execute code on your system. Instead, use an integer ID to look up your object, or consider alternative serialization schemes such as JSON. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://mogwailabs.de/blog/2019/03/attacking-java-rmi-services-after-jep-290/ - subcategory: - - audit - technology: - - rmi - patterns: - - pattern: | - interface $INTERFACE extends Remote { - $RETURNTYPE $METHOD($CLASS $PARAM) throws RemoteException; - } - - metavariable-regex: - metavariable: $CLASS - regex: (?!int|boolean|short|long|byte|char|float|double) - severity: WARNING - - id: java.rmi.security.server-dangerous-object-deserialization.server-dangerous-object-deserialization - languages: - - java - message: Using an arbitrary object ('$PARAMTYPE $PARAM') with Java RMI is an insecure deserialization vulnerability. This object can be manipulated by a malicious actor allowing them to execute code on your system. Instead, use an integer ID to look up your object, or consider alternative serialization schemes such as JSON. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://frohoff.github.io/appseccali-marshalling-pickles/ - - https://book.hacktricks.xyz/network-services-pentesting/1099-pentesting-java-rmi - - https://youtu.be/t_aw1mDNhzI - - https://github.com/qtc-de/remote-method-guesser - - https://github.com/openjdk/jdk/blob/master/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java#L303C4-L331 - subcategory: - - audit - technology: - - rmi - patterns: - - pattern: | - interface $INTERFACE extends Remote { - $RETURNTYPE $METHOD($PARAMTYPE $PARAM) throws RemoteException; - } - - metavariable-pattern: - language: generic - metavariable: $PARAMTYPE - patterns: - - pattern-not: String - - pattern-not: java.lang.String - - pattern-not: boolean - - pattern-not: Boolean - - pattern-not: java.lang.Boolean - - pattern-not: byte - - pattern-not: Byte - - pattern-not: java.lang.Byte - - pattern-not: char - - pattern-not: Character - - pattern-not: java.lang.Character - - pattern-not: double - - pattern-not: Double - - pattern-not: java.lang.Double - - pattern-not: float - - pattern-not: Float - - pattern-not: java.lang.Float - - pattern-not: int - - pattern-not: Integer - - pattern-not: java.lang.Integer - - pattern-not: long - - pattern-not: Long - - pattern-not: java.lang.Long - - pattern-not: short - - pattern-not: Short - - pattern-not: java.lang.Short - severity: ERROR - - fix: | - $COOKIE = new Cookie($...ARGS); - $COOKIE.setSecure(true); - id: java.servlets.security.cookie-issecure-false.cookie-issecure-false - languages: - - java - message: 'Default session middleware settings: `setSecure` not set to true. This ensures that the cookie is sent only over HTTPS to prevent cross-site scripting attacks.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.oracle.com/javaee/6/api/javax/servlet/http/Cookie.html#setSecure(boolean) - - https://owasp.org/www-community/controls/SecureCookieAttribute - subcategory: - - audit - technology: - - java - - cookie - vulnerability: Insecure Transport - patterns: - - pattern: $COOKIE = new Cookie($...ARGS); - - pattern-not-inside: | - $COOKIE = new Cookie(...); - ... - $COOKIE.setSecure(...); - severity: WARNING - - fix-regex: - regex: setSecure\(false\) - replacement: setSecure(true) - id: java.servlets.security.cookie-setsecure.cookie-setsecure - languages: - - java - message: 'Default session middleware settings: `setSecure` not set to true. This ensures that the cookie is sent only over HTTPS to prevent cross-site scripting attacks.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.oracle.com/javaee/6/api/javax/servlet/http/Cookie.html#setSecure(boolean) - - https://owasp.org/www-community/controls/SecureCookieAttribute - subcategory: - - audit - technology: - - java - - cookie - vulnerability: Insecure Transport - patterns: - - patterns: - - pattern-inside: | - $COOKIE = new Cookie(...); - ... - - pattern: | - $COOKIE.setSecure(false); - - pattern-not-inside: | - $COOKIE = new Cookie(...); - ... - $COOKIE.setSecure(true); - severity: WARNING - - id: java.spring.security.audit.spel-injection.spel-injection - languages: - - java - message: A Spring expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SPEL_INJECTION - subcategory: - - audit - technology: - - spring - patterns: - - pattern-either: - - pattern-inside: | - class $CLASS { - ... - ExpressionParser $PARSER; - ... - } - - pattern-inside: | - class $CLASS { - ... - ExpressionParser $PARSER = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - ExpressionParser $PARSER = ...; - ... - } - - pattern-inside: | - class $CLASS { - ... - SpelExpressionParser $PARSER; - ... - } - - pattern-inside: | - class $CLASS { - ... - SpelExpressionParser $PARSER = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - SpelExpressionParser $PARSER = ...; - ... - } - - pattern-inside: | - class $CLASS { - ... - TemplateAwareExpressionParser $PARSER; - ... - } - - pattern-inside: | - class $CLASS { - ... - TemplateAwareExpressionParser $PARSER = ...; - ... - } - - pattern-inside: | - $X $METHOD(...) { - ... - TemplateAwareExpressionParser $PARSER = ...; - ... - } - - pattern: | - $X $METHOD(...) { - ... - $PARSER.parseExpression(...); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - $PARSER.parseExpression("..."); - ... - } - - pattern-not: | - $X $METHOD(...) { - ... - String $S = "..."; - ... - $PARSER.parseExpression($S); - ... - } - severity: WARNING - - id: java.spring.security.audit.spring-actuator-fully-enabled-yaml.spring-actuator-fully-enabled-yaml - languages: - - yaml - message: Spring Boot Actuator is fully enabled. This exposes sensitive endpoints such as /actuator/env, /actuator/logfile, /actuator/heapdump and others. Unless you have Spring Security enabled or another means to protect these endpoints, this functionality is available without authentication, causing a severe security risk. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints - - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 - - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators - subcategory: - - vuln - technology: - - spring - patterns: - - pattern-inside: | - management: - ... - endpoints: - ... - web: - ... - exposure: - ... - - pattern: | - include: "*" - severity: WARNING - - id: java.spring.security.audit.spring-actuator-fully-enabled.spring-actuator-fully-enabled - languages: - - generic - message: Spring Boot Actuator is fully enabled. This exposes sensitive endpoints such as /actuator/env, /actuator/logfile, /actuator/heapdump and others. Unless you have Spring Security enabled or another means to protect these endpoints, this functionality is available without authentication, causing a significant security risk. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints - - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 - - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators - subcategory: - - vuln - technology: - - spring - paths: - include: - - '*properties' - pattern: management.endpoints.web.exposure.include=* - severity: ERROR - - id: java.spring.security.audit.spring-actuator-non-health-enabled-yaml.spring-actuator-dangerous-endpoints-enabled-yaml - languages: - - yaml - message: Spring Boot Actuator "$ACTUATOR" is enabled. Depending on the actuator, this can pose a significant security risk. Please double-check if the actuator is needed and properly secured. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints - - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 - - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators - subcategory: - - vuln - technology: - - spring - patterns: - - pattern-inside: | - management: - ... - endpoints: - ... - web: - ... - exposure: - ... - include: - ... - - pattern: | - include: [..., $ACTUATOR, ...] - - metavariable-comparison: - comparison: not str($ACTUATOR) in ["health","*"] - metavariable: $ACTUATOR - severity: WARNING - - id: java.spring.security.audit.spring-actuator-non-health-enabled.spring-actuator-dangerous-endpoints-enabled - languages: - - generic - message: Spring Boot Actuators "$...ACTUATORS" are enabled. Depending on the actuators, this can pose a significant security risk. Please double-check if the actuators are needed and properly secured. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-exposing-endpoints - - https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785 - - https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators - subcategory: - - vuln - technology: - - spring - options: - generic_ellipsis_max_span: 0 - patterns: - - pattern: management.endpoints.web.exposure.include=$...ACTUATORS - - metavariable-comparison: - comparison: not str($...ACTUATORS) in ["health","*"] - metavariable: $...ACTUATORS - severity: WARNING - - id: java.spring.security.audit.spring-csrf-disabled.spring-csrf-disabled - languages: - - java - message: CSRF protection is disabled for this configuration. This is a security risk. - metadata: - asvs: - control_id: 4.2.2 CSRF - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V4-Access-Control.md#v42-operation-level-access-control - section: V4 Access Control - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_PROTECTION_DISABLED - subcategory: - - audit - technology: - - spring - pattern: $OBJ.csrf(...).disable(...) - severity: WARNING - - id: java.spring.security.audit.spring-jsp-eval.spring-jsp-eval - languages: - - generic - message: A Spring expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#JSP_SPRING_EVAL - subcategory: - - audit - technology: - - spring - paths: - include: - - '*.jsp' - pattern: | - - severity: WARNING - - id: java.spring.security.audit.spring-sqli.spring-sqli - languages: - - java - message: Detected a string argument from a public method contract in a raw SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - spring - mode: taint - options: - taint_assume_safe_booleans: true - taint_assume_safe_numbers: true - pattern-sanitizers: - - not_conflicting: true - pattern-either: - - patterns: - - focus-metavariable: $A - - pattern-inside: | - new $TYPE(...,$A,...); - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - focus-metavariable: $A - - pattern: | - new PreparedStatementCreatorFactory($A,...); - - patterns: - - focus-metavariable: $A - - pattern: | - (JdbcTemplate $T).$M($A,...) - - patterns: - - pattern: (String $A) - - pattern-inside: | - (JdbcTemplate $T).batchUpdate(...) - - patterns: - - focus-metavariable: $A - - pattern: | - NamedParameterBatchUpdateUtils.$M($A,...) - - patterns: - - focus-metavariable: $A - - pattern: | - BatchUpdateUtils.$M($A,...) - pattern-sources: - - patterns: - - pattern: $ARG - - pattern-inside: | - public $T $M (..., String $ARG,...){...} - severity: WARNING - - id: java.spring.security.audit.spring-unvalidated-redirect.spring-unvalidated-redirect - languages: - - java - message: Application redirects a user to a destination URL specified by a user supplied parameter that is not validated. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#UNVALIDATED_REDIRECT - subcategory: - - vuln - technology: - - spring - pattern-either: - - pattern: | - $X $METHOD(...,String $URL,...) { - return "redirect:" + $URL; - } - - pattern: | - $X $METHOD(...,String $URL,...) { - ... - String $REDIR = "redirect:" + $URL; - ... - return $REDIR; - ... - } - - pattern: | - $X $METHOD(...,String $URL,...) { - ... - new ModelAndView("redirect:" + $URL); - ... - } - - pattern: |- - $X $METHOD(...,String $URL,...) { - ... - String $REDIR = "redirect:" + $URL; - ... - new ModelAndView($REDIR); - ... - } - severity: WARNING - - id: java.spring.security.injection.tainted-file-path.tainted-file-path - languages: - - java - message: Detected user input controlling a file path. An attacker could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-23: Relative Path Traversal' - impact: HIGH - interfile: true - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - subcategory: - - vuln - technology: - - java - - spring - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: new File(...) - - pattern: new java.io.File(...) - - pattern: new FileReader(...) - - pattern: new java.io.FileReader(...) - - pattern: new FileInputStream(...) - - pattern: new java.io.FileInputStream(...) - - pattern: (Paths $PATHS).get(...) - - patterns: - - pattern: | - $CLASS.$FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: ^(getResourceAsStream|getResource)$ - - patterns: - - pattern-either: - - pattern: new ClassPathResource($FILE, ...) - - pattern: ResourceUtils.getFile($FILE, ...) - - pattern: new FileOutputStream($FILE, ...) - - pattern: new java.io.FileOutputStream($FILE, ...) - - pattern: new StreamSource($FILE, ...) - - pattern: new javax.xml.transform.StreamSource($FILE, ...) - - pattern: FileUtils.openOutputStream($FILE, ...) - - focus-metavariable: $FILE - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE - severity: ERROR - - id: java.spring.security.injection.tainted-html-string.tainted-html-string - languages: - - java - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. You can use the OWASP ESAPI encoder if you must render user data. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - java - - spring - mode: taint - pattern-propagators: - - from: $...TAINTED - pattern: (StringBuilder $SB).append($...TAINTED) - to: $SB - - from: $...TAINTED - pattern: $VAR += $...TAINTED - to: $VAR - pattern-sanitizers: - - pattern-either: - - pattern: Encode.forHtml(...) - - pattern: (PolicyFactory $POLICY).sanitize(...) - - pattern: (AntiSamy $AS).scan(...) - - pattern: JSoup.clean(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: new ResponseEntity<>($PAYLOAD, ...) - - pattern: new ResponseEntity<$ERROR>($PAYLOAD, ...) - - pattern: ResponseEntity. ... .body($PAYLOAD) - - patterns: - - pattern: | - ResponseEntity.$RESPFUNC($PAYLOAD). ... - - metavariable-regex: - metavariable: $RESPFUNC - regex: ^(ok|of)$ - - focus-metavariable: $PAYLOAD - requires: CONCAT - pattern-sources: - - label: INPUT - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE - - by-side-effect: true - label: CONCAT - patterns: - - pattern-either: - - pattern: | - "$HTMLSTR" + ... - - pattern: | - "$HTMLSTR".concat(...) - - patterns: - - pattern-inside: | - StringBuilder $SB = new StringBuilder("$HTMLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$HTMLSTR"; - ... - - pattern: $VAR += ... - - pattern: String.format("$HTMLSTR", ...) - - patterns: - - pattern-inside: | - String $VAR = "$HTMLSTR"; - ... - - pattern: String.format($VAR, ...) - - metavariable-regex: - metavariable: $HTMLSTR - regex: ^<\w+ - requires: INPUT - severity: ERROR - - id: java.spring.security.injection.tainted-sql-string.tainted-sql-string - languages: - - java - message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html - subcategory: - - vuln - technology: - - spring - mode: taint - options: - interfile: true - taint_assume_safe_booleans: true - taint_assume_safe_numbers: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR".concat(...) - - patterns: - - pattern-inside: | - StringBuilder $SB = new StringBuilder("$SQLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$SQLSTR"; - ... - - pattern: $VAR += ... - - pattern: String.format("$SQLSTR", ...) - - patterns: - - pattern-inside: | - String $VAR = "$SQLSTR"; - ... - - pattern: String.format($VAR, ...) - - pattern-not-inside: System.out.println(...) - - pattern-not-inside: $LOG.info(...) - - pattern-not-inside: $LOG.warn(...) - - pattern-not-inside: $LOG.warning(...) - - pattern-not-inside: $LOG.debug(...) - - pattern-not-inside: $LOG.debugging(...) - - pattern-not-inside: $LOG.error(...) - - pattern-not-inside: new Exception(...) - - pattern-not-inside: throw ...; - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue) - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - focus-metavariable: $SOURCE - severity: ERROR - - id: java.spring.security.injection.tainted-system-command.tainted-system-command - languages: - - java - message: 'Detected user input entering a method which executes a system command. This could result in a command injection vulnerability, which allows an attacker to inject an arbitrary system command onto the server. The attacker could download malware onto or steal data from the server. Instead, use ProcessBuilder, separating the command into individual arguments, like this: `new ProcessBuilder("ls", "-al", targetDirectory)`. Further, make sure you hardcode or allowlist the actual command so that attackers can''t run arbitrary commands.' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://www.stackhawk.com/blog/command-injection-java/ - - https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html - - https://github.com/github/codeql/blob/main/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.java - subcategory: - - vuln - technology: - - java - - spring - mode: taint - pattern-propagators: - - from: $INPUT - label: CONCAT - pattern: (StringBuilder $STRB).append($INPUT) - requires: INPUT - to: $STRB - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (Process $P) = new Process(...); - - pattern: | - (ProcessBuilder $PB).command(...); - - patterns: - - pattern-either: - - pattern: | - (Runtime $R).$EXEC(...); - - pattern: | - Runtime.getRuntime(...).$EXEC(...); - - metavariable-regex: - metavariable: $EXEC - regex: (exec|loadLibrary|load) - - patterns: - - pattern: | - (ProcessBuilder $PB).command(...).$ADD(...); - - metavariable-regex: - metavariable: $ADD - regex: (add|addAll) - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $BUILDER = new ProcessBuilder(...); - ... - - pattern: $BUILDER.start(...) - - pattern: | - new ProcessBuilder(...). ... .start(...); - requires: CONCAT - pattern-sources: - - label: INPUT - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE - - label: CONCAT - patterns: - - pattern-either: - - pattern: $X + $SOURCE - - pattern: $SOURCE + $Y - - pattern: String.format("...", ..., $SOURCE, ...) - - pattern: String.join("...", ..., $SOURCE, ...) - - pattern: (String $STR).concat($SOURCE) - - pattern: $SOURCE.concat(...) - - pattern: $X += $SOURCE - - pattern: $SOURCE += $X - requires: INPUT - severity: ERROR - - id: java.spring.security.injection.tainted-url-host.tainted-url-host - languages: - - java - message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, hardcode the correct host, or ensure that the user data can only affect the path or parameters. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - java - - spring - mode: taint - options: - interfile: true - pattern-sinks: - - pattern-either: - - pattern: new URL($ONEARG) - - patterns: - - pattern-either: - - pattern: | - "$URLSTR" + ... - - pattern: | - "$URLSTR".concat(...) - - patterns: - - pattern-inside: | - StringBuilder $SB = new StringBuilder("$URLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$URLSTR"; - ... - - pattern: $VAR += ... - - patterns: - - pattern: String.format("$URLSTR", ...) - - pattern-not: String.format("$URLSTR", "...", ...) - - patterns: - - pattern-inside: | - String $VAR = "$URLSTR"; - ... - - pattern: String.format($VAR, ...) - - metavariable-regex: - metavariable: $URLSTR - regex: http(s?)://%(v|s|q).* - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE - severity: ERROR - - id: java.spring.security.unrestricted-request-mapping.unrestricted-request-mapping - languages: - - java - message: Detected a method annotated with 'RequestMapping' that does not specify the HTTP method. CSRF protections are not enabled for GET, HEAD, TRACE, or OPTIONS, and by default all HTTP methods are allowed when the HTTP method is not explicitly specified. This means that a method that performs state changes could be vulnerable to CSRF attacks. To mitigate, add the 'method' field and specify the HTTP method (such as 'RequestMethod.POST'). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING - subcategory: - - audit - technology: - - spring - patterns: - - pattern-inside: | - @RequestMapping(...) - $RETURNTYPE $METHOD(...) { ... } - - pattern-not-inside: | - @RequestMapping(..., method = $X, ...) - $RETURNTYPE $METHOD(...) { ... } - - pattern: | - RequestMapping - severity: WARNING - - id: javascript.ajv.security.audit.ajv-allerrors-true.ajv-allerrors-true - languages: - - javascript - - typescript - message: 'By setting `allErrors: true` in `Ajv` library, all error objects will be allocated without limit. This allows the attacker to produce a huge number of errors which can lead to denial of service. Do not use `allErrors: true` in production.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-400: Uncontrolled Resource Consumption' - cwe2022-top25: true - impact: LOW - likelihood: LOW - references: - - https://ajv.js.org/options.html#allerrors - subcategory: - - audit - technology: - - ajv - pattern-either: - - pattern: | - new Ajv({...,allErrors: true,...},...) - - patterns: - - pattern: | - new Ajv($SETTINGS,...) - - pattern-inside: | - $SETTINGS = {...,allErrors: true,...} - ... - severity: WARNING - - id: javascript.angular.security.detect-angular-element-methods.detect-angular-element-methods - languages: - - javascript - - typescript - message: Use of angular.element can lead to XSS if user-input is treated as part of the HTML element within `$SINK`. It is recommended to contextually output encode user-input, before inserting into `$SINK`. If the HTML needs to be preserved it is recommended to sanitize the input using $sce.getTrustedHTML or $sanitize. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/function/angular.element - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - vuln - technology: - - angularjs - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: $sce.getTrustedHtml(...) - - pattern: $sanitize(...) - - pattern: DOMPurify.sanitize(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - angular.element(...). ... .$SINK($QUERY) - - pattern-inside: | - $ANGULAR = angular.element(...) - ... - $ANGULAR. ... .$SINK($QUERY) - - metavariable-regex: - metavariable: $SINK - regex: ^(after|append|html|prepend|replaceWith|wrap)$ - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - function(..., $SCOPE, ...) { ... } - - focus-metavariable: $SCOPE - - metavariable-regex: - metavariable: $SCOPE - regex: ^\$scope$ - - pattern: $rootScope - - pattern: $injector.get('$rootScope') - - pattern: $injector.get('$scope') - severity: INFO - - id: javascript.angular.security.detect-angular-element-taint.detect-angular-element-taint - languages: - - javascript - - typescript - message: Use of angular.element can lead to XSS if user-input is treated as part of the HTML element within `$SINK`. It is recommended to contextually output encode user-input, before inserting into `$SINK`. If the HTML needs to be preserved it is recommended to sanitize the input using $sce.getTrustedHTML or $sanitize. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/function/angular.element - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - vuln - technology: - - angularjs - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: $sce.getTrustedHtml(...) - - pattern: $sanitize(...) - - pattern: DOMPurify.sanitize(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - angular.element(...). ... .$SINK($QUERY) - - pattern-inside: | - $ANGULAR = angular.element(...) - ... - $ANGULAR. ... .$SINK($QUERY) - - metavariable-regex: - metavariable: $SINK - regex: ^(after|append|html|prepend|replaceWith|wrap)$ - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-either: - - pattern: window.location.search - - pattern: window.document.location.search - - pattern: document.location.search - - pattern: location.search - - pattern: $location.search(...) - - patterns: - - pattern-either: - - pattern: $DECODE(<... location.hash ...>) - - pattern: $DECODE(<... window.location.hash ...>) - - pattern: $DECODE(<... document.location.hash ...>) - - pattern: $DECODE(<... location.href ...>) - - pattern: $DECODE(<... window.location.href ...>) - - pattern: $DECODE(<... document.location.href ...>) - - pattern: $DECODE(<... document.URL ...>) - - pattern: $DECODE(<... window.document.URL ...>) - - pattern: $DECODE(<... document.location.href ...>) - - pattern: $DECODE(<... document.location.href ...>) - - pattern: $DECODE(<... $location.absUrl() ...>) - - pattern: $DECODE(<... $location.url() ...>) - - pattern: $DECODE(<... $location.hash() ...>) - - metavariable-regex: - metavariable: $DECODE - regex: ^(unescape|decodeURI|decodeURIComponent)$ - - patterns: - - pattern-inside: $http.$METHOD(...).$CONTINUE(function $FUNC($RES) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|delete|head|jsonp|post|put|patch) - - pattern: $RES.data - severity: WARNING - - id: javascript.angular.security.detect-angular-open-redirect.detect-angular-open-redirect - languages: - - javascript - - typescript - message: Use of $window.location.href can lead to open-redirect if user input is used for redirection. - metadata: - asvs: - control_id: 5.5.1 Insecue Redirect - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/service/$sce#trustAsJs - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - audit - technology: - - angular - patterns: - - pattern: | - $window.location.href = ... - - pattern-not: | - $window.location.href = "..." - severity: ERROR - - id: javascript.angular.security.detect-angular-resource-loading.detect-angular-resource-loading - languages: - - javascript - - typescript - message: $sceDelegateProvider allowlisting can introduce security issues if wildcards are used. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/service/$sce#trustAsJs - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - audit - technology: - - angular - pattern-either: - - pattern: | - $sceDelegateProvider.resourceUrlWhitelist([...,'**',...]); - - patterns: - - pattern: | - $sceDelegateProvider.resourceUrlWhitelist([...,$DOM,...]); - - metavariable-regex: - metavariable: $DOM - regex: ^'.*\*\*.+'$ - severity: WARNING - - id: javascript.angular.security.detect-angular-sce-disabled.detect-angular-sce-disabled - languages: - - javascript - - typescript - message: $sceProvider is set to false. Disabling Strict Contextual escaping (SCE) in an AngularJS application could provide additional attack surface for XSS vulnerabilities. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/service/$sce - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - vuln - technology: - - angular - pattern: | - $sceProvider.enabled(false); - severity: ERROR - - id: javascript.angular.security.detect-angular-trust-as-css.detect-angular-trust-as-css-method - languages: - - javascript - - typescript - message: The use of $sce.trustAsCss can be dangerous if unsanitized user input flows through this API. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/service/$sce#trustAsCss - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - audit - technology: - - angular - patterns: - - pattern-either: - - pattern: | - $SOURCE = $scope.$INPUT; - $sce.trustAsCss($SOURCE); - - pattern: | - $sce.trustAsCss($scope.$INPUT); - - pattern-inside: | - app.controller(..., function($scope,$sce){ - ... - }); - severity: WARNING - - id: javascript.angular.security.detect-angular-trust-as-html-method.detect-angular-trust-as-html-method - languages: - - javascript - - typescript - message: The use of $sce.trustAsHtml can be dangerous if unsanitized user input flows through this API. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/service/$sce#trustAsHtml - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - audit - technology: - - angular - patterns: - - pattern-either: - - pattern: | - $SOURCE = $scope.$INPUT; - $sce.trustAsHtml($SOURCE); - - pattern: | - $sce.trustAsHtml($scope.$INPUT); - - pattern-inside: | - app.controller(..., function($scope,$sce){ - ... - }); - severity: WARNING - - id: javascript.angular.security.detect-angular-trust-as-js-method.detect-angular-trust-as-js-method - languages: - - javascript - - typescript - message: The use of $sce.trustAsJs can be dangerous if unsanitized user input flows through this API. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/service/$sce#trustAsJs - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - audit - technology: - - angular - patterns: - - pattern-either: - - pattern: | - $SOURCE = $scope.$INPUT; - $sce.trustAsJs($SOURCE); - - pattern: | - $sce.trustAsJs($scope.$INPUT); - - pattern-inside: | - app.controller(..., function($scope,$sce){ - ... - }); - severity: WARNING - - id: javascript.angular.security.detect-angular-trust-as-method.detect-angular-trust-as-method - languages: - - javascript - - typescript - message: The use of $sce.trustAs can be dangerous if unsanitized user input flows through this API. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/service/$sce - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - vuln - technology: - - angular - mode: taint - pattern-sinks: - - pattern: $sce.trustAs(...) - - pattern: $sce.trustAsHtml(...) - pattern-sources: - - patterns: - - pattern-inside: | - app.controller(..., function($scope,$sce) { - ... - }); - - pattern: $scope.$X - severity: WARNING - - id: javascript.angular.security.detect-angular-trust-as-resourceurl-method.detect-angular-trust-as-resourceurl-method - languages: - - javascript - - typescript - message: The use of $sce.trustAsResourceUrl can be dangerous if unsanitized user input flows through this API. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/service/$sce#trustAsResourceUrl - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - audit - technology: - - angular - patterns: - - pattern-either: - - pattern: | - $SOURCE = $scope.$INPUT; - $sce.trustAsResourceUrl($SOURCE); - - pattern: | - $sce.trustAsResourceUrl($scope.$INPUT); - - pattern-inside: | - app.controller(..., function($scope,$sce){ - ... - }); - severity: WARNING - - id: javascript.angular.security.detect-angular-trust-as-url-method.detect-angular-trust-as-url-method - languages: - - javascript - - typescript - message: The use of $sce.trustAsUrl can be dangerous if unsanitized user input flows through this API. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/service/$sce#trustAsUrl - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - audit - technology: - - angular - patterns: - - pattern-either: - - pattern: | - $SOURCE = $scope.$INPUT; - $sce.trustAsUrl($SOURCE); - - pattern: | - $sce.trustAsUrl($scope.$INPUT); - - pattern-inside: | - app.controller(..., function($scope,$sce){ - ... - }); - severity: WARNING - - id: javascript.angular.security.detect-third-party-angular-translate.detect-angular-translateprovider-translations-method - languages: - - javascript - message: The use of $translateProvider.translations method can be dangerous if user input is provided to this API. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.angularjs.org/api/ng/service/$sce#trustAsUrl - - https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20170727_AngularJS.pdf - subcategory: - - audit - technology: - - angular - - typescript - patterns: - - pattern: | - $translateProvider.translations(...,$SOURCE); - - pattern-inside: | - app.controller(..., function($scope,$sce){ - ... - }); - severity: WARNING - - id: javascript.apollo.security.apollo-axios-ssrf.apollo-axios-ssrf - languages: - - javascript - message: User-controllable argument $DATAVAL to $METHOD passed to Axios via internal handler $INNERFUNC. This could be a server-side request forgery. A user could call a restricted API or leak internal headers to an unauthorized party. Validate your user arguments against an allowlist of known URLs, or consider refactoring so that user-controlled data is not necessary. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://www.cvedetails.com/cve/CVE-2020-28168/ - - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery - subcategory: - - audit - technology: - - apollo - - axios - patterns: - - pattern: const $RESPONSE = await axios.request($INNERARG,...) - - pattern-inside: | - Query: { - $METHOD(parent, args, context, info) { - ... - $DATA = args.$DATAVAL - ... - async function $INNERFUNC(...,$INNERARG,...){ - ... - } - ... - return $INNERFUNC(...,$DATA,...) - } - } - severity: WARNING - - id: javascript.argon2.security.unsafe-argon2-config.unsafe-argon2-config - languages: - - javascript - - typescript - message: Prefer Argon2id where possible. Per RFC9016, section 4 IETF recommends selecting Argon2id unless you can guarantee an adversary has no direct access to the computing environment. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-916: Use of Password Hash With Insufficient Computational Effort' - impact: LOW - likelihood: HIGH - owasp: - - A02:2021 - Cryptographic Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - - https://eprint.iacr.org/2016/759.pdf - - https://www.cs.tau.ac.il/~tromer/papers/cache-joc-20090619.pdf - - https://datatracker.ietf.org/doc/html/rfc9106#section-4 - subcategory: - - vuln - technology: - - argon2 - - cryptography - mode: taint - pattern-sanitizers: - - patterns: - - pattern: | - {type: $ARGON.argon2id} - ... - pattern-sinks: - - patterns: - - pattern: | - $Y - - pattern-inside: | - $ARGON.hash(...,$Y) - pattern-sources: - - patterns: - - pattern-inside: | - $ARGON = require('argon2'); - ... - - pattern: | - {type: ...} - severity: WARNING - - id: javascript.audit.detect-replaceall-sanitization.detect-replaceall-sanitization - languages: - - javascript - - typescript - message: Detected a call to `$FUNC()` in an attempt to HTML escape the string `$STR`. Manually sanitizing input through a manually built list can be circumvented in many situations, and it's better to use a well known sanitization library such as `sanitize-html` or `DOMPurify`. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://www.npmjs.com/package/dompurify - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - javascript - - typescript - patterns: - - pattern-either: - - pattern: $STR.$FUNC('<', '<') - - pattern: $STR.$FUNC('>', '>') - - pattern: $STR.$FUNC('"', '"') - - pattern: $STR.$FUNC("'", ''') - - pattern: $STR.$FUNC('&', '&') - - metavariable-regex: - metavariable: $FUNC - regex: (replace|replaceAll) - severity: INFO - - id: javascript.aws-lambda.security.detect-child-process.detect-child-process - languages: - - javascript - - typescript - message: Allowing spawning arbitrary programs or running shell processes with arbitrary arguments may end up in a command injection vulnerability. Try to avoid non-literal values for the command string. If it is not possible, then do not let running arbitrary commands, use a white list for inputs. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - javascript - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $CMD - - pattern-either: - - pattern: exec($CMD,...) - - pattern: execSync($CMD,...) - - pattern: spawn($CMD,...) - - pattern: spawnSync($CMD,...) - - pattern: $CP.exec($CMD,...) - - pattern: $CP.execSync($CMD,...) - - pattern: $CP.spawn($CMD,...) - - pattern: $CP.spawnSync($CMD,...) - - pattern-either: - - pattern-inside: | - require('child_process') - ... - - pattern-inside: | - import 'child_process' - ... - pattern-sources: - - patterns: - - pattern: $EVENT - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - severity: ERROR - - id: javascript.aws-lambda.security.dynamodb-request-object.dynamodb-request-object - languages: - - javascript - - typescript - message: Detected DynamoDB query params that are tainted by `$EVENT` object. This could lead to NoSQL injection if the variable is user-controlled and not properly sanitized. Explicitly assign query params instead of passing data from `$EVENT` directly to DynamoDB client. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-943: Improper Neutralization of Special Elements in Data Query Logic' - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - javascript - - aws-lambda - - dynamodb - mode: taint - pattern-sanitizers: - - patterns: - - pattern: | - {...} - pattern-sinks: - - patterns: - - focus-metavariable: $SINK - - pattern: | - $DC.$METHOD($SINK, ...) - - metavariable-regex: - metavariable: $METHOD - regex: (query|send|scan|delete|put|transactWrite|update|batchExecuteStatement|executeStatement|executeTransaction|transactWriteItems) - - pattern-either: - - pattern-inside: | - $DC = new $AWS.DocumentClient(...); - ... - - pattern-inside: | - $DC = new $AWS.DynamoDB(...); - ... - - pattern-inside: | - $DC = new DynamoDBClient(...); - ... - - pattern-inside: | - $DC = DynamoDBDocumentClient.from(...); - ... - pattern-sources: - - patterns: - - pattern: $EVENT - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - severity: ERROR - - id: javascript.aws-lambda.security.knex-sqli.knex-sqli - languages: - - javascript - - typescript - message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `knex.raw(''SELECT $1 from table'', [userinput])`' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://knexjs.org/#Builder-fromRaw - - https://knexjs.org/#Builder-whereRaw - subcategory: - - vuln - technology: - - aws-lambda - - knex - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $KNEX.fromRaw($QUERY, ...) - - pattern: $KNEX.whereRaw($QUERY, ...) - - pattern: $KNEX.raw($QUERY, ...) - - pattern-either: - - pattern-inside: | - require('knex') - ... - - pattern-inside: | - import 'knex' - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.pg-sqli.pg-sqli - languages: - - javascript - - typescript - message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `connection.query(''SELECT $1 from table'', [userinput])`' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://node-postgres.com/features/queries - subcategory: - - vuln - technology: - - aws-lambda - - postgres - - pg - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $DB.query($QUERY, ...) - - pattern-either: - - pattern-inside: | - require('pg') - ... - - pattern-inside: | - import 'pg' - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.sequelize-sqli.sequelize-sqli - languages: - - javascript - - typescript - message: 'Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `sequelize.query(''SELECT * FROM projects WHERE status = ?'', { replacements: [''active''], type: QueryTypes.SELECT });`' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://sequelize.org/master/manual/raw-queries.html - subcategory: - - vuln - technology: - - aws-lambda - - sequelize - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern: $DB.query($QUERY, ...) - - pattern-either: - - pattern-inside: | - require('sequelize') - ... - - pattern-inside: | - import 'sequelize' - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.tainted-eval.tainted-eval - languages: - - javascript - - typescript - message: The `eval()` function evaluates JavaScript code represented as a string. Executing JavaScript from a string is an enormous security risk. It is far too easy for a bad actor to run arbitrary code when you use `eval()`. Ensure evaluated content is not definable by external sources. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - javascript - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $CODE - - pattern-either: - - pattern: eval($CODE) - - pattern: Function(...,$CODE) - - pattern: new Function(...,$CODE) - pattern-sources: - - patterns: - - pattern: $EVENT - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - severity: WARNING - - id: javascript.aws-lambda.security.tainted-html-response.tainted-html-response - languages: - - javascript - - typescript - message: Detected user input flowing into an HTML response. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $BODY - - pattern-inside: | - {..., headers: {..., 'Content-Type': 'text/html', ...}, body: $BODY, ... } - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.tainted-html-string.tainted-html-string - languages: - - javascript - - typescript - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates which will safely render HTML instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - "$HTMLSTR" + $EXPR - - pattern: | - "$HTMLSTR".concat(...) - - pattern: $UTIL.format($HTMLSTR, ...) - - pattern: format($HTMLSTR, ...) - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - - patterns: - - pattern: | - `...${...}...` - - pattern-regex: | - .*<\w+.* - - pattern-not-inside: | - console.$LOG(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: WARNING - - id: javascript.aws-lambda.security.tainted-sql-string.tainted-sql-string - languages: - - javascript - - typescript - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/SQL_Injection - subcategory: - - vuln - technology: - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + $EXPR - - pattern: | - "$SQLSTR".concat(...) - - pattern: util.format($SQLSTR, ...) - - metavariable-regex: - metavariable: $SQLSTR - regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - - patterns: - - pattern: | - `...${...}...` - - pattern-regex: | - .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - - pattern-not-inside: | - console.$LOG(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern: $EVENT - severity: ERROR - - id: javascript.aws-lambda.security.vm-runincontext-injection.vm-runincontext-injection - languages: - - javascript - - typescript - message: The `vm` module enables compiling and running code within V8 Virtual Machine contexts. The `vm` module is not a security mechanism. Do not use it to run untrusted code. If code passed to `vm` functions is controlled by user input it could result in command injection. Do not let user input in `vm` functions. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - javascript - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('vm'); - ... - - pattern-inside: | - import 'vm' - ... - - pattern-either: - - pattern: $VM.runInContext($X,...) - - pattern: $VM.runInNewContext($X,...) - - pattern: $VM.runInThisContext($X,...) - - pattern: $VM.compileFunction($X,...) - - pattern: new $VM.Script($X,...) - - pattern: new $VM.SourceTextModule($X,...) - - pattern: runInContext($X,...) - - pattern: runInNewContext($X,...) - - pattern: runInThisContext($X,...) - - pattern: compileFunction($X,...) - - pattern: new Script($X,...) - - pattern: new SourceTextModule($X,...) - pattern-sources: - - patterns: - - pattern: $EVENT - - pattern-either: - - pattern-inside: | - exports.handler = function ($EVENT, ...) { - ... - } - - pattern-inside: | - function $FUNC ($EVENT, ...) {...} - ... - exports.handler = $FUNC - - pattern-inside: | - $FUNC = function ($EVENT, ...) {...} - ... - exports.handler = $FUNC - severity: ERROR - - id: javascript.bluebird.security.audit.tofastproperties-code-execution.tofastproperties-code-execution - languages: - - javascript - - typescript - message: Potential arbitrary code execution, whatever is provided to `toFastProperties` is sent straight to eval() - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - http://bluebirdjs.com/docs/getting-started.html - subcategory: - - vuln - technology: - - bluebird - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $UTIL.toFastProperties($SINK,...) - - pattern: toFastProperties($SINK,...) - - pattern-either: - - pattern-inside: | - $BB = require('bluebird'); - ... - - pattern-inside: | - import 'bluebird'; - ... - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-inside: function ... (..., $ARG,...) {...} - - focus-metavariable: $ARG - severity: WARNING - - id: javascript.browser.security.dom-based-xss.dom-based-xss - languages: - - javascript - - typescript - message: 'Detected possible DOM-based XSS. This occurs because a portion of the URL is being used to construct an element added directly to the page. For example, a malicious actor could send someone a link like this: http://www.some.site/page.html?default= which would add the script to the page. Consider allowlisting appropriate values or using an approach which does not involve the URL.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/DOM_Based_XSS - subcategory: - - audit - technology: - - browser - pattern-either: - - pattern: document.write(<... document.location.$W ...>) - - pattern: document.write(<... location.$W ...>) - severity: ERROR - - id: javascript.browser.security.eval-detected.eval-detected - languages: - - javascript - - typescript - message: Detected the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources. - metadata: - asvs: - control_id: 5.2.4 Dynamic Code Execution Features - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - browser - patterns: - - pattern-not: eval("...") - - pattern: eval(...) - severity: WARNING - - id: javascript.browser.security.insecure-document-method.insecure-document-method - languages: - - javascript - - typescript - message: User controlled data in methods like `innerHTML`, `outerHTML` or `document.write` is an anti-pattern that can lead to XSS vulnerabilities - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - browser - patterns: - - pattern-either: - - pattern: | - $EL.innerHTML = $HTML; - - pattern: | - $EL.outerHTML = $HTML; - - pattern: document.write(...) - - pattern-not: | - $EL.innerHTML = "..."; - - pattern-not: | - $EL.outerHTML = "..."; - - pattern-not: document.write("...") - severity: ERROR - - id: javascript.browser.security.insecure-innerhtml.insecure-innerhtml - languages: - - javascript - - typescript - message: User controlled data in a `$EL.innerHTML` is an anti-pattern that can lead to XSS vulnerabilities - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - browser - patterns: - - pattern: | - $EL.innerHTML = $HTML; - - pattern-not: | - $EL.innerHTML = "..."; - severity: ERROR - - id: javascript.browser.security.insufficient-postmessage-origin-validation.insufficient-postmessage-origin-validation - languages: - - javascript - - typescript - message: No validation of origin is done by the addEventListener API. It may be possible to exploit this flaw to perform Cross Origin attacks such as Cross-Site Scripting(XSS). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-345: Insufficient Verification of Data Authenticity' - impact: LOW - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures - subcategory: - - audit - technology: - - browser - pattern-either: - - patterns: - - pattern: | - window.addEventListener('message', $FUNC, ...) - - metavariable-pattern: - metavariable: $FUNC - patterns: - - pattern: | - function($OBJ) { ... } - - pattern-not: | - function($OBJ) { ... if (<... $OBJ.origin ...>) { ... } ... } - - patterns: - - pattern-either: - - pattern-inside: | - function $FNAME($OBJ) { $CONTEXT } - ... - - pattern-inside: | - $FNAME = (...) => { $CONTEXT } - ... - - pattern: | - window.addEventListener('message', $FNAME,...) - - metavariable-pattern: - metavariable: $CONTEXT - patterns: - - pattern-not: | - ... if (<... $OBJ.origin ...>) { ... } ... - severity: WARNING - - id: javascript.browser.security.open-redirect-from-function.js-open-redirect-from-function - languages: - - javascript - - typescript - message: The application accepts potentially user-controlled input `$PROP` which can control the location of the current window context. This can lead two types of vulnerabilities open-redirection and Cross-Site-Scripting (XSS) with JavaScript URIs. It is recommended to validate user-controllable input before allowing it to control the redirection. - metadata: - asvs: - control_id: 5.5.1 Insecue Redirect - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html - subcategory: - - vuln - technology: - - browser - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: location.href = $SINK - - pattern: window.location.href = $SINK - - pattern: this.window.location.href = $SINK - - pattern: this.location.href = $SINK - - pattern: location.replace($SINK) - - pattern: window.location.replace($SINK) - - pattern: this.window.location.replace($SINK) - - pattern: this.location.replace($SINK) - - focus-metavariable: $SINK - - metavariable-pattern: - metavariable: $SINK - patterns: - - pattern-not: | - "..." + $VALUE - - pattern-not: | - `...${$VALUE}` - pattern-sources: - - patterns: - - pattern-inside: | - function ... (..., $PROP, ...) { ... } - - focus-metavariable: $PROP - severity: INFO - - id: javascript.browser.security.open-redirect.js-open-redirect - languages: - - javascript - - typescript - message: The application accepts potentially user-controlled input `$PROP` which can control the location of the current window context. This can lead two types of vulnerabilities open-redirection and Cross-Site-Scripting (XSS) with JavaScript URIs. It is recommended to validate user-controllable input before allowing it to control the redirection. - metadata: - asvs: - control_id: 5.5.1 Insecue Redirect - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A01:2021 - Broken Access Control - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html - subcategory: - - vuln - technology: - - browser - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: location.href = $SINK - - pattern: $THIS. ... .location.href = $SINK - - pattern: location.replace($SINK) - - pattern: $THIS. ... .location.replace($SINK) - - pattern: location = $SINK - - pattern: $WINDOW. ... .location = $SINK - - focus-metavariable: $SINK - - metavariable-pattern: - metavariable: $SINK - patterns: - - pattern-not: | - "..." + $VALUE - - pattern-not: | - `...${$VALUE}` - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $PROP = new URLSearchParams($WINDOW. ... .location.search).get('...') - ... - - pattern-inside: | - $PROP = new URLSearchParams(location.search).get('...') - ... - - pattern-inside: | - $PROP = new URLSearchParams($WINDOW. ... .location.hash.substring(1)).get('...') - ... - - pattern-inside: | - $PROP = new URLSearchParams(location.hash.substring(1)).get('...') - ... - - pattern: $PROP - - patterns: - - pattern-either: - - pattern-inside: | - $PROPS = new URLSearchParams($WINDOW. ... .location.search) - ... - - pattern-inside: | - $PROPS = new URLSearchParams(location.search) - ... - - pattern-inside: | - $PROPS = new URLSearchParams($WINDOW. ... .location.hash.substring(1)) - ... - - pattern-inside: | - $PROPS = new URLSearchParams(location.hash.substring(1)) - ... - - pattern: $PROPS.get('...') - - patterns: - - pattern-either: - - pattern-inside: | - $PROPS = new URL($WINDOW. ... .location.href) - ... - - pattern-inside: | - $PROPS = new URL(location.href) - ... - - pattern: $PROPS.searchParams.get('...') - - patterns: - - pattern-either: - - pattern-inside: | - $PROPS = new URL($WINDOW. ... .location.href).searchParams.get('...') - ... - - pattern-inside: | - $PROPS = new URL(location.href).searchParams.get('...') - ... - - pattern: $PROPS - severity: WARNING - - id: javascript.browser.security.raw-html-concat.raw-html-concat - languages: - - javascript - - typescript - message: User controlled data in a HTML string may result in XSS - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/xss/ - subcategory: - - vuln - technology: - - browser - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; - ... - - pattern-inside: | - $S = require("sanitize-html") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - $S = new Remarkable() - ... - - pattern: $S.render(...) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: $STRING + $EXPR - - pattern-not: $STRING + "..." - - metavariable-pattern: - language: generic - metavariable: $STRING - patterns: - - pattern: <$TAG ... - - pattern-not: <$TAG ...>...... - - patterns: - - pattern: $EXPR + $STRING - - pattern-not: '"..." + $STRING' - - metavariable-pattern: - language: generic - metavariable: $STRING - patterns: - - pattern: '... ,...) - - pattern-not-inside: | - $OPTS = <... {name:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.name = ...; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-secure - languages: - - javascript - - typescript - message: 'Default session middleware settings: `secure` not set. It ensures the browser only sends the cookie over HTTPS.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: HIGH - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html - subcategory: - - vuln - technology: - - express - patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{secure:true}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{secure:true}} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {secure:true} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {secure:true} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.secure = true; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.secure = true; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-httponly - languages: - - javascript - - typescript - message: 'Default session middleware settings: `httpOnly` not set. It ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: HIGH - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html - subcategory: - - vuln - technology: - - express - patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{httpOnly:true}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{httpOnly:true}} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {httpOnly:true} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {httpOnly:true} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.httpOnly = true; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.httpOnly = true; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-domain - languages: - - javascript - - typescript - message: 'Default session middleware settings: `domain` not set. It indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: HIGH - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html - subcategory: - - vuln - technology: - - express - patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{domain:...}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{domain:...}} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {domain:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {domain:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.domain = ...; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.domain = ...; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-path - languages: - - javascript - - typescript - message: 'Default session middleware settings: `path` not set. It indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: HIGH - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html - subcategory: - - vuln - technology: - - express - patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{path:...}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{path:...}} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {path:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {path:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.path = ...; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.path = ...; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-expires - languages: - - javascript - - typescript - message: 'Default session middleware settings: `expires` not set. Use it to set expiration date for persistent cookies.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: HIGH - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://expressjs.com/en/advanced/best-practice-security.html - subcategory: - - vuln - technology: - - express - patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session'); - ... - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{expires:...}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{expires:...}} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {expires:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {expires:...} ...>; - ... - $SESSION($OPTS,...); - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.expires = ...; - ... - $SESSION($OPTS,...); - - pattern-not-inside: |- - $OPTS = ...; - ... - $OPTS.cookie.expires = ...; - ... - $SESSION($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-detect-notevil-usage.express-detect-notevil-usage - languages: - - javascript - - typescript - message: Detected usage of the `notevil` package, which is unmaintained and has vulnerabilities. Using any sort of `eval()` functionality can be very dangerous, but if you must, the `eval` package is an up to date alternative. Be sure that only trusted input reaches an `eval()` function. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-1104: Use of Unmaintained Third Party Components' - impact: HIGH - likelihood: LOW - owasp: - - A06:2021 - Vulnerable and Outdated Components - references: - - https://github.com/mmckegg/notevil - subcategory: - - audit - technology: - - javascript - - typescript - patterns: - - pattern-either: - - pattern-inside: | - import $EVAL from 'notevil' - ... - - pattern-inside: | - import {$EVAL} from 'notevil' - ... - - pattern-inside: | - $EVAL = require('notevil') - ... - - pattern-either: - - patterns: - - pattern: $EVAL(...) - - pattern-not: $EVAL('...') - - patterns: - - pattern-either: - - pattern: $VM.runInContext("$CMD", ...) - - pattern: $VM.runInNewContext("$CMD", ...) - - pattern: $VM.runInThisContext("$CMD", ...) - - pattern: $VM.compileFunction("$CMD", ...) - - metavariable-pattern: - language: typescript - metavariable: $CMD - patterns: - - pattern: $EVAL(...) - - pattern-not: $EVAL('...') - severity: WARNING - - id: javascript.express.security.audit.express-jwt-not-revoked.express-jwt-not-revoked - languages: - - javascript - - typescript - message: No token revoking configured for `express-jwt`. A leaked token could still be used and unable to be revoked. Consider using function as the `isRevoked` option. - metadata: - asvs: - control_id: 3.5.3 Insecue Stateless Session Tokens - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://github.com/goldbergyoni/nodebestpractices/blob/master/sections/security/expirejwt.md - subcategory: - - vuln - technology: - - express - patterns: - - pattern-inside: | - $JWT = require('express-jwt'); - ... - - pattern: $JWT(...) - - pattern-not-inside: $JWT(<... {isRevoked:...} ...>,...) - - pattern-not-inside: |- - $OPTS = <... {isRevoked:...} ...>; - ... - $JWT($OPTS,...); - severity: WARNING - - id: javascript.express.security.audit.express-libxml-noent.express-libxml-noent - languages: - - javascript - - typescript - message: The libxml library processes user-input with the `noent` attribute is set to `true` which can lead to being vulnerable to XML External Entities (XXE) type attacks. It is recommended to set `noent` to `false` when using this feature to ensure you are protected. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - interfile: true - likelihood: HIGH - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - mode: taint - options: - interfile: true - pattern-sinks: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - $XML = require('$IMPORT') - ... - - pattern-inside: | - import $XML from '$IMPORT' - ... - - pattern-inside: | - import * as $XML from '$IMPORT' - ... - - metavariable-regex: - metavariable: $IMPORT - regex: ^(libxmljs|libxmljs2)$ - - pattern-inside: $XML.$FUNC($QUERY, {...,noent:true,...}) - - metavariable-regex: - metavariable: $FUNC - regex: ^(parseXmlString|parseXml)$ - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - pattern: $REQ.files.$ANYTHING.data.toString('utf8') - - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - pattern: files.$ANYTHING.data.toString('utf8') - - pattern: files.$ANYTHING['data'].toString('utf8') - severity: ERROR - - id: javascript.express.security.audit.express-libxml-vm-noent.express-libxml-vm-noent - languages: - - javascript - - typescript - message: Detected use of parseXml() function with the `noent` field set to `true`. This can lead to an XML External Entities (XXE) attack if untrusted data is passed into it. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - express - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: $VM.runInContext("$CMD", ...) - - pattern: $VM.runInNewContext("$CMD", ...) - - pattern: $VM.runInThisContext("$CMD", ...) - - pattern: $VM.compileFunction("$CMD", ...) - - metavariable-pattern: - language: typescript - metavariable: $CMD - pattern-either: - - pattern: | - $LIBXML.parseXml($DATA, {..., noent: true, ...}, ...) - - patterns: - - pattern-inside: | - $OPTS = {..., noent: true, ...} - ... - - pattern: $LIBXML.parseXml( $DATA, $OPTS ) - - pattern: | - $LIBXML.parseXml($DATA, {..., noent: true, ...}, ...) - - patterns: - - pattern-inside: | - $OPTS = {..., noent: true, ...} - ... - - pattern: $LIBXML.parseXml( $DATA, $OPTS ) - severity: WARNING - - id: javascript.express.security.audit.express-open-redirect.express-open-redirect - languages: - - javascript - - typescript - message: The application redirects to a URL specified by user-supplied input `$REQ` that is not validated. This could redirect users to malicious locations. Consider using an allow-list approach to validate URLs, or warn users they are being redirected to a third-party website. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A01:2021 - Broken Access Control - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - mode: taint - options: - symbolic_propagation: true - taint_unify_mvars: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $RES.redirect("$HTTP"+$REQ. ... .$VALUE) - - pattern: $RES.redirect("$HTTP"+$REQ. ... .$VALUE + $...A) - - pattern: $RES.redirect(`$HTTP${$REQ. ... .$VALUE}...`) - - pattern: $RES.redirect("$HTTP"+$REQ.$VALUE[...]) - - pattern: $RES.redirect("$HTTP"+$REQ.$VALUE[...] + $...A) - - pattern: $RES.redirect(`$HTTP${$REQ.$VALUE[...]}...`) - - metavariable-regex: - metavariable: $HTTP - regex: ^https?:\/\/$ - - pattern-either: - - pattern: $REQ. ... .$VALUE - - patterns: - - pattern-either: - - pattern: $RES.redirect($REQ. ... .$VALUE) - - pattern: $RES.redirect($REQ. ... .$VALUE + $...A) - - pattern: $RES.redirect(`${$REQ. ... .$VALUE}...`) - - pattern: $REQ. ... .$VALUE - - patterns: - - pattern-either: - - pattern: $RES.redirect($REQ.$VALUE['...']) - - pattern: $RES.redirect($REQ.$VALUE['...'] + $...A) - - pattern: $RES.redirect(`${$REQ.$VALUE['...']}...`) - - pattern: $REQ.$VALUE - - patterns: - - pattern-either: - - pattern-inside: | - $ASSIGN = $REQ. ... .$VALUE - ... - - pattern-inside: | - $ASSIGN = $REQ.$VALUE['...'] - ... - - pattern-inside: | - $ASSIGN = $REQ. ... .$VALUE + $...A - ... - - pattern-inside: "$ASSIGN = $REQ.$VALUE['...'] + $...A\n... \n" - - pattern-inside: | - $ASSIGN = `${$REQ. ... .$VALUE}...` - ... - - pattern-inside: "$ASSIGN = `${$REQ.$VALUE['...']}...`\n... \n" - - pattern-either: - - pattern: $RES.redirect($ASSIGN) - - pattern: $RES.redirect($ASSIGN + $...FOO) - - pattern: $RES.redirect(`${$ASSIGN}...`) - - focus-metavariable: $ASSIGN - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.audit.express-path-join-resolve-traversal.express-path-join-resolve-traversal - languages: - - javascript - - typescript - message: Possible writing outside of the destination, make sure that the target path is nested in the intended destination - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - subcategory: - - vuln - technology: - - express - - node.js - mode: taint - pattern-sanitizers: - - pattern: $Y.replace(...) - - pattern: $Y.indexOf(...) - - pattern: | - function ... (...) { - ... - <... $Y.indexOf(...) ...> - ... - } - - patterns: - - pattern: $FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: sanitize - pattern-sinks: - - patterns: - - focus-metavariable: $SINK - - pattern-either: - - pattern-inside: | - $PATH = require('path'); - ... - - pattern-inside: | - import $PATH from 'path'; - ... - - pattern-either: - - pattern: $PATH.join(...,$SINK,...) - - pattern: $PATH.resolve(...,$SINK,...) - - patterns: - - focus-metavariable: $SINK - - pattern-inside: | - import 'path'; - ... - - pattern-either: - - pattern: path.join(...,$SINK,...) - - pattern: path.resolve(...,$SINK,...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.audit.express-res-sendfile.express-res-sendfile - languages: - - javascript - - typescript - message: The application processes user-input, this is passed to res.sendFile which can allow an attacker to arbitrarily read files on the system through path traversal. It is recommended to perform input validation in addition to canonicalizing the path. This allows you to validate the path against the intended directory it should be accessing. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-73: External Control of File Name or Path' - impact: MEDIUM - likelihood: HIGH - owasp: - - A04:2021 - Insecure Design - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $RES.$METH($QUERY,...) - - pattern-not-inside: $RES.$METH($QUERY,$OPTIONS) - - metavariable-regex: - metavariable: $METH - regex: ^(sendfile|sendFile)$ - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - function ... (...,$REQ: $TYPE, ...) {...} - - metavariable-regex: - metavariable: $TYPE - regex: ^(string|String) - severity: WARNING - - id: javascript.express.security.audit.express-session-hardcoded-secret.express-session-hardcoded-secret - languages: - - javascript - - typescript - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - interfile: true - likelihood: HIGH - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - - secrets - options: - interfile: true - patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('express-session'); - ... - - pattern-inside: | - import $SESSION from 'express-session' - ... - - pattern-inside: | - import {..., $SESSION, ...} from 'express-session' - ... - - pattern-inside: | - import * as $SESSION from 'express-session' - ... - - patterns: - - pattern-either: - - pattern-inside: $APP.use($SESSION({...})) - - pattern: | - $SECRET = $VALUE - ... - $APP.use($SESSION($SECRET)) - - pattern: | - secret: '$Y' - severity: WARNING - - id: javascript.express.security.audit.express-ssrf.express-ssrf - languages: - - javascript - - typescript - message: 'The following request $REQUEST.$METHOD() was found to be crafted from user-input `$REQ` which can lead to Server-Side Request Forgery (SSRF) vulnerabilities. It is recommended where possible to not allow user-input to craft the base request, but to be treated as part of the path or query parameter. When user-input is necessary to craft the request, it is recommeneded to follow OWASP best practices to prevent abuse. ' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - mode: taint - options: - taint_unify_mvars: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $REQUEST = require('request') - ... - - pattern-inside: | - import * as $REQUEST from 'request' - ... - - pattern-inside: | - import $REQUEST from 'request' - ... - - pattern-either: - - pattern: $REQUEST.$METHOD("$HTTP"+$REQ. ... .$VALUE) - - pattern: $REQUEST.$METHOD("$HTTP"+$REQ. ... .$VALUE + $...A) - - pattern: $REQUEST.$METHOD(`$HTTP${$REQ. ... .$VALUE}...`) - - pattern: $REQUEST.$METHOD("$HTTP"+$REQ.$VALUE[...]) - - pattern: $REQUEST.$METHOD("$HTTP"+$REQ.$VALUE[...] + $...A) - - pattern: $REQUEST.$METHOD(`$HTTP${$REQ.$VALUE[...]}...`) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|patch|del|head|delete)$ - - metavariable-regex: - metavariable: $HTTP - regex: ^(https?:\/\/|//)$ - - pattern-either: - - pattern: $REQ. ... .$VALUE - - patterns: - - pattern-either: - - pattern-inside: | - $REQUEST = require('request') - ... - - pattern-inside: | - import * as $REQUEST from 'request' - ... - - pattern-inside: | - import $REQUEST from 'request' - ... - - pattern-either: - - pattern: $REQUEST.$METHOD($REQ. ... .$VALUE,...) - - pattern: $REQUEST.$METHOD($REQ. ... .$VALUE + $...A,...) - - pattern: $REQUEST.$METHOD(`${$REQ. ... .$VALUE}...`,...) - - pattern: $REQ. ... .$VALUE - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|patch|del|head|delete)$ - - patterns: - - pattern-either: - - pattern-inside: | - $REQUEST = require('request') - ... - - pattern-inside: | - import * as $REQUEST from 'request' - ... - - pattern-inside: | - import $REQUEST from 'request' - ... - - pattern-either: - - pattern: $REQUEST.$METHOD($REQ.$VALUE['...'],...) - - pattern: $REQUEST.$METHOD($REQ.$VALUE['...'] + $...A,...) - - pattern: $REQUEST.$METHOD(`${$REQ.$VALUE['...']}...`,...) - - pattern: $REQ.$VALUE - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|patch|del|head|delete)$ - - patterns: - - pattern-either: - - pattern-inside: | - $REQUEST = require('request') - ... - - pattern-inside: | - import * as $REQUEST from 'request' - ... - - pattern-inside: | - import $REQUEST from 'request' - ... - - pattern-either: - - pattern-inside: | - $ASSIGN = $REQ. ... .$VALUE - ... - - pattern-inside: | - $ASSIGN = $REQ. ... .$VALUE['...'] - ... - - pattern-inside: | - $ASSIGN = $REQ. ... .$VALUE + $...A - ... - - pattern-inside: "$ASSIGN = $REQ. ... .$VALUE['...'] + $...A\n... \n" - - pattern-inside: | - $ASSIGN = `${$REQ. ... .$VALUE}...` - ... - - pattern-inside: "$ASSIGN = `${$REQ. ... .$VALUE['...']}...`\n... \n" - - patterns: - - pattern-either: - - pattern-inside: | - $ASSIGN = "$HTTP"+ $REQ. ... .$VALUE - ... - - pattern-inside: | - $ASSIGN = "$HTTP"+$REQ. ... .$VALUE + $...A - ... - - pattern-inside: | - $ASSIGN = "$HTTP"+$REQ.$VALUE[...] - ... - - pattern-inside: | - $ASSIGN = "$HTTP"+$REQ.$VALUE[...] + $...A - ... - - pattern-inside: | - $ASSIGN = `$HTTP${$REQ.$VALUE[...]}...` - ... - - metavariable-regex: - metavariable: $HTTP - regex: ^(https?:\/\/|//)$ - - pattern-either: - - pattern: $REQUEST.$METHOD($ASSIGN,...) - - pattern: $REQUEST.$METHOD($ASSIGN + $...FOO,...) - - pattern: $REQUEST.$METHOD(`${$ASSIGN}...`,...) - - patterns: - - pattern-either: - - pattern: $REQUEST.$METHOD("$HTTP"+$ASSIGN,...) - - pattern: $REQUEST.$METHOD("$HTTP"+$ASSIGN + $...A,...) - - pattern: $REQUEST.$METHOD(`$HTTP${$ASSIGN}...`,...) - - metavariable-regex: - metavariable: $HTTP - regex: ^(https?:\/\/|//)$ - - pattern: $ASSIGN - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|patch|del|head|delete)$ - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, ...) {...} - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,...) => - {...} - - pattern-inside: | - ({ $REQ }: $EXPRESS.Request,...) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.audit.express-third-party-object-deserialization.express-third-party-object-deserialization - languages: - - javascript - - typescript - message: The following function call $SER.$FUNC accepts user controlled data which can result in Remote Code Execution (RCE) through Object Deserialization. It is recommended to use secure data processing alternatives such as JSON.parse() and Buffer.from(). - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - interfile: true - likelihood: HIGH - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html - source_rule_url: - - https://github.com/ajinabraham/njsscan/blob/75bfbeb9c8d72999e4d527dfa2548f7f0f3cc48a/njsscan/rules/semantic_grep/eval/eval_deserialize.yaml - subcategory: - - vuln - technology: - - express - mode: taint - options: - interfile: true - pattern-sinks: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - $SER = require('$IMPORT') - ... - - pattern-inside: | - import $SER from '$IMPORT' - ... - - pattern-inside: | - import * as $SER from '$IMPORT' - ... - - metavariable-regex: - metavariable: $IMPORT - regex: ^(node-serialize|serialize-to-js)$ - - pattern: $SER.$FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: ^(unserialize|deserialize)$ - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - pattern: $REQ.files.$ANYTHING.data.toString('utf8') - - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - pattern: files.$ANYTHING.data.toString('utf8') - - pattern: files.$ANYTHING['data'].toString('utf8') - severity: WARNING - - id: javascript.express.security.audit.express-xml2json-xxe-event.express-xml2json-xxe-event - languages: - - javascript - - typescript - message: Xml Parser is used inside Request Event. Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://www.npmjs.com/package/xml2json - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('xml2json'); - ... - - pattern-inside: | - import 'xml2json'; - ... - - pattern: $REQ.on('...', function(...) { ... $EXPAT.toJson($INPUT,...); ... }) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.audit.possible-user-input-redirect.unknown-value-in-redirect - languages: - - javascript - - typescript - message: It looks like '$UNK' is read from user input and it is used to as a redirect. Ensure '$UNK' is not externally controlled, otherwise this is an open redirect. - metadata: - asvs: - control_id: 5.5.1 Insecue Redirect - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v51-input-validation - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - express - patterns: - - pattern-either: - - pattern-inside: | - $UNK = query.$B; - ... - - pattern-inside: | - $UNK = $A.query.$B; - ... - - pattern-inside: | - $UNK = req.$SOMETHING; - ... - - pattern: $RES.redirect(..., <... $UNK ...>, ...) - severity: WARNING - - id: javascript.express.security.audit.remote-property-injection.remote-property-injection - languages: - - javascript - - typescript - message: Bracket object notation with user input is present, this might allow an attacker to access all properties of the object and even it's prototype. Use literal values for object properties. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://github.com/nodesecurity/eslint-plugin-security/blob/3c7522ca1be800353513282867a1034c795d9eb4/docs/the-dangers-of-square-bracket-notation.md - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sanitizers: - - patterns: - - pattern: var $X = ... - - pattern-not: var $X = $REQ.$ANY - pattern-sinks: - - patterns: - - pattern-inside: $OBJ[...] = ... - - pattern-not-inside: $OBJ["..."] = ... - - pattern-not-inside: $OBJ[...] = "..." - - pattern: $INDEX - - pattern-not: | - "..." + $INDEX - - pattern-not: | - $INDEX + "..." - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.audit.res-render-injection.res-render-injection - languages: - - javascript - - typescript - message: User controllable data `$REQ` enters `$RES.render(...)` this can lead to the loading of other HTML/templating pages that they may not be authorized to render. An attacker may attempt to use directory traversal techniques e.g. `../folder/index` to access other HTML pages on the file system. Where possible, do not allow users to define what should be loaded in $RES.render or use an allow list for the existing application. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-706: Use of Incorrectly-Resolved Name or Reference' - impact: MEDIUM - interfile: true - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - http://expressjs.com/en/4x/api.html#res.render - subcategory: - - vuln - technology: - - express - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $RES.render($SINK, ...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.audit.xss.direct-response-write.direct-response-write - languages: - - javascript - - typescript - message: Detected directly writing to a Response object from user-defined input. This bypasses any HTML escaping and may expose your application to a Cross-Site-scripting (XSS) vulnerability. Instead, use 'resp.render()' to render safely escaped HTML. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - vulnerability_class: - - Cross-Site-Scripting (XSS) - mode: taint - options: - interfile: true - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; - ... - - pattern-inside: | - $S = require("sanitize-html") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - $S = new Remarkable() - ... - - pattern: $S.render(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'express-xss-sanitizer'; - ... - - pattern-inside: | - import * as $S from "express-xss-sanitizer"; - ... - - pattern-inside: | - const { ..., $S, ... } = require('express-xss-sanitizer'); - ... - - pattern-inside: | - var { ..., $S, ... } = require('express-xss-sanitizer'); - ... - - pattern-inside: | - let { ...,$S,... } = require('express-xss-sanitizer'); - ... - - pattern-inside: | - $S = require("express-xss-sanitizer") - ... - - pattern: $S(...) - - patterns: - - pattern: $RES. ... .type('$F'). ... .send(...) - - metavariable-regex: - metavariable: $F - regex: (?!.*text/html) - - patterns: - - pattern-inside: | - $X = [...]; - ... - - pattern: | - if(<... !$X.includes($SOURCE)...>) { - ... - return ... - } - ... - - pattern: $SOURCE - pattern-sinks: - - patterns: - - pattern-inside: function ... (..., $RES,...) {...} - - pattern-either: - - pattern: $RES.write($ARG) - - pattern: $RES.send($ARG) - - pattern-not: $RES. ... .set('...'). ... .send($ARG) - - pattern-not: $RES. ... .type('...'). ... .send($ARG) - - pattern-not-inside: $RES.$METHOD({ ... }) - - focus-metavariable: $ARG - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options) - - pattern-not-inside: | - function ... ($REQ, $RES) { - ... - $RES.$SET('Content-Type', '$TYPE') - } - - pattern-not-inside: | - $APP.$METHOD(..., function $FUNC($REQ, $RES) { - ... - $RES.$SET('Content-Type', '$TYPE') - }) - - pattern-not-inside: | - function ... ($REQ, $RES, $NEXT) { - ... - $RES.$SET('Content-Type', '$TYPE') - } - - pattern-not-inside: | - function ... ($REQ, $RES) { - ... - $RES.set('$TYPE') - } - - pattern-not-inside: | - $APP.$METHOD(..., function $FUNC($REQ, $RES) { - ... - $RES.set('$TYPE') - }) - - pattern-not-inside: | - function ... ($REQ, $RES, $NEXT) { - ... - $RES.set('$TYPE') - } - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - pattern-not-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - { - ... - $RES.$SET('Content-Type', '$TYPE') - } - - pattern-not-inside: | - ({ $REQ }: Request,$RES: Response) => { - ... - $RES.$SET('Content-Type', '$TYPE') - } - - pattern-not-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - { - ... - $RES.set('$TYPE') - } - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: body - severity: WARNING - - fix-regex: - regex: <%-(.*?)%> - replacement: <%=\1%> - id: javascript.express.security.audit.xss.ejs.explicit-unescape.template-explicit-unescape - languages: - - regex - message: Detected an explicit unescape in an EJS template, using '<%- ... %>' If external data can reach these locations, your application is exposed to a cross-site scripting (XSS) vulnerability. Use '<%= ... %>' to escape this data. If you need escaping, ensure no external data can reach this location. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - http://www.managerjs.com/blog/2015/05/will-ejs-escape-save-me-from-xss-sorta/ - subcategory: - - audit - technology: - - express - paths: - include: - - '*.ejs' - - '*.html' - pattern-regex: <%-((?!include).)*?%> - severity: WARNING - - id: javascript.express.security.audit.xss.ejs.var-in-href.var-in-href - languages: - - regex - message: 'Detected a template variable used in an anchor tag with the ''href'' attribute. This allows a malicious actor to input the ''javascript:'' URI and is subject to cross- site scripting (XSS) attacks. If using a relative URL, start with a literal forward slash and concatenate the URL, like this: href=''/<%= link %>''. You may also consider setting the Content Security Policy (CSP) header.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss#:~:text=javascript:%20URI - - https://github.com/pugjs/pug/issues/2952 - subcategory: - - audit - technology: - - express - paths: - include: - - '*.ejs' - - '*.html' - pattern-regex: ]*?[^\/&=]<%.*?%>.*?> - severity: WARNING - - id: javascript.express.security.audit.xss.ejs.var-in-script-src.var-in-script-src - languages: - - generic - message: Detected a template variable used as the 'src' in a script tag. Although template variables are HTML escaped, HTML escaping does not always prevent malicious URLs from being injected and could results in a cross-site scripting (XSS) vulnerability. Prefer not to dynamically generate the 'src' attribute and use static URLs instead. If you must do this, carefully check URLs against an allowlist and be sure to URL-encode the result. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://www.veracode.com/blog/secure-development/nodejs-template-engines-why-default-encoders-are-not-enough - - https://github.com/ESAPI/owasp-esapi-js - subcategory: - - audit - technology: - - express - paths: - include: - - '*.ejs' - - '*.html' - patterns: - - pattern-inside: - - pattern-not-inside: - - pattern: '{{ ... }}' - severity: WARNING - - id: javascript.express.security.audit.xss.pug.and-attributes.template-and-attributes - languages: - - regex - message: Detected a unescaped variables using '&attributes'. If external data can reach these locations, your application is exposed to a cross-site scripting (XSS) vulnerability. If you must do this, ensure no external data can reach this location. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://pugjs.org/language/attributes.html#attributes - subcategory: - - audit - technology: - - express - paths: - include: - - '*.pug' - pattern-regex: .*&attributes.* - severity: WARNING - - id: javascript.express.security.audit.xss.pug.explicit-unescape.template-explicit-unescape - languages: - - regex - message: Detected an explicit unescape in a Pug template, using either '!=' or '!{...}'. If external data can reach these locations, your application is exposed to a cross-site scripting (XSS) vulnerability. If you must do this, ensure no external data can reach this location. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://pugjs.org/language/code.html#unescaped-buffered-code - - https://pugjs.org/language/attributes.html#unescaped-attributes - subcategory: - - audit - technology: - - express - paths: - include: - - '*.pug' - pattern-either: - - pattern-regex: \w.*(!=)[^=].* - - pattern-regex: '!{.*?}' - severity: WARNING - - id: javascript.express.security.audit.xss.pug.var-in-href.var-in-href - languages: - - regex - message: 'Detected a template variable used in an anchor tag with the ''href'' attribute. This allows a malicious actor to input the ''javascript:'' URI and is subject to cross- site scripting (XSS) attacks. If using a relative URL, start with a literal forward slash and concatenate the URL, like this: a(href=''/''+url). You may also consider setting the Content Security Policy (CSP) header.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://github.com/pugjs/pug/issues/2952 - - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss#:~:text=javascript:%20URI - subcategory: - - audit - technology: - - express - paths: - include: - - '*.pug' - pattern-regex: a\(.*href=[^'"].*\) - severity: WARNING - - id: javascript.express.security.audit.xss.pug.var-in-script-tag.var-in-script-tag - languages: - - regex - message: Detected a template variable used in a script tag. Although template variables are HTML escaped, HTML escaping does not always prevent cross-site scripting (XSS) attacks when used directly in JavaScript. If you need this data on the rendered page, consider placing it in the HTML portion (outside of a script tag). Alternatively, use a JavaScript-specific encoder, such as the one available in OWASP ESAPI. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://www.veracode.com/blog/secure-development/nodejs-template-engines-why-default-encoders-are-not-enough - - https://github.com/ESAPI/owasp-esapi-js - subcategory: - - audit - technology: - - express - paths: - include: - - '*.pug' - pattern-either: - - pattern-regex: script\s*=[A-Za-z0-9]+ - - pattern-regex: script\s*=.*["']\s*\+.* - - pattern-regex: script\s*=[^'"]+\+.* - - pattern-regex: script\(.*?\)\s*=\s*[A-Za-z0-9]+ - - pattern-regex: script\(.*?\)\s*=\s*.*["']\s*\+.* - - pattern-regex: script\(.*?\)\s*=\s*[^'"]+\+.* - severity: WARNING - - id: javascript.express.security.cors-misconfiguration.cors-misconfiguration - languages: - - javascript - - typescript - message: By letting user input control CORS parameters, there is a risk that software does not properly verify that the source of data or communication is valid. Use literal values for CORS settings. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-346: Origin Validation Error' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $RES.set($HEADER, $X) - - pattern: $RES.header($HEADER, $X) - - pattern: $RES.setHeader($HEADER, $X) - - pattern: | - $RES.set({$HEADER: $X}, ...) - - pattern: | - $RES.writeHead($STATUS, {$HEADER: $X}, ...) - - focus-metavariable: $X - - metavariable-regex: - metavariable: $HEADER - regex: .*(Access-Control-Allow-Origin|access-control-allow-origin).* - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.express-data-exfiltration.express-data-exfiltration - languages: - - javascript - - typescript - message: Depending on the context, user control data in `Object.assign` can cause web response to include data that it should not have or can lead to a mass assignment vulnerability. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://en.wikipedia.org/wiki/Mass_assignment_vulnerability - - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html - subcategory: - - audit - technology: - - express - mode: taint - pattern-sinks: - - pattern: Object.assign(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.express-expat-xxe.express-expat-xxe - languages: - - javascript - - typescript - message: Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities. - metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - likelihood: MEDIUM - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://github.com/astro/node-expat - subcategory: - - vuln - technology: - - express - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $XML = require('node-expat') - ... - - pattern-inside: | - import $XML from 'node-expat' - ... - - pattern-inside: | - import * as $XML from 'node-expat' - ... - - pattern-either: - - pattern-inside: | - $PARSER = new $XML.Parser(...); - ... - - pattern-either: - - pattern: $PARSER.parse($QUERY) - - pattern: $PARSER.write($QUERY) - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-insecure-template-usage.express-insecure-template-usage - languages: - - javascript - - typescript - message: User data from `$REQ` is being compiled into the template, which can lead to a Server Side Template Injection (SSTI) vulnerability. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine' - impact: MEDIUM - interfile: true - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - - A01:2017 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html - source_rule_url: - - https://github.com/github/codeql/blob/2ba2642c7ab29b9eedef33bcc2b8cd1d203d0c10/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js - subcategory: - - vuln - technology: - - javascript - - typescript - - express - - pug - - jade - - dot - - ejs - - nunjucks - - lodash - - handlbars - - mustache - - hogan.js - - eta - - squirrelly - mode: taint - options: - interfile: true - pattern-propagators: - - from: $E - pattern: $MODEL.$FIND($E).then((...,$S,...)=>{...}) - to: $S - pattern-sinks: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('pug') - ... - - pattern-inside: | - import * as $PUG from 'pug' - ... - - pattern-inside: | - $PUG = require('jade') - ... - - pattern-inside: | - import * as $PUG from 'jade' - ... - - pattern-either: - - pattern: $PUG.compile(...) - - pattern: $PUG.compileClient(...) - - pattern: $PUG.compileClientWithDependenciesTracked(...) - - pattern: $PUG.render(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('dot') - ... - - pattern-inside: | - import * as $PUG from 'dot' - ... - - pattern-either: - - pattern: $PUG.template(...) - - pattern: $PUG.compile(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('ejs') - ... - - pattern-inside: | - import * as $PUG from 'ejs' - ... - - pattern-either: - - pattern: $PUG.render(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('nunjucks') - ... - - pattern-inside: | - import * as $PUG from 'nunjucks' - ... - - pattern-either: - - pattern: $PUG.renderString(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('lodash') - ... - - pattern-inside: | - import * as $PUG from 'lodash' - ... - - pattern-either: - - pattern: $PUG.template(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('mustache') - ... - - pattern-inside: | - import * as $PUG from 'mustache' - ... - - pattern-inside: | - $PUG = require('eta') - ... - - pattern-inside: | - import * as $PUG from 'eta' - ... - - pattern-inside: | - $PUG = require('squirrelly') - ... - - pattern-inside: | - import * as $PUG from 'squirrelly' - ... - - pattern-either: - - pattern: $PUG.render(...) - - patterns: - - pattern-either: - - pattern-inside: | - $PUG = require('hogan.js') - ... - - pattern-inside: | - import * as $PUG from 'hogan.js' - ... - - pattern-inside: | - $PUG = require('handlebars') - ... - - pattern-inside: | - import * as $PUG from 'handlebars' - ... - - pattern-either: - - pattern: $PUG.compile(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.express-jwt-hardcoded-secret.express-jwt-hardcoded-secret - languages: - - javascript - - typescript - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - likelihood: HIGH - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - subcategory: - - audit - technology: - - express - - secrets - options: - interfile: true - patterns: - - pattern-either: - - pattern-inside: | - $JWT = require('express-jwt'); - ... - - pattern-inside: | - import $JWT from 'express-jwt'; - ... - - pattern-inside: | - import * as $JWT from 'express-jwt'; - ... - - pattern-inside: | - import { ..., $JWT, ... } from 'express-jwt'; - ... - - pattern-either: - - pattern: | - $JWT({...,secret: "$Y",...},...) - - pattern: | - $OPTS = "$Y"; - ... - $JWT({...,secret: $OPTS},...); - - focus-metavariable: $Y - severity: WARNING - - id: javascript.express.security.express-phantom-injection.express-phantom-injection - languages: - - javascript - - typescript - message: If unverified user data can reach the `phantom` methods it can result in Server-Side Request Forgery vulnerabilities - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://phantomjs.org/page-automation.html - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('phantom'); - ... - - pattern-inside: | - import 'phantom'; - ... - - pattern-either: - - pattern: $PAGE.open($SINK,...) - - pattern: $PAGE.setContent($SINK,...) - - pattern: $PAGE.openUrl($SINK,...) - - pattern: $PAGE.evaluateJavaScript($SINK,...) - - pattern: $PAGE.property("content",$SINK,...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-puppeteer-injection.express-puppeteer-injection - languages: - - javascript - - typescript - message: If unverified user data can reach the `puppeteer` methods it can result in Server-Side Request Forgery vulnerabilities - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://pptr.dev/api/puppeteer.page - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('puppeteer'); - ... - - pattern-inside: | - import 'puppeteer'; - ... - - pattern-either: - - pattern: $PAGE.goto($SINK,...) - - pattern: $PAGE.setContent($SINK,...) - - pattern: $PAGE.evaluate($SINK,...) - - pattern: $PAGE.evaluate($CODE,$SINK,...) - - pattern: $PAGE.evaluateHandle($SINK,...) - - pattern: $PAGE.evaluateHandle($CODE,$SINK,...) - - pattern: $PAGE.evaluateOnNewDocument($SINK,...) - - pattern: $PAGE.evaluateOnNewDocument($CODE,$SINK,...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-sandbox-injection.express-sandbox-code-injection - languages: - - javascript - - typescript - message: Make sure that unverified user data can not reach `sandbox`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - $SANDBOX = require('sandbox'); - ... - - pattern-either: - - patterns: - - pattern-inside: | - $S = new $SANDBOX(...); - ... - - pattern: | - $S.run(...) - - pattern: | - new $SANDBOX($OPTS).run(...) - - pattern: new $SANDBOX().run(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-vm-injection.express-vm-injection - languages: - - javascript - - typescript - message: Make sure that unverified user data can not reach `$VM`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - $VM = require('vm'); - ... - - pattern-either: - - pattern: | - $VM.runInContext(...) - - pattern: | - $VM.runInNewContext(...) - - pattern: | - $VM.compileFunction(...) - - pattern: | - $VM.runInThisContext(...) - - pattern: new $VM.Script(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-vm2-injection.express-vm2-injection - languages: - - javascript - - typescript - message: Make sure that unverified user data can not reach `vm2`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - require('vm2') - ... - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - $VM = new VM(...) - ... - - pattern-inside: | - $VM = new NodeVM(...) - ... - - pattern: | - $VM.run(...) - - pattern: | - new VM(...).run(...) - - pattern: | - new NodeVM(...).run(...) - - pattern: | - new VMScript(...) - - pattern: | - new VM(...) - - pattern: new NodeVM(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.express.security.express-wkhtml-injection.express-wkhtmltoimage-injection - languages: - - javascript - - typescript - message: If unverified user data can reach the `phantom` methods it can result in Server-Side Request Forgery vulnerabilities - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://www.npmjs.com/package/wkhtmltopdf - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern: $WK.generate($SINK,...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-wkhtml-injection.express-wkhtmltopdf-injection - languages: - - javascript - - typescript - message: If unverified user data can reach the `wkhtmltopdf` methods it can result in Server-Side Request Forgery vulnerabilities - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://www.npmjs.com/package/wkhtmltopdf - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - $WK = require('wkhtmltopdf'); - ... - - pattern: $WK($SINK,...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.express-xml2json-xxe.express-xml2json-xxe - languages: - - javascript - - typescript - message: Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities - metadata: - asvs: - control_id: 5.5.2 Insecue XML Deserialization - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention - section: V5 Validation, Sanitization and Encoding - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://www.npmjs.com/package/xml2json - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('xml2json'); - ... - - pattern-inside: | - import 'xml2json'; - ... - - pattern: $EXPAT.toJson($SINK,...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - pattern: $REQ.files.$ANYTHING.data.toString('utf8') - - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - pattern: files.$ANYTHING.data.toString('utf8') - - pattern: files.$ANYTHING['data'].toString('utf8') - severity: ERROR - - id: javascript.express.security.injection.raw-html-format.raw-html-format - languages: - - javascript - - typescript - message: User data flows into the host portion of this manually-constructed HTML. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. Consider using a sanitization library such as DOMPurify to sanitize the HTML within. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: '"$HTMLSTR" + $EXPR' - - pattern: '"$HTMLSTR".concat(...)' - - pattern: util.format($HTMLSTR, ...) - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - - patterns: - - pattern: | - `...` - - pattern-regex: | - .*<\w+.* - requires: (EXPRESS and not CLEAN) or (EXPRESSTS and not CLEAN) - pattern-sources: - - label: EXPRESS - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - label: EXPRESSTS - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - by-side-effect: true - label: CLEAN - patterns: - - pattern-either: - - pattern: $A($SOURCE) - - pattern: $SANITIZE. ... .$A($SOURCE) - - pattern: $A. ... .$SANITIZE($SOURCE) - - focus-metavariable: $SOURCE - - metavariable-regex: - metavariable: $A - regex: (?i)(.*valid|.*sanitiz) - severity: WARNING - - id: javascript.express.security.injection.tainted-sql-string.tainted-sql-string - languages: - - javascript - - typescript - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/SQL_Injection - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - "$SQLSTR" + $EXPR - - pattern-inside: | - "$SQLSTR".concat($EXPR) - - pattern: util.format($SQLSTR, $EXPR) - - pattern: | - `$SQLSTR${$EXPR}...` - - metavariable-regex: - metavariable: $SQLSTR - regex: .*\b(?i)(select|delete|insert|create|update\s+.+\sset|alter|drop)\b.* - - focus-metavariable: $EXPR - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... (...,$REQ, ...) {...} - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - (...,{ $REQ }: Request,...) => {...} - - pattern-inside: | - (...,{ $REQ }: $EXPRESS.Request,...) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.require-request.require-request - languages: - - javascript - - typescript - message: If an attacker controls the x in require(x) then they can cause code to load that was not intended to run on the server. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-706: Use of Incorrectly-Resolved Name or Reference' - impact: MEDIUM - interfile: true - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://github.com/google/node-sec-roadmap/blob/master/chapter-2/dynamism.md#dynamism-when-you-need-it - source-rule-url: https://nodesecroadmap.fyi/chapter-1/threat-UIR.html - subcategory: - - vuln - technology: - - express - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern: require($SINK) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: ERROR - - id: javascript.express.security.x-frame-options-misconfiguration.x-frame-options-misconfiguration - languages: - - javascript - - typescript - message: By letting user input control `X-Frame-Options` header, there is a risk that software does not properly verify whether or not a browser should be allowed to render a page in an `iframe`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-451: User Interface (UI) Misrepresentation of Critical Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A04:2021 - Insecure Design - references: - - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options - subcategory: - - vuln - technology: - - express - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $RES.set($HEADER, ...) - - pattern: $RES.header($HEADER, ...) - - pattern: $RES.setHeader($HEADER, ...) - - pattern: | - $RES.set({$HEADER: ...}, ...) - - pattern: | - $RES.writeHead($STATUS, {$HEADER: ...}, ...) - - metavariable-regex: - metavariable: $HEADER - regex: .*(X-Frame-Options|x-frame-options).* - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - severity: WARNING - - id: javascript.fbjs.security.audit.insecure-createnodesfrommarkup.insecure-createnodesfrommarkup - languages: - - javascript - - typescript - message: User controlled data in a `createNodesFromMarkup` is an anti-pattern that can lead to XSS vulnerabilities - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - fbjs - patterns: - - pattern-either: - - pattern: createNodesFromMarkup(...) - - pattern: $X.createNodesFromMarkup(...) - - pattern-not: createNodesFromMarkup("...",...) - - pattern-not: $X.createNodesFromMarkup("...",...) - severity: WARNING - - id: javascript.grpc.security.grpc-nodejs-insecure-connection.grpc-nodejs-insecure-connection - languages: - - javascript - - typescript - message: Found an insecure gRPC connection. This creates a connection without encryption to a gRPC client/server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://blog.gopheracademy.com/advent-2017/go-grpc-beyond-basics/#:~:text=disables%20transport%20security - subcategory: - - audit - technology: - - grpc - pattern-either: - - pattern: | - require('grpc'); - ... - $GRPC($ADDR,...,$CREDENTIALS.createInsecure(),...); - - pattern: | - require('grpc'); - ... - new $GRPC($ADDR,...,$CREDENTIALS.createInsecure(),...); - - pattern: |- - require('grpc'); - ... - $CREDS = <... $CREDENTIALS.createInsecure() ...>; - ... - $GRPC($ADDR,...,$CREDS,...); - - pattern: |- - require('grpc'); - ... - $CREDS = <... $CREDENTIALS.createInsecure() ...>; - ... - new $GRPC($ADDR,...,$CREDS,...); - severity: ERROR - - id: javascript.intercom.security.audit.intercom-settings-user-identifier-without-user-hash.intercom-settings-user-identifier-without-user-hash - languages: - - js - message: Found an initialization of the Intercom Messenger that identifies a User, but does not specify a `user_hash`.This configuration allows users to impersonate one another. See the Intercom Identity Verification docs for more context https://www.intercom.com/help/en/articles/183-set-up-identity-verification-for-web-and-mobile - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-287: Improper Authentication' - impact: HIGH - likelihood: MEDIUM - references: - - https://www.intercom.com/help/en/articles/183-set-up-identity-verification-for-web-and-mobile - subcategory: - - guardrail - technology: - - intercom - patterns: - - pattern-either: - - pattern: | - window.intercomSettings = {..., email: $EMAIL, ...}; - - pattern: | - window.intercomSettings = {..., user_id: $USER_ID, ...}; - - pattern: | - Intercom('boot', {..., email: $EMAIL, ...}); - - pattern: | - Intercom('boot', {..., user_id: $USER_ID, ...}); - - pattern: | - $VAR = {..., email: $EMAIL, ...}; - ... - Intercom('boot', $VAR); - - pattern: | - $VAR = {..., user_id: $EMAIL, ...}; - ... - Intercom('boot', $VAR); - - pattern-not: | - window.intercomSettings = {..., user_hash: $USER_HASH, ...}; - - pattern-not: | - Intercom('boot', {..., user_hash: $USER_HASH, ...}); - - pattern-not: | - $VAR = {..., user_hash: $USER_HASH, ...}; - ... - Intercom('boot', $VAR); - severity: WARNING - - id: javascript.jose.security.audit.jose-exposed-data.jose-exposed-data - languages: - - javascript - - typescript - message: The object is passed strictly to jose.JWT.sign(...) Make sure that sensitive information is not exposed through JWT token payload. - metadata: - asvs: - control_id: 3.5.2 Static API keys or secret - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jose - - jwt - patterns: - - pattern-inside: | - require('jose'); - ... - - pattern-either: - - patterns: - - pattern-inside: function (...,$INPUT,...) {...} - - pattern-either: - - pattern: $JOSE.JWT.sign($INPUT,...) - - pattern: $JWT.sign($INPUT,...) - - patterns: - - pattern-inside: function $F(...,$INPUT,...) {...} - - pattern-either: - - pattern: $JOSE.JWT.sign($INPUT,...) - - pattern: $JWT.sign($INPUT,...) - severity: WARNING - - id: javascript.jose.security.jwt-hardcode.hardcoded-jwt-secret - languages: - - javascript - - typescript - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - asvs: - control_id: 3.5.2 Static API keys or secret - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - interfile: true - likelihood: HIGH - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - subcategory: - - vuln - technology: - - jose - - jwt - - secrets - options: - interfile: true - symbolic_propagation: true - patterns: - - pattern-inside: | - $JOSE = require("jose"); - ... - - pattern-either: - - pattern-inside: | - var {JWT} = $JOSE; - ... - - pattern-inside: | - var {JWK, JWT} = $JOSE; - ... - - pattern-inside: | - const {JWT} = $JOSE; - ... - - pattern-inside: | - const {JWK, JWT} = $JOSE; - ... - - pattern-inside: | - let {JWT} = $JOSE; - ... - - pattern-inside: | - let {JWK, JWT} = $JOSE; - ... - - pattern-either: - - pattern: | - JWT.verify($P, "...", ...); - - pattern: | - JWT.sign($P, "...", ...); - - pattern: "JWT.verify($P, JWK.asKey(\"...\"), ...); \n" - - pattern: | - $JWT.sign($P, JWK.asKey("..."), ...); - severity: WARNING - - id: javascript.jose.security.jwt-none-alg.jwt-none-alg - languages: - - javascript - - typescript - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. - metadata: - asvs: - control_id: 3.5.3 Insecue Stateless Session Tokens - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - vuln - technology: - - jose - - jwt - pattern-either: - - pattern: | - var $JOSE = require("jose"); - ... - var { JWK, JWT } = $JOSE; - ... - var $T = JWT.verify($P, JWK.None,...); - - pattern: | - var $JOSE = require("jose"); - ... - var { JWK, JWT } = $JOSE; - ... - $T = JWT.verify($P, JWK.None,...); - - pattern: | - var $JOSE = require("jose"); - ... - var { JWK, JWT } = $JOSE; - ... - JWT.verify($P, JWK.None,...); - severity: ERROR - - id: javascript.jquery.security.audit.jquery-insecure-method.jquery-insecure-method - languages: - - javascript - - typescript - message: User controlled data in a jQuery's `.$METHOD(...)` is an anti-pattern that can lead to XSS vulnerabilities - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/xss/ - - https://bugs.jquery.com/ticket/9521 - subcategory: - - audit - technology: - - jquery - options: - symbolic_propagation: true - pattern-either: - - patterns: - - pattern-either: - - pattern: $.$METHOD($VAR,...) - - pattern: $(...).$METHOD($VAR,...) - - pattern: jQuery.$METHOD($VAR,...) - - pattern: jQuery(...).$METHOD($VAR,...) - - pattern-not: $.$METHOD("...",...) - - pattern-not: $(...).$METHOD("...",...) - - pattern-not: jQuery.$METHOD("...",...) - - pattern-not: jQuery(...).$METHOD("...",...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(html|append|prepend|wrap|wrapInner|wrapAll|before|after|globalEval|getScript)$ - - patterns: - - pattern-either: - - pattern: $(...).$METHOD($VAR,...) - - pattern: jQuery(...).$METHOD($VAR,...) - - pattern-not: $("...",...).$METHOD(...) - - pattern-not: jQuery("...",...).$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(appendTo|insertAfter|insertBefore|prependTo)$ - severity: WARNING - - id: javascript.jquery.security.audit.jquery-insecure-selector.jquery-insecure-selector - languages: - - javascript - - typescript - message: User controlled data in a `$(...)` is an anti-pattern that can lead to XSS vulnerabilities - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/xss/ - - https://bugs.jquery.com/ticket/9521 - subcategory: - - audit - technology: - - jquery - patterns: - - pattern-either: - - pattern: | - $(<... window ...>) - - pattern: | - $(<... location ...>) - - patterns: - - pattern: | - $X = <... window ...>; - ... - $(<... $X ...>); - - focus-metavariable: $X - - patterns: - - pattern: | - $X = <... location ...>; - ... - $(<... $X ...>); - - focus-metavariable: $X - - patterns: - - pattern-either: - - pattern-inside: | - function $FUNC(..., $Y, ...) { - ... - } - - pattern-inside: | - function (..., $Y, ...) { - ... - } - - pattern-inside: | - function $FUNC(...,$Z,...) { - ... - $Y = <... $Z ...>; - ... - } - - pattern-inside: | - function (...,$Z,...) { - ... - $Y = <... $Z ...>; - ... - } - - pattern-either: - - pattern: | - $(<... $Y ...>) - - pattern: | - $("..." + (<... $Y ...>)) - - pattern: | - $((<... $Y ...>) + "...") - - pattern-not-inside: | - $JQUERY.each(function($INDEX, $Y) { - ... - }) - - focus-metavariable: $Y - - pattern-not: | - $(window) - - pattern-not: | - $(document) - - pattern-not: | - $(this) - severity: WARNING - - id: javascript.jquery.security.audit.prohibit-jquery-html.prohibit-jquery-html - languages: - - javascript - - typescript - message: JQuery's `html` function is susceptible to Cross Site Scripting (XSS) attacks. If you're just passing text, consider `text` instead. Otherwise, use a function that escapes HTML such as edX's `HtmlUtils.setHtml()`. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - help: | - ## Remediation - Avoid using JQuery's html() function. If the string is plain text, use the text() function instead. - Otherwise, use a function that escapes html such as edx's HtmlUtils.setHtml(). - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - precision: high - references: - - https://edx.readthedocs.io/projects/edx-developer-guide/en/latest/preventing_xss/preventing_xss.html#javascript-concat-html - - https://stackoverflow.com/questions/8318581/html-vs-innerhtml-jquery-javascript-xss-attacks - - https://api.jquery.com/text/#text-text - shortDesription: Use of JQuery's unsafe html() function. - subcategory: - - audit - tags: - - security - technology: - - jquery - patterns: - - pattern: | - $X.html(...) - - pattern-not: | - $X.html("...",...) - severity: WARNING - - id: javascript.jsonwebtoken.security.audit.jwt-decode-without-verify.jwt-decode-without-verify - languages: - - javascript - - typescript - message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token. - metadata: - asvs: - control_id: 3.5.3 Insecue Stateless Session Tokens - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-345: Insufficient Verification of Data Authenticity' - impact: LOW - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - patterns: - - pattern-inside: | - $JWT = require('jsonwebtoken'); - ... - - pattern-not-inside: | - ... - $JWT.verify($TOKEN, ...) - ... - - pattern-not-inside: | - ... - if (<... $JWT.verify($TOKEN, ...) ...>) { ... } - ... - - pattern: $JWT.decode($TOKEN, ...) - severity: WARNING - - id: javascript.jsonwebtoken.security.audit.jwt-exposed-data.jwt-exposed-data - languages: - - javascript - - typescript - message: The object is passed strictly to jsonwebtoken.sign(...) Make sure that sensitive information is not exposed through JWT token payload. - metadata: - asvs: - control_id: 3.5.3 Insecue Stateless Session Tokens - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - patterns: - - pattern-inside: | - $JWT = require('jsonwebtoken'); - ... - - pattern-either: - - pattern-inside: function (...,$INPUT,...) {...} - - pattern-inside: function $F(...,$INPUT,...) {...} - - pattern: $JWT.sign($INPUT,...) - severity: WARNING - - id: javascript.jsonwebtoken.security.jwt-hardcode.hardcoded-jwt-secret - languages: - - javascript - - typescript - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - asvs: - control_id: 3.5.2 Static API keys or secret - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: HIGH - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - subcategory: - - vuln - technology: - - jwt - - javascript - - secrets - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $JWT = require("jsonwebtoken") - ... - - pattern-inside: | - import $JWT from "jsonwebtoken" - ... - - pattern-inside: | - import * as $JWT from "jsonwebtoken" - ... - - pattern-inside: | - import {...,$JWT,...} from "jsonwebtoken" - ... - - pattern-either: - - pattern-inside: | - $JWT.sign($DATA,$VALUE,...); - - pattern-inside: | - $JWT.verify($DATA,$VALUE,...); - - focus-metavariable: $VALUE - pattern-sources: - - patterns: - - pattern: "$X = '...' \n" - - pattern: "$X = '$Y' \n" - - patterns: - - pattern-either: - - pattern-inside: | - $JWT.sign($DATA,"...",...); - - pattern-inside: | - $JWT.verify($DATA,"...",...); - severity: WARNING - - id: javascript.jsonwebtoken.security.jwt-none-alg.jwt-none-alg - languages: - - javascript - - typescript - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. - metadata: - asvs: - control_id: 3.5.3 Insecue Stateless Session Tokens - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - vuln - technology: - - jwt - patterns: - - pattern-inside: | - $JWT = require("jsonwebtoken"); - ... - - pattern: $JWT.verify($P, $X, {algorithms:[...,'none',...]},...) - severity: ERROR - - id: javascript.jwt-simple.security.jwt-simple-noverify.jwt-simple-noverify - languages: - - javascript - - typescript - message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Set 'verify' to `true` before using the token. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-287: Improper Authentication' - - 'CWE-345: Insufficient Verification of Data Authenticity' - - 'CWE-347: Improper Verification of Cryptographic Signature' - impact: HIGH - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - - A07:2021 - Identification and Authentication Failures - references: - - https://www.npmjs.com/package/jwt-simple - - https://cwe.mitre.org/data/definitions/287 - - https://cwe.mitre.org/data/definitions/345 - - https://cwe.mitre.org/data/definitions/347 - subcategory: - - vuln - technology: - - jwt-simple - - jwt - patterns: - - pattern-inside: | - $JWT = require('jwt-simple'); - ... - - pattern: $JWT.decode($TOKEN, $SECRET, $NOVERIFY, ...) - - metavariable-pattern: - metavariable: $NOVERIFY - patterns: - - pattern-either: - - pattern: | - true - - pattern: | - "..." - severity: ERROR - - id: javascript.lang.best-practice.assigned-undefined.assigned-undefined - languages: - - javascript - - typescript - message: '`undefined` is not a reserved keyword in Javascript, so this is "valid" Javascript but highly confusing and likely to result in bugs.' - metadata: - category: best-practice - technology: - - javascript - pattern-either: - - pattern: undefined = $X; - - pattern: var undefined = $X; - - pattern: let undefined = $X; - - pattern: const undefined = $X; - severity: WARNING - - id: javascript.lang.best-practice.lazy-load-module.lazy-load-module - languages: - - javascript - - typescript - message: Lazy loading can complicate code bundling if care is not taken, also `require`s are run synchronously by Node.js. If they are called from within a function, it may block other requests from being handled at a more critical time. The best practice is to `require` modules at the beginning of each file, before and outside of any functions. - metadata: - category: best-practice - references: - - https://nodesecroadmap.fyi/chapter-2/dynamism.html - - https://github.com/goldbergyoni/nodebestpractices#-38-require-modules-first-not-inside-functions - technology: - - javascript - patterns: - - pattern: require(...) - - pattern-inside: | - function $NAME(...) { - ... - } - severity: WARNING - - id: javascript.lang.best-practice.leftover_debugging.javascript-alert - languages: - - javascript - - typescript - message: found alert() call; should this be in production code? - metadata: - category: best-practice - technology: - - javascript - pattern-either: - - pattern: alert() - - pattern: alert($X) - severity: WARNING - - id: javascript.lang.best-practice.leftover_debugging.javascript-debugger - languages: - - javascript - - typescript - message: found debugger call; should this be in production code? - metadata: - category: best-practice - technology: - - javascript - pattern: debugger; - severity: WARNING - - id: javascript.lang.best-practice.leftover_debugging.javascript-confirm - languages: - - javascript - - typescript - message: found confirm() call; should this be in production code? - metadata: - category: best-practice - technology: - - javascript - pattern: confirm(...) - severity: WARNING - - id: javascript.lang.best-practice.leftover_debugging.javascript-prompt - languages: - - javascript - - typescript - message: found prompt() call; should this be in production code? - metadata: - category: best-practice - technology: - - javascript - pattern-either: - - pattern: prompt() - - pattern: prompt($X) - - pattern: prompt($X, $Y) - severity: WARNING - - id: javascript.lang.best-practice.zlib-async-loop.zlib-async-loop - languages: - - javascript - - typescript - message: Creating and using a large number of zlib objects simultaneously can cause significant memory fragmentation. It is strongly recommended that the results of compression operations be cached or made synchronous to avoid duplication of effort. - metadata: - category: best-practice - references: - - https://nodejs.org/api/zlib.html#zlib_threadpool_usage_and_performance_considerations - technology: - - javascript - patterns: - - pattern-either: - - pattern-inside: | - for (...) { - ... - } - - pattern-inside: | - while (...) { - ... - } - - pattern-inside: | - do { - ... - } while (...) - - pattern-inside: | - $SMTH.forEach(...) - - pattern-inside: | - $SMTH.map(...) - - pattern-inside: | - $SMTH.reduce(...) - - pattern-inside: | - $SMTH.reduceRight(...) - - pattern: zlib.$METHOD(...); - - metavariable-regex: - metavariable: $METHOD - regex: ^.+$(?; - severity: INFO - - id: javascript.lang.correctness.useless-eqeq.eqeq-is-bad - languages: - - javascript - - typescript - message: Detected a useless comparison operation `$X == $X` or `$X != $X`. This operation is always true. If testing for floating point NaN, use `math.isnan`, or `cmath.isnan` if the number is complex. - metadata: - category: correctness - technology: - - javascript - patterns: - - pattern-not-inside: assert(...) - - pattern-either: - - pattern: $X == $X - - pattern: $X != $X - - pattern-not: 1 == 1 - severity: INFO - - id: javascript.lang.security.audit.code-string-concat.code-string-concat - languages: - - javascript - - typescript - message: Found data from an Express or Next web request flowing to `eval`. If this data is user-controllable this can lead to execution of arbitrary system commands in the context of your application process. Avoid `eval` whenever possible. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: MEDIUM - interfile: true - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval - - https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback - - https://www.stackhawk.com/blog/nodejs-command-injection-examples-and-prevention/ - - https://ckarande.gitbooks.io/owasp-nodegoat-tutorial/content/tutorial/a1_-_server_side_js_injection.html - subcategory: - - vuln - technology: - - node.js - - Express - - Next.js - mode: taint - options: - interfile: true - pattern-sinks: - - patterns: - - pattern: | - eval(...) - pattern-sources: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options)$ - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - patterns: - - pattern-either: - - pattern-inside: | - import { ...,$IMPORT,... } from 'next/router' - ... - - pattern-inside: | - import $IMPORT from 'next/router'; - ... - - pattern-either: - - patterns: - - pattern-inside: | - $ROUTER = $IMPORT() - ... - - pattern-either: - - pattern-inside: | - const { ...,$PROPS,... } = $ROUTER.query - ... - - pattern-inside: | - var { ...,$PROPS,... } = $ROUTER.query - ... - - pattern-inside: | - let { ...,$PROPS,... } = $ROUTER.query - ... - - focus-metavariable: $PROPS - - patterns: - - pattern-inside: | - $ROUTER = $IMPORT() - ... - - pattern: "$ROUTER.query.$VALUE \n" - - patterns: - - pattern: $IMPORT().query.$VALUE - severity: ERROR - - id: javascript.lang.security.audit.dangerous-spawn-shell.dangerous-spawn-shell - languages: - - javascript - - typescript - message: Detected non-literal calls to $EXEC(). This could lead to a command injection vulnerability. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#do-not-use-dangerous-functions - source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-child-process.js - subcategory: - - vuln - technology: - - javascript - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('child_process') - ... - - pattern-inside: | - import 'child_process' - ... - - pattern-either: - - pattern: spawn(...) - - pattern: spawnSync(...) - - pattern: $CP.spawn(...) - - pattern: $CP.spawnSync(...) - - pattern-either: - - pattern: | - $EXEC("=~/(sh|bash|ksh|csh|tcsh|zsh)/",["-c", $ARG, ...],...) - - patterns: - - pattern: $EXEC($CMD,["-c", $ARG, ...],...) - - pattern-inside: | - $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/" - ... - - pattern: | - $EXEC("=~/(sh|bash|ksh|csh|tcsh|zsh)/",[$ARG, ...],...) - - patterns: - - pattern: $EXEC($CMD,[$ARG, ...],...) - - pattern-inside: | - $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/" - ... - - focus-metavariable: $ARG - pattern-sources: - - patterns: - - pattern-inside: | - function ... (...,$FUNC,...) { - ... - } - - focus-metavariable: $FUNC - severity: ERROR - - id: javascript.lang.security.audit.detect-non-literal-fs-filename.detect-non-literal-fs-filename - languages: - - typescript - - javascript - message: Detected that function argument `$ARG` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are validated. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-fs-filename.js - subcategory: - - vuln - technology: - - typescript - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $FS = require('fs') - ... - - pattern-inside: | - $FS = require('fs/promises') - ... - - pattern-inside: | - import * as $FS from 'fs' - ... - - pattern-inside: | - import $FS from 'fs' - ... - - pattern-inside: | - import * as $FS from 'fs/promises' - ... - - pattern-inside: | - import $FS from 'fs/promises' - ... - - pattern-not: $FS. ... .$METHOD("...", ...) - - pattern-either: - - pattern: $FS. ... .access($FILE,...) - - pattern: $FS. ... .appendFile($FILE,...) - - pattern: $FS. ... .chmod($FILE,...) - - pattern: $FS. ... .chown($FILE,...) - - pattern: $FS. ... .close($FILE,...) - - pattern: $FS. ... .copyFile($FILE,...) - - pattern: $FS. ... .copyFile($SMTH, $FILE,...) - - pattern: $FS. ... .cp($FILE, ...) - - pattern: $FS. ... .cp($SMTH, $FILE, ...) - - pattern: $FS. ... .createReadStream($FILE,...) - - pattern: $FS. ... .createWriteStream($FILE,...) - - pattern: $FS. ... .exists($FILE, ...) - - pattern: $FS. ... .fchmod($FILE, ...) - - pattern: $FS. ... .fchown($FILE, ...) - - pattern: $FS. ... .fdatasync($FILE, ...) - - pattern: $FS. ... .fstat($FILE, ...) - - pattern: $FS. ... .fsync($FILE, ...) - - pattern: $FS. ... .ftruncate($FILE, ...) - - pattern: $FS. ... .futimes($FILE, ...) - - pattern: $FS. ... .lchmod($FILE, ...) - - pattern: $FS. ... .lchown($FILE, ...) - - pattern: $FS. ... .lutimes($FILE, ...) - - pattern: $FS. ... .link($FILE, ...) - - pattern: $FS. ... .link($SMTH, $FILE, ...) - - pattern: $FS. ... .lstat($FILE, ...) - - pattern: $FS. ... .mkdir($FILE, ...) - - pattern: $FS. ... .mkdtemp($FILE, ...) - - pattern: $FS. ... .open($FILE, ...) - - pattern: $FS. ... .opendir($FILE, ...) - - pattern: $FS. ... .read($FILE, ...) - - pattern: $FS. ... .read($FILE, ...) - - pattern: $FS. ... .readdir($FILE, ...) - - pattern: $FS. ... .readFile($FILE, ...) - - pattern: $FS. ... .readlink($FILE, ...) - - pattern: $FS. ... .readv($FILE, ...) - - pattern: $FS. ... .realpath($FILE, ...) - - pattern: $FS. ... .realpath.native($FILE, ...) - - pattern: $FS. ... .rename($FILE, ...) - - pattern: $FS. ... .rename($SMTH, $FILE, ...) - - pattern: $FS. ... .rmdir($FILE, ...) - - pattern: $FS. ... .rm($FILE, ...) - - pattern: $FS. ... .stat($FILE, ...) - - pattern: $FS. ... .symlink($SMTH, $FILE, ...) - - pattern: $FS. ... .symlink($FILE, ...) - - pattern: $FS. ... .truncate($FILE, ...) - - pattern: $FS. ... .unlink($FILE, ...) - - pattern: $FS. ... .unwatchFile($FILE, ...) - - pattern: $FS. ... .utimes($FILE, ...) - - pattern: $FS. ... .watch($FILE, ...) - - pattern: $FS. ... .watchFile($FILE, ...) - - pattern: $FS. ... .write($FILE, ...) - - pattern: $FS. ... .writeFile($FILE, ...) - - pattern: $FS. ... .writev($FILE, ...) - - pattern: $FS. ... .accessSync($FILE, ...) - - pattern: $FS. ... .appendFileSync($FILE, ...) - - pattern: $FS. ... .chmodSync($FILE, ...) - - pattern: $FS. ... .chownSync($FILE, ...) - - pattern: $FS. ... .closeSync($FILE, ...) - - pattern: $FS. ... .copyFileSync($FILE, ...) - - pattern: $FS. ... .copyFileSync($SMTH, $FILE, ...) - - pattern: $FS. ... .cpSync($FILE, ...) - - pattern: $FS. ... .cpSync($SMTH, $FILE, ...) - - pattern: $FS. ... .existsSync($FILE, ...) - - pattern: $FS. ... .fchmodSync($FILE, ...) - - pattern: $FS. ... .fchownSync($FILE, ...) - - pattern: $FS. ... .fdatasyncSync($FILE, ...) - - pattern: $FS. ... .fstatSync($FILE, ...) - - pattern: $FS. ... .fsyncSync($FILE, ...) - - pattern: $FS. ... .ftruncateSync($FILE, ...) - - pattern: $FS. ... .futimesSync($FILE, ...) - - pattern: $FS. ... .lchmodSync($FILE, ...) - - pattern: $FS. ... .lchownSync($FILE, ...) - - pattern: $FS. ... .lutimesSync($FILE, ...) - - pattern: $FS. ... .linkSync($FILE, ...) - - pattern: $FS. ... .linkSync($SMTH, $FILE, ...) - - pattern: $FS. ... .lstatSync($FILE, ...) - - pattern: $FS. ... .mkdirSync($FILE, ...) - - pattern: $FS. ... .mkdtempSync($FILE, ...) - - pattern: $FS. ... .opendirSync($FILE, ...) - - pattern: $FS. ... .openSync($FILE, ...) - - pattern: $FS. ... .readdirSync($FILE, ...) - - pattern: $FS. ... .readFileSync($FILE, ...) - - pattern: $FS. ... .readlinkSync($FILE, ...) - - pattern: $FS. ... .readSync($FILE, ...) - - pattern: $FS. ... .readSync($FILE, ...) - - pattern: $FS. ... .readvSync($FILE, ...) - - pattern: $FS. ... .realpathync($FILE, ...) - - pattern: $FS. ... .realpathSync.native($FILE, ...) - - pattern: $FS. ... .renameSync($FILE, ...) - - pattern: $FS. ... .renameSync($SMTH, $FILE, ...) - - pattern: $FS. ... .rmdirSync($FILE, ...) - - pattern: $FS. ... .rmSync($FILE, ...) - - pattern: $FS. ... .statSync($FILE, ...) - - pattern: $FS. ... .symlinkSync($FILE, ...) - - pattern: $FS. ... .symlinkSync($SMTH, $FILE, ...) - - pattern: $FS. ... .truncateSync($FILE, ...) - - pattern: $FS. ... .unlinkSync($FILE, ...) - - pattern: $FS. ... .utimesSync($FILE, ...) - - pattern: $FS. ... .writeFileSync($FILE, ...) - - pattern: $FS. ... .writeSync($FILE, ...) - - pattern: $FS. ... .writevSync($FILE, ...) - - focus-metavariable: $FILE - - patterns: - - pattern-either: - - pattern-inside: | - import 'fs' - ... - - pattern-inside: | - import 'fs/promises' - ... - - pattern-not: $METHOD("...", ...) - - pattern-either: - - pattern: access($FILE,...) - - pattern: appendFile($FILE,...) - - pattern: chmod($FILE,...) - - pattern: chown($FILE,...) - - pattern: close($FILE,...) - - pattern: copyFile($FILE,...) - - pattern: copyFile($SMTH, $FILE,...) - - pattern: cp($FILE, ...) - - pattern: cp($SMTH, $FILE, ...) - - pattern: createReadStream($FILE,...) - - pattern: createWriteStream($FILE,...) - - pattern: exists($FILE, ...) - - pattern: fchmod($FILE, ...) - - pattern: fchown($FILE, ...) - - pattern: fdatasync($FILE, ...) - - pattern: fstat($FILE, ...) - - pattern: fsync($FILE, ...) - - pattern: ftruncate($FILE, ...) - - pattern: futimes($FILE, ...) - - pattern: lchmod($FILE, ...) - - pattern: lchown($FILE, ...) - - pattern: lutimes($FILE, ...) - - pattern: link($FILE, ...) - - pattern: link($SMTH, $FILE, ...) - - pattern: lstat($FILE, ...) - - pattern: mkdir($FILE, ...) - - pattern: mkdtemp($FILE, ...) - - pattern: open($FILE, ...) - - pattern: opendir($FILE, ...) - - pattern: read($FILE, ...) - - pattern: read($FILE, ...) - - pattern: readdir($FILE, ...) - - pattern: readFile($FILE, ...) - - pattern: readlink($FILE, ...) - - pattern: readv($FILE, ...) - - pattern: realpath($FILE, ...) - - pattern: realpath.native($FILE, ...) - - pattern: rename($FILE, ...) - - pattern: rename($SMTH, $FILE, ...) - - pattern: rmdir($FILE, ...) - - pattern: rm($FILE, ...) - - pattern: stat($FILE, ...) - - pattern: symlink($SMTH, $FILE, ...) - - pattern: symlink($FILE, ...) - - pattern: truncate($FILE, ...) - - pattern: unlink($FILE, ...) - - pattern: unwatchFile($FILE, ...) - - pattern: utimes($FILE, ...) - - pattern: watch($FILE, ...) - - pattern: watchFile($FILE, ...) - - pattern: write($FILE, ...) - - pattern: writeFile($FILE, ...) - - pattern: writev($FILE, ...) - - pattern: accessSync($FILE, ...) - - pattern: appendFileSync($FILE, ...) - - pattern: chmodSync($FILE, ...) - - pattern: chownSync($FILE, ...) - - pattern: closeSync($FILE, ...) - - pattern: copyFileSync($FILE, ...) - - pattern: copyFileSync($SMTH, $FILE, ...) - - pattern: cpSync($FILE, ...) - - pattern: cpSync($SMTH, $FILE, ...) - - pattern: existsSync($FILE, ...) - - pattern: fchmodSync($FILE, ...) - - pattern: fchownSync($FILE, ...) - - pattern: fdatasyncSync($FILE, ...) - - pattern: fstatSync($FILE, ...) - - pattern: fsyncSync($FILE, ...) - - pattern: ftruncateSync($FILE, ...) - - pattern: futimesSync($FILE, ...) - - pattern: lchmodSync($FILE, ...) - - pattern: lchownSync($FILE, ...) - - pattern: lutimesSync($FILE, ...) - - pattern: linkSync($FILE, ...) - - pattern: linkSync($SMTH, $FILE, ...) - - pattern: lstatSync($FILE, ...) - - pattern: mkdirSync($FILE, ...) - - pattern: mkdtempSync($FILE, ...) - - pattern: opendirSync($FILE, ...) - - pattern: openSync($FILE, ...) - - pattern: readdirSync($FILE, ...) - - pattern: readFileSync($FILE, ...) - - pattern: readlinkSync($FILE, ...) - - pattern: readSync($FILE, ...) - - pattern: readSync($FILE, ...) - - pattern: readvSync($FILE, ...) - - pattern: realpathync($FILE, ...) - - pattern: realpathSync.native($FILE, ...) - - pattern: renameSync($FILE, ...) - - pattern: renameSync($SMTH, $FILE, ...) - - pattern: rmdirSync($FILE, ...) - - pattern: rmSync($FILE, ...) - - pattern: statSync($FILE, ...) - - pattern: symlinkSync($FILE, ...) - - pattern: symlinkSync($SMTH, $FILE, ...) - - pattern: truncateSync($FILE, ...) - - pattern: unlinkSync($FILE, ...) - - pattern: utimesSync($FILE, ...) - - pattern: writeFileSync($FILE, ...) - - pattern: writeSync($FILE, ...) - - pattern: writevSync($FILE, ...) - - focus-metavariable: $FILE - pattern-sources: - - patterns: - - pattern-inside: function ... (..., $ARG,...) {...} - - focus-metavariable: $ARG - severity: WARNING - - id: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp - languages: - - javascript - - typescript - message: RegExp() called with a `$ARG` function argument, this might allow an attacker to cause a Regular Expression Denial-of-Service (ReDoS) within your application as RegExP blocks the main thread. For this reason, it is recommended to use hardcoded regexes instead. If your regex is run on user-controlled input, consider performing input validation or use a regex checking/sanitization library such as https://www.npmjs.com/package/recheck to verify that the regex does not appear vulnerable to ReDoS. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-1333: Inefficient Regular Expression Complexity' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS - source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-regexp.js - subcategory: - - vuln - technology: - - javascript - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: new RegExp($ARG, ...) - - pattern: RegExp($ARG, ...) - - pattern-not: RegExp("...", ...) - - pattern-not: new RegExp("...", ...) - - pattern-not: RegExp(/.../, ...) - - pattern-not: new RegExp(/.../, ...) - pattern-sources: - - patterns: - - pattern-inside: | - function ... (...,$ARG,...) {...} - - focus-metavariable: $ARG - severity: WARNING - - id: javascript.lang.security.audit.detect-non-literal-require.detect-non-literal-require - languages: - - javascript - - typescript - message: Detected the use of require(variable). Calling require with a non-literal argument might allow an attacker to load and run arbitrary code, or access arbitrary files. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-require.js - source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-require.js - subcategory: - - vuln - technology: - - javascript - mode: taint - pattern-sinks: - - pattern: require(...) - pattern-sources: - - patterns: - - pattern-inside: function ... (..., $ARG,...) {...} - - focus-metavariable: $ARG - severity: WARNING - - id: javascript.lang.security.audit.detect-redos.detect-redos - languages: - - javascript - - typescript - message: Detected the use of a regular expression `$REDOS` which appears to be vulnerable to a Regular expression Denial-of-Service (ReDoS). For this reason, it is recommended to review the regex and ensure it is not vulnerable to catastrophic backtracking, and if possible use a library which offers default safety against ReDoS vulnerabilities. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-1333: Inefficient Regular Expression Complexity' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS - - https://www.regular-expressions.info/redos.html - subcategory: - - vuln - technology: - - javascript - patterns: - - pattern-either: - - pattern: | - new RegExp(/$REDOS/,...) - - pattern: | - new RegExp("$REDOS",...) - - pattern: | - /$REDOS/.test(...) - - pattern: | - "$REDOS".test(...) - - pattern: | - $X.match(/$REDOS/) - - pattern: | - $X.match("$REDOS") - - metavariable-analysis: - analyzer: redos - metavariable: $REDOS - severity: WARNING - - id: javascript.lang.security.audit.hardcoded-hmac-key.hardcoded-hmac-key - languages: - - javascript - - typescript - message: Detected a hardcoded hmac key. Avoid hardcoding secrets and consider using an alternate option such as reading the secret from a config file or using an environment variable. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - interfile: true - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://rules.sonarsource.com/javascript/RSPEC-2068 - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#key-management - subcategory: - - audit - technology: - - crypto - - hmac - options: - interfile: true - pattern-either: - - pattern: $CRYPTO.createHmac($ALGO, '...') - - patterns: - - pattern-inside: | - const $SECRET = '...' - ... - - pattern: $CRYPTO.createHmac($ALGO, $SECRET) - severity: WARNING - - id: javascript.lang.security.audit.incomplete-sanitization.incomplete-sanitization - languages: - - javascript - - typescript - message: '`$STR.replace` method will only replace the first occurrence when used with a string argument ($CHAR). If this method is used for escaping of dangerous data then there is a possibility for a bypass. Try to use sanitization library instead or use a Regex with a global flag.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-116: Improper Encoding or Escaping of Output' - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - javascript - patterns: - - pattern: | - $STR.replace(($CHAR: string), ...) - - metavariable-regex: - metavariable: $CHAR - regex: ^[\"\']([\'\"\<\>\*\|\{\}\[\]\%\$]{1}|\\n|\\r|\\t|\\&)[\"\']$ - severity: WARNING - - id: javascript.lang.security.audit.md5-used-as-password.md5-used-as-password - languages: - - javascript - message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as bcrypt. You can use the `bcrypt` node.js package. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html - - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords - - https://github.com/returntocorp/semgrep-rules/issues/1609 - - https://www.npmjs.com/package/bcrypt - subcategory: - - vuln - technology: - - crypto - - md5 - mode: taint - pattern-sinks: - - patterns: - - pattern: $FUNCTION(...); - - metavariable-regex: - metavariable: $FUNCTION - regex: (?i)(.*password.*) - pattern-sources: - - pattern: $CRYPTO.createHash("md5") - severity: WARNING - - id: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal - languages: - - javascript - - typescript - message: Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to sanitize or validate user input first. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - subcategory: - - vuln - technology: - - javascript - - node.js - mode: taint - pattern-sanitizers: - - pattern: $Y.replace(...) - - pattern: $Y.indexOf(...) - - pattern: | - function ... (...) { - ... - <... $Y.indexOf(...) ...> - ... - } - - patterns: - - pattern: $FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: sanitize - pattern-sinks: - - patterns: - - focus-metavariable: $SINK - - pattern-either: - - pattern-inside: | - $PATH = require('path'); - ... - - pattern-inside: | - import $PATH from 'path'; - ... - - pattern-either: - - pattern: $PATH.join(...,$SINK,...) - - pattern: $PATH.resolve(...,$SINK,...) - - patterns: - - focus-metavariable: $SINK - - pattern-inside: | - import 'path'; - ... - - pattern-either: - - pattern-inside: path.join(...,$SINK,...) - - pattern-inside: path.resolve(...,$SINK,...) - pattern-sources: - - patterns: - - focus-metavariable: $X - - pattern-either: - - pattern-inside: | - function ... (...,$X,...) {...} - - pattern-inside: | - function ... (...,{...,$X,...},...) {...} - severity: WARNING - - id: javascript.lang.security.audit.prototype-pollution.prototype-pollution-assignment.prototype-pollution-assignment - languages: - - javascript - - typescript - message: 'Possibility of prototype polluting assignment detected. By adding or modifying attributes of an object prototype, it is possible to create attributes that exist on every object, or replace critical attributes with malicious ones. This can be problematic if the software depends on existence or non-existence of certain attributes, or uses pre-defined attributes of object prototype (such as hasOwnProperty, toString or valueOf). Possible mitigations might be: freezing the object prototype, using an object without prototypes (via Object.create(null) ), blocking modifications of attributes that resolve to object prototype, using Map instead of object.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: LOW - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf - subcategory: - - audit - technology: - - javascript - patterns: - - pattern: | - $X[$B] = ... - - pattern-not: | - $X[$B] = '...' - - pattern-inside: | - $X = $SMTH[$A] - ... - - pattern-not-inside: | - if (<...'constructor' ...>) { - ... - } - ... - - pattern-not-inside: | - if (<...'__proto__' ...>) { - ... - } - ... - - pattern-not-inside: | - for(var $B = $S; ...; ...) {...} - - pattern-not-inside: | - for($B = $S; ...; ...) {...} - - pattern-not-inside: | - $X.forEach(function $NAME($OBJ, $B,...) {...}) - - metavariable-pattern: - metavariable: $A - patterns: - - pattern-not: '"..."' - - pattern-not: | - `...${...}...` - - pattern-not: | - ($A: float) - - metavariable-pattern: - metavariable: $B - patterns: - - pattern-not: '"..."' - - pattern-not: | - `...${...}...` - - pattern-not: | - ($B: float) - severity: WARNING - - id: javascript.lang.security.audit.prototype-pollution.prototype-pollution-loop.prototype-pollution-loop - languages: - - typescript - - javascript - message: 'Possibility of prototype polluting function detected. By adding or modifying attributes of an object prototype, it is possible to create attributes that exist on every object, or replace critical attributes with malicious ones. This can be problematic if the software depends on existence or non-existence of certain attributes, or uses pre-defined attributes of object prototype (such as hasOwnProperty, toString or valueOf). Possible mitigations might be: freezing the object prototype, using an object without prototypes (via Object.create(null) ), blocking modifications of attributes that resolve to object prototype, using Map instead of object.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: LOW - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf - subcategory: - - audit - technology: - - typescript - patterns: - - pattern-either: - - pattern: | - $SMTH = $SMTH[$A] - - pattern: | - $SMTH = $SMTH[$A] = ... - - pattern: | - $SMTH = $SMTH[$A] && $Z - - pattern: | - $SMTH = $SMTH[$A] || $Z - - pattern-either: - - pattern-inside: | - for(...) { - ... - } - - pattern-inside: | - while(...) { - ... - } - - pattern-inside: | - $X.forEach(function $NAME(...) { - ... - }) - - pattern-not-inside: | - for(var $A = $S; ...; ...) {...} - - pattern-not-inside: | - for($A = $S; ...; ...) {...} - - pattern-not-inside: | - $X.forEach(function $NAME($OBJ, $A,...) {...}) - - metavariable-pattern: - metavariable: $A - patterns: - - pattern-not: '"..."' - - pattern-not: | - `...${...}...` - - pattern-not: | - ($A: float) - severity: WARNING - - id: javascript.lang.security.audit.spawn-shell-true.spawn-shell-true - languages: - - javascript - - typescript - message: 'Found ''$SPAWN'' with ''{shell: $SHELL}''. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use ''{shell: false}'' instead.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - javascript - patterns: - - pattern-either: - - pattern: | - spawn(...,{shell: $SHELL}) - - pattern: | - spawnSync(...,{shell: $SHELL}) - - pattern: | - $CP.spawn(...,{shell: $SHELL}) - - pattern: | - $CP.spawnSync(...,{shell: $SHELL}) - - pattern-not: | - spawn(...,{shell: false}) - - pattern-not: | - spawnSync(...,{shell: false}) - - pattern-not: | - $CP.spawn(...,{shell: false}) - - pattern-not: | - $CP.spawnSync(...,{shell: false}) - severity: ERROR - - id: javascript.lang.security.audit.sqli.node-knex-sqli.node-knex-sqli - languages: - - javascript - - typescript - message: 'Detected SQL statement that is tainted by `$REQ` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements. An example of parameterized queries like so: `knex.raw(''SELECT $1 from table'', [userinput])` can help prevent SQLi.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://knexjs.org/#Builder-fromRaw - - https://knexjs.org/#Builder-whereRaw - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - express - - nodejs - - knex - mode: taint - pattern-sanitizers: - - patterns: - - pattern: parseInt(...) - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern-inside: $KNEX.fromRaw($QUERY, ...) - - pattern-inside: $KNEX.whereRaw($QUERY, ...) - - pattern-inside: $KNEX.raw($QUERY, ...) - - pattern-either: - - pattern-inside: | - require('knex') - ... - - pattern-inside: | - import 'knex' - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: function ... ($REQ, $RES) {...} - - pattern-inside: function ... ($REQ, $RES, $NEXT) {...} - - patterns: - - pattern-either: - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...}) - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...}) - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|post|put|head|delete|options) - - pattern-either: - - pattern: $REQ.query - - pattern: $REQ.body - - pattern: $REQ.params - - pattern: $REQ.cookies - - pattern: $REQ.headers - - pattern: $REQ.files.$ANYTHING.data.toString('utf8') - - pattern: $REQ.files.$ANYTHING['data'].toString('utf8') - - patterns: - - pattern-either: - - pattern-inside: | - ({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => - {...} - - pattern-inside: | - ({ $REQ }: Request,$RES: Response) => {...} - - focus-metavariable: $REQ - - pattern-either: - - pattern: params - - pattern: query - - pattern: cookies - - pattern: headers - - pattern: body - - pattern: files.$ANYTHING.data.toString('utf8') - - pattern: files.$ANYTHING['data'].toString('utf8') - severity: WARNING - - id: javascript.lang.security.audit.sqli.node-mssql-sqli.node-mssql-sqli - languages: - - javascript - - typescript - message: 'Detected string concatenation with a non-literal variable in a `mssql` JS SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `$REQ.input(''USER_ID'', mssql.Int, id);`' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://www.npmjs.com/package/mssql - subcategory: - - vuln - technology: - - mssql - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - require('mssql'); - ... - - pattern-inside: | - import 'mssql'; - ... - - pattern-inside: | - $REQ = $POOL.request(...) - ... - - pattern: | - $REQ.query($QUERY,...) - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-inside: | - function ... (...,$FUNC,...) { - ... - } - - focus-metavariable: $FUNC - severity: WARNING - - id: javascript.lang.security.audit.sqli.node-mysql-sqli.node-mysql-sqli - languages: - - javascript - - typescript - message: Detected a `$IMPORT` SQL statement that comes from a function argument. This could lead to SQL injection if the variable is user-controlled and is not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://www.npmjs.com/package/mysql2 - - https://www.npmjs.com/package/mysql - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - mysql - - mysql2 - - javascript - - nodejs - mode: taint - pattern-sanitizers: - - patterns: - - pattern: parseInt(...) - pattern-sinks: - - patterns: - - focus-metavariable: $QUERY - - pattern-either: - - pattern-inside: $POOL.query($QUERY, ...) - - pattern-inside: $POOL.execute($QUERY, ...) - - pattern-either: - - pattern-inside: | - import $S from "$IMPORT" - ... - - pattern-inside: | - import { ... } from "$IMPORT" - ... - - pattern-inside: | - import * as $S from "$IMPORT" - ... - - pattern-inside: | - require("$IMPORT") - ... - - metavariable-regex: - metavariable: $IMPORT - regex: (mysql|mysql2) - pattern-sources: - - patterns: - - pattern-inside: function ... (..., $Y,...) {...} - - pattern: $Y - - pattern-not-inside: | - function ... (..., $Y: number,...) {...} - - pattern-not-inside: $Y.query - - pattern-not-inside: $Y.body - - pattern-not-inside: $Y.params - - pattern-not-inside: $Y.cookies - - pattern-not-inside: $Y.headers - severity: WARNING - - id: javascript.lang.security.audit.sqli.node-postgres-sqli.node-postgres-sqli - languages: - - javascript - - typescript - message: 'Detected string concatenation with a non-literal variable in a node-postgres JS SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `client.query(''SELECT $1 from table'', [userinput])`' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://node-postgres.com/features/queries - subcategory: - - vuln - technology: - - node-postgres - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - const { $CLIENT } = require('pg') - ... - - pattern-inside: | - var { $CLIENT } = require('pg') - ... - - pattern-inside: | - let { $CLIENT } = require('pg') - ... - - pattern-either: - - pattern-inside: | - $DB = new $CLIENT(...) - ... - - pattern-inside: | - $NEWPOOL = new $CLIENT(...) - ... - $NEWPOOL.connect((..., $DB, ...) => { - ... - }) - - pattern: $DB.query($QUERY,...) - - focus-metavariable: $QUERY - pattern-sources: - - patterns: - - pattern-inside: | - function ... (...,$FUNC,...) { - ... - } - - focus-metavariable: $FUNC - - pattern-not-inside: | - $F. ... .$SOURCE(...) - severity: WARNING - - id: javascript.lang.security.audit.unknown-value-with-script-tag.unknown-value-with-script-tag - languages: - - javascript - - typescript - message: Cannot determine what '$UNK' is and it is used with a ' - - pattern: '{{ ... }}' - - pattern-not-inside: nonce = '...' - - pattern-not-inside: nonce = "..." - severity: ERROR - - id: python.django.security.django-no-csrf-token.django-no-csrf-token - languages: - - generic - message: Manually-created forms in django templates should specify a csrf_token to prevent CSRF attacks - metadata: - category: security - confidence: MEDIUM - cwe: 'CWE-352: Cross-Site Request Forgery (CSRF)' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://docs.djangoproject.com/en/4.2/howto/csrf/ - subcategory: - - guardrail - technology: - - django - paths: - include: - - '*.html' - patterns: - - pattern: ... - - pattern-either: - - pattern: | -
    ...
    - - pattern: | -
    ...
    - - pattern: | -
    ...
    - - metavariable-regex: - metavariable: $METHOD - regex: (?i)(post|put|delete|patch) - - pattern-not-inside: ...{% csrf_token %}... - - pattern-not-inside: ...{{ $VAR.csrf_token }}... - severity: WARNING - - id: python.django.security.django-using-request-post-after-is-valid.django-using-request-post-after-is-valid - languages: - - python - message: Use $FORM.cleaned_data[] instead of request.POST[] after form.is_valid() has been executed to only access sanitized data - metadata: - category: security - confidence: MEDIUM - cwe: 'CWE-20: Improper Input Validation' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://docs.djangoproject.com/en/4.2/ref/forms/api/#accessing-clean-data - subcategory: - - guardrail - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-inside: | - if $FORM.is_valid(): - ... - - pattern-either: - - pattern: request.POST[...] - - pattern: request.POST.get(...) - severity: WARNING - - id: python.django.security.globals-as-template-context.globals-as-template-context - languages: - - python - message: 'Using ''globals()'' as a context to ''render(...)'' is extremely dangerous. This exposes Python functions to the template that were not meant to be exposed. An attacker could use these functions to execute code that was not intended to run and could compromise the application. (This is server-side template injection (SSTI)). Do not use ''globals()''. Instead, specify each variable in a dictionary or ''django.template.Context'' object, like ''{"var1": "hello"}'' and use that instead.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.2/ref/settings/#templates - - https://docs.djangoproject.com/en/3.2/topics/templates/#django.template.backends.django.DjangoTemplates - - https://docs.djangoproject.com/en/3.2/ref/templates/api/#rendering-a-context - subcategory: - - audit - technology: - - django - pattern-either: - - pattern: django.shortcuts.render(..., globals(...), ...) - - pattern: django.template.Template.render(..., globals(...), ...) - - patterns: - - pattern-inside: | - $CONTEXT = globals(...) - ... - - pattern-either: - - pattern: django.shortcuts.render(..., $CONTEXT, ...) - - pattern: django.template.Template.render(..., $CONTEXT, ...) - severity: ERROR - - id: python.django.security.hashids-with-django-secret.hashids-with-django-secret - languages: - - python - message: The Django 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 Django secret key can be obtained by attackers, through the HashIDs. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: HIGH - likelihood: LOW - owasp: - - A02:2021 – Cryptographic Failures - references: - - https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-SECRET_KEY - - http://carnage.github.io/2015/08/cryptanalysis-of-hashids - subcategory: - - vuln - technology: - - django - pattern-either: - - pattern: hashids.Hashids(..., salt=django.conf.settings.SECRET_KEY, ...) - - pattern: hashids.Hashids(django.conf.settings.SECRET_KEY, ...) - severity: ERROR - - id: python.django.security.injection.code.globals-misuse-code-execution.globals-misuse-code-execution - languages: - - python - message: Found request data as an index to 'globals()'. This is extremely dangerous because it allows an attacker to execute arbitrary code on the system. Refactor your code not to use 'globals()'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://github.com/mpirnat/lets-be-bad-guys/blob/d92768fb3ade32956abd53bd6bb06e19d634a084/badguys/vulnerable/views.py#L181-L186 - subcategory: - - audit - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = globals().get($DATA, ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = globals().get("..." % $DATA, ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = globals().get(f"...{$DATA}...", ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = globals().get("...".format(..., $DATA, ...), ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = globals()[$DATA] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = globals()["..." % $DATA] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = globals()[f"...{$DATA}..."] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = globals()["...".format(..., $DATA, ...)] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = globals().get($DATA, ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = globals().get("..." % $DATA, ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = globals().get(f"...{$DATA}...", ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = globals().get("...".format(..., $DATA, ...), ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = globals()[$DATA] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = globals()["..." % $DATA] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = globals()[f"...{$DATA}..."] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = globals()["...".format(..., $DATA, ...)] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = globals().get($DATA, ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = globals().get("..." % $DATA, ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = globals().get(f"...{$DATA}...", ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = globals().get("...".format(..., $DATA, ...), ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = globals()[$DATA] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = globals()["..." % $DATA] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = globals()[f"...{$DATA}..."] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = globals()["...".format(..., $DATA, ...)] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W - ... - $INTERM = globals().get($DATA, ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W - ... - $INTERM = globals().get("..." % $DATA, ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W - ... - $INTERM = globals().get(f"...{$DATA}...", ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W - ... - $INTERM = globals().get("...".format(..., $DATA, ...), ...) - ... - $INTERM(...) - - pattern: | - $DATA = request.$W - ... - $INTERM = globals()[$DATA] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W - ... - $INTERM = globals()["..." % $DATA] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W - ... - $INTERM = globals()[f"...{$DATA}..."] - ... - $INTERM(...) - - pattern: | - $DATA = request.$W - ... - $INTERM = globals()["...".format(..., $DATA, ...)] - ... - $INTERM(...) - severity: WARNING - - id: python.django.security.injection.code.user-eval-format-string.user-eval-format-string - languages: - - python - message: Found user data in a call to 'eval'. This is extremely dangerous because it can enable an attacker to execute remote code. See https://owasp.org/www-community/attacks/Code_Injection for more information. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $F(...): - ... - - pattern-either: - - pattern: eval(..., $STR % request.$W.get(...), ...) - - pattern: | - $V = request.$W.get(...) - ... - eval(..., $STR % $V, ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = $STR % $V - ... - eval(..., $S, ...) - - pattern: eval(..., "..." % request.$W(...), ...) - - pattern: | - $V = request.$W(...) - ... - eval(..., $STR % $V, ...) - - pattern: | - $V = request.$W(...) - ... - $S = $STR % $V - ... - eval(..., $S, ...) - - pattern: eval(..., $STR % request.$W[...], ...) - - pattern: | - $V = request.$W[...] - ... - eval(..., $STR % $V, ...) - - pattern: | - $V = request.$W[...] - ... - $S = $STR % $V - ... - eval(..., $S, ...) - - pattern: eval(..., $STR.format(..., request.$W.get(...), ...), ...) - - pattern: | - $V = request.$W.get(...) - ... - eval(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = $STR.format(..., $V, ...) - ... - eval(..., $S, ...) - - pattern: eval(..., $STR.format(..., request.$W(...), ...), ...) - - pattern: | - $V = request.$W(...) - ... - eval(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W(...) - ... - $S = $STR.format(..., $V, ...) - ... - eval(..., $S, ...) - - pattern: eval(..., $STR.format(..., request.$W[...], ...), ...) - - pattern: | - $V = request.$W[...] - ... - eval(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W[...] - ... - $S = $STR.format(..., $V, ...) - ... - eval(..., $S, ...) - - pattern: | - $V = request.$W.get(...) - ... - eval(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = f"...{$V}..." - ... - eval(..., $S, ...) - - pattern: | - $V = request.$W(...) - ... - eval(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W(...) - ... - $S = f"...{$V}..." - ... - eval(..., $S, ...) - - pattern: | - $V = request.$W[...] - ... - eval(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W[...] - ... - $S = f"...{$V}..." - ... - eval(..., $S, ...) - severity: WARNING - - id: python.django.security.injection.code.user-eval.user-eval - languages: - - python - message: Found user data in a call to 'eval'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html - - https://owasp.org/www-community/attacks/Code_Injection - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $F(...): - ... - - pattern-either: - - pattern: eval(..., request.$W.get(...), ...) - - pattern: | - $V = request.$W.get(...) - ... - eval(..., $V, ...) - - pattern: eval(..., request.$W(...), ...) - - pattern: | - $V = request.$W(...) - ... - eval(..., $V, ...) - - pattern: eval(..., request.$W[...], ...) - - pattern: | - $V = request.$W[...] - ... - eval(..., $V, ...) - severity: WARNING - - id: python.django.security.injection.code.user-exec-format-string.user-exec-format-string - languages: - - python - message: Found user data in a call to 'exec'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/Code_Injection - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $F(...): - ... - - pattern-either: - - pattern: exec(..., $STR % request.$W.get(...), ...) - - pattern: | - $V = request.$W.get(...) - ... - exec(..., $STR % $V, ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = $STR % $V - ... - exec(..., $S, ...) - - pattern: exec(..., "..." % request.$W(...), ...) - - pattern: | - $V = request.$W(...) - ... - exec(..., $STR % $V, ...) - - pattern: | - $V = request.$W(...) - ... - $S = $STR % $V - ... - exec(..., $S, ...) - - pattern: exec(..., $STR % request.$W[...], ...) - - pattern: | - $V = request.$W[...] - ... - exec(..., $STR % $V, ...) - - pattern: | - $V = request.$W[...] - ... - $S = $STR % $V - ... - exec(..., $S, ...) - - pattern: exec(..., $STR.format(..., request.$W.get(...), ...), ...) - - pattern: | - $V = request.$W.get(...) - ... - exec(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = $STR.format(..., $V, ...) - ... - exec(..., $S, ...) - - pattern: exec(..., $STR.format(..., request.$W(...), ...), ...) - - pattern: | - $V = request.$W(...) - ... - exec(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W(...) - ... - $S = $STR.format(..., $V, ...) - ... - exec(..., $S, ...) - - pattern: exec(..., $STR.format(..., request.$W[...], ...), ...) - - pattern: | - $V = request.$W[...] - ... - exec(..., $STR.format(..., $V, ...), ...) - - pattern: | - $V = request.$W[...] - ... - $S = $STR.format(..., $V, ...) - ... - exec(..., $S, ...) - - pattern: | - $V = request.$W.get(...) - ... - exec(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W.get(...) - ... - $S = f"...{$V}..." - ... - exec(..., $S, ...) - - pattern: | - $V = request.$W(...) - ... - exec(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W(...) - ... - $S = f"...{$V}..." - ... - exec(..., $S, ...) - - pattern: | - $V = request.$W[...] - ... - exec(..., f"...{$V}...", ...) - - pattern: | - $V = request.$W[...] - ... - $S = f"...{$V}..." - ... - exec(..., $S, ...) - - pattern: exec(..., base64.decodestring($S.format(..., request.$W.get(...), ...), ...), ...) - - pattern: exec(..., base64.decodestring($S % request.$W.get(...), ...), ...) - - pattern: exec(..., base64.decodestring(f"...{request.$W.get(...)}...", ...), ...) - - pattern: exec(..., base64.decodestring(request.$W.get(...), ...), ...) - - pattern: exec(..., base64.decodestring(bytes($S.format(..., request.$W.get(...), ...), ...), ...), ...) - - pattern: exec(..., base64.decodestring(bytes($S % request.$W.get(...), ...), ...), ...) - - pattern: exec(..., base64.decodestring(bytes(f"...{request.$W.get(...)}...", ...), ...), ...) - - pattern: exec(..., base64.decodestring(bytes(request.$W.get(...), ...), ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - exec(..., base64.decodestring($DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = base64.decodestring($DATA, ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = base64.decodestring(bytes($DATA, ...), ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - exec(..., base64.decodestring($DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = base64.decodestring($DATA, ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = base64.decodestring(bytes($DATA, ...), ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - exec(..., base64.decodestring($DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = base64.decodestring($DATA, ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = base64.decodestring(bytes($DATA, ...), ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - exec(..., base64.decodestring($DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = base64.decodestring($DATA, ...) - ... - exec(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - exec(..., base64.decodestring(bytes($DATA, ...), ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = base64.decodestring(bytes($DATA, ...), ...) - ... - exec(..., $INTERM, ...) - severity: WARNING - - id: python.django.security.injection.code.user-exec.user-exec - languages: - - python - message: Found user data in a call to 'exec'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/Code_Injection - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $F(...): - ... - - pattern-either: - - pattern: exec(..., request.$W.get(...), ...) - - pattern: | - $V = request.$W.get(...) - ... - exec(..., $V, ...) - - pattern: exec(..., request.$W(...), ...) - - pattern: | - $V = request.$W(...) - ... - exec(..., $V, ...) - - pattern: exec(..., request.$W[...], ...) - - pattern: | - $V = request.$W[...] - ... - exec(..., $V, ...) - - pattern: | - loop = asyncio.get_running_loop() - ... - await loop.run_in_executor(None, exec, request.$W[...]) - - pattern: | - $V = request.$W[...] - ... - loop = asyncio.get_running_loop() - ... - await loop.run_in_executor(None, exec, $V) - - pattern: | - loop = asyncio.get_running_loop() - ... - await loop.run_in_executor(None, exec, request.$W.get(...)) - - pattern: | - $V = request.$W.get(...) - ... - loop = asyncio.get_running_loop() - ... - await loop.run_in_executor(None, exec, $V) - severity: WARNING - - id: python.django.security.injection.command.command-injection-os-system.command-injection-os-system - languages: - - python - message: Request data detected in os.system. This could be vulnerable to a command injection and should be avoided. If this must be done, use the 'subprocess' module instead and pass the arguments as a list. See https://owasp.org/www-community/attacks/Command_Injection for more information. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/Command_Injection - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: os.system(..., request.$W.get(...), ...) - - pattern: os.system(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: os.system(..., $S % request.$W.get(...), ...) - - pattern: os.system(..., f"...{request.$W.get(...)}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - os.system(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - os.system(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - os.system(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - os.system(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - os.system(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - os.system(..., $INTERM, ...) - - pattern: $A = os.system(..., request.$W.get(...), ...) - - pattern: $A = os.system(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $A = os.system(..., $S % request.$W.get(...), ...) - - pattern: $A = os.system(..., f"...{request.$W.get(...)}...", ...) - - pattern: return os.system(..., request.$W.get(...), ...) - - pattern: return os.system(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: return os.system(..., $S % request.$W.get(...), ...) - - pattern: return os.system(..., f"...{request.$W.get(...)}...", ...) - - pattern: os.system(..., request.$W(...), ...) - - pattern: os.system(..., $S.format(..., request.$W(...), ...), ...) - - pattern: os.system(..., $S % request.$W(...), ...) - - pattern: os.system(..., f"...{request.$W(...)}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - os.system(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - os.system(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - os.system(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - os.system(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - os.system(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - os.system(..., $INTERM, ...) - - pattern: $A = os.system(..., request.$W(...), ...) - - pattern: $A = os.system(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $A = os.system(..., $S % request.$W(...), ...) - - pattern: $A = os.system(..., f"...{request.$W(...)}...", ...) - - pattern: return os.system(..., request.$W(...), ...) - - pattern: return os.system(..., $S.format(..., request.$W(...), ...), ...) - - pattern: return os.system(..., $S % request.$W(...), ...) - - pattern: return os.system(..., f"...{request.$W(...)}...", ...) - - pattern: os.system(..., request.$W[...], ...) - - pattern: os.system(..., $S.format(..., request.$W[...], ...), ...) - - pattern: os.system(..., $S % request.$W[...], ...) - - pattern: os.system(..., f"...{request.$W[...]}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - os.system(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - os.system(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - os.system(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - os.system(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - os.system(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - os.system(..., $INTERM, ...) - - pattern: $A = os.system(..., request.$W[...], ...) - - pattern: $A = os.system(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $A = os.system(..., $S % request.$W[...], ...) - - pattern: $A = os.system(..., f"...{request.$W[...]}...", ...) - - pattern: return os.system(..., request.$W[...], ...) - - pattern: return os.system(..., $S.format(..., request.$W[...], ...), ...) - - pattern: return os.system(..., $S % request.$W[...], ...) - - pattern: return os.system(..., f"...{request.$W[...]}...", ...) - - pattern: os.system(..., request.$W, ...) - - pattern: os.system(..., $S.format(..., request.$W, ...), ...) - - pattern: os.system(..., $S % request.$W, ...) - - pattern: os.system(..., f"...{request.$W}...", ...) - - pattern: | - $DATA = request.$W - ... - os.system(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - os.system(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - os.system(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - os.system(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - os.system(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - os.system(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - os.system(..., $INTERM, ...) - - pattern: $A = os.system(..., request.$W, ...) - - pattern: $A = os.system(..., $S.format(..., request.$W, ...), ...) - - pattern: $A = os.system(..., $S % request.$W, ...) - - pattern: $A = os.system(..., f"...{request.$W}...", ...) - - pattern: return os.system(..., request.$W, ...) - - pattern: return os.system(..., $S.format(..., request.$W, ...), ...) - - pattern: return os.system(..., $S % request.$W, ...) - - pattern: return os.system(..., f"...{request.$W}...", ...) - severity: ERROR - - id: python.django.security.injection.command.subprocess-injection.subprocess-injection - languages: - - python - message: Detected user input entering a `subprocess` call unsafely. This could result in a command injection vulnerability. An attacker could use this vulnerability to execute arbitrary commands on the host, which allows them to download malware, scan sensitive data, or run any command they wish on the server. Do not let users choose the command to run. In general, prefer to use Python API versions of system commands. If you must use subprocess, use a dictionary to allowlist a set of commands. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - flask - mode: taint - options: - symbolic_propagation: true - pattern-sanitizers: - - patterns: - - pattern: $DICT[$KEY] - - focus-metavariable: $KEY - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: subprocess.$FUNC(...) - - pattern-not: subprocess.$FUNC("...", ...) - - pattern-not: subprocess.$FUNC(["...", ...], ...) - - pattern-not-inside: | - $CMD = ["...", ...] - ... - subprocess.$FUNC($CMD, ...) - - patterns: - - pattern: subprocess.$FUNC(["$SHELL", "-c", ...], ...) - - metavariable-regex: - metavariable: $SHELL - regex: ^(sh|bash|ksh|csh|tcsh|zsh)$ - - patterns: - - pattern: subprocess.$FUNC(["$INTERPRETER", ...], ...) - - metavariable-regex: - metavariable: $INTERPRETER - regex: ^(python|python\d)$ - pattern-sources: - - patterns: - - pattern-inside: | - def $FUNC(..., $REQUEST, ...): - ... - - focus-metavariable: $REQUEST - - metavariable-pattern: - metavariable: $REQUEST - patterns: - - pattern: request - - pattern-not-inside: request.build_absolute_uri - severity: ERROR - - id: python.django.security.injection.csv-writer-injection.csv-writer-injection - languages: - - python - message: Detected user input into a generated CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1236: Improper Neutralization of Formula Elements in a CSV File' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/raphaelm/defusedcsv - - https://owasp.org/www-community/attacks/CSV_Injection - - https://web.archive.org/web/20220516052229/https://www.contextis.com/us/blog/comma-separated-vulnerabilities - subcategory: - - vuln - technology: - - django - - python - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - $WRITER = csv.writer(...) - - ... - - $WRITER.$WRITE(...) - - pattern: $WRITER.$WRITE(...) - - metavariable-regex: - metavariable: $WRITE - regex: ^(writerow|writerows|writeheader)$ - pattern-sources: - - patterns: - - pattern-inside: | - def $FUNC(..., $REQUEST, ...): - ... - - focus-metavariable: $REQUEST - - metavariable-pattern: - metavariable: $REQUEST - patterns: - - pattern: request - - pattern-not-inside: request.build_absolute_uri - severity: ERROR - - id: python.django.security.injection.email.xss-html-email-body.xss-html-email-body - languages: - - python - message: Found request data in an EmailMessage that is set to use HTML. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component (''Injection'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://www.damonkohler.com/2008/12/email-injection.html - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - $EMAIL.content_subtype = "html" - ... - - pattern-either: - - pattern: django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.EmailMessage($SUBJ, $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) - - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...) - - pattern: django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.EmailMessage($SUBJ, $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) - - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W(...), ...) - - pattern: django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.EmailMessage($SUBJ, $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) - - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W[...], ...) - - pattern: django.core.mail.EmailMessage($SUBJ, request.$W, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.EmailMessage($SUBJ, $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.EmailMessage($SUBJ, $INTERM, ...) - - pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W, ...) - - pattern: return django.core.mail.EmailMessage($SUBJ, request.$W, ...) - severity: WARNING - - id: python.django.security.injection.email.xss-send-mail-html-message.xss-send-mail-html-message - languages: - - python - message: Found request data in 'send_mail(...)' that uses 'html_message'. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component (''Injection'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://www.damonkohler.com/2008/12/email-injection.html - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.send_mail(..., html_message=$DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) - - pattern: return django.core.mail.send_mail(..., html_message=request.$W.get(...), ...) - - pattern: django.core.mail.send_mail(..., html_message=request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.send_mail(..., html_message=$DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W(...), ...) - - pattern: return django.core.mail.send_mail(..., html_message=request.$W(...), ...) - - pattern: django.core.mail.send_mail(..., html_message=request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.send_mail(..., html_message=$DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W[...], ...) - - pattern: return django.core.mail.send_mail(..., html_message=request.$W[...], ...) - - pattern: django.core.mail.send_mail(..., html_message=request.$W, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.send_mail(..., html_message=$DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.send_mail(..., html_message=$STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.core.mail.send_mail(..., html_message=$STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - django.core.mail.send_mail(..., html_message=$INTERM, ...) - - pattern: $A = django.core.mail.send_mail(..., html_message=request.$W, ...) - - pattern: return django.core.mail.send_mail(..., html_message=request.$W, ...) - severity: WARNING - - id: python.django.security.injection.mass-assignment.mass-assignment - languages: - - python - message: Mass assignment detected. This can result in assignment to model fields that are unintended and can be exploited by an attacker. Instead of using '**request.$W', assign each field you want to edit individually to prevent mass assignment. You can read more about mass assignment at https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - owaspapi: 'API6: Mass Assignment' - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html - subcategory: - - audit - technology: - - django - pattern-either: - - pattern: $MODEL.objects.create(**request.$W) - - pattern: | - $OBJ.update(**request.$W) - ... - $OBJ.save() - severity: WARNING - - id: python.django.security.injection.open-redirect.open-redirect - languages: - - python - message: Data from request ($DATA) is passed to redirect(). This is an open redirect and could be exploited. Ensure you are redirecting to safe URLs by using django.utils.http.is_safe_url(). See https://cwe.mitre.org/data/definitions/601.html for more information. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://www.djm.org.uk/posts/djangos-little-protections-word-redirect-dangers/ - - https://github.com/django/django/blob/d1b7bd030b1db111e1a3505b1fc029ab964382cc/django/utils/http.py#L231 - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-not-inside: | - def $FUNC(...): - ... - django.utils.http.is_safe_url(...) - ... - - pattern-not-inside: | - def $FUNC(...): - ... - if <... django.utils.http.is_safe_url(...) ...>: - ... - - pattern-not-inside: | - def $FUNC(...): - ... - django.utils.http.url_has_allowed_host_and_scheme(...) - ... - - pattern-not-inside: | - def $FUNC(...): - ... - if <... django.utils.http.url_has_allowed_host_and_scheme(...) ...>: - ... - - pattern-either: - - pattern: django.shortcuts.redirect(..., request.$W.get(...), ...) - - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: django.shortcuts.redirect(..., $S % request.$W.get(...), ...) - - pattern: django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.shortcuts.redirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.shortcuts.redirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.shortcuts.redirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.shortcuts.redirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: $A = django.shortcuts.redirect(..., request.$W.get(...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S % request.$W.get(...), ...) - - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: return django.shortcuts.redirect(..., request.$W.get(...), ...) - - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: return django.shortcuts.redirect(..., $S % request.$W.get(...), ...) - - pattern: return django.shortcuts.redirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: django.shortcuts.redirect(..., request.$W(...), ...) - - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: django.shortcuts.redirect(..., $S % request.$W(...), ...) - - pattern: django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - django.shortcuts.redirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.shortcuts.redirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.shortcuts.redirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.shortcuts.redirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: $A = django.shortcuts.redirect(..., request.$W(...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S % request.$W(...), ...) - - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) - - pattern: return django.shortcuts.redirect(..., request.$W(...), ...) - - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: return django.shortcuts.redirect(..., $S % request.$W(...), ...) - - pattern: return django.shortcuts.redirect(..., f"...{request.$W(...)}...", ...) - - pattern: django.shortcuts.redirect(..., request.$W[...], ...) - - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: django.shortcuts.redirect(..., $S % request.$W[...], ...) - - pattern: django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - django.shortcuts.redirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.shortcuts.redirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.shortcuts.redirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.shortcuts.redirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: $A = django.shortcuts.redirect(..., request.$W[...], ...) - - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S % request.$W[...], ...) - - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) - - pattern: return django.shortcuts.redirect(..., request.$W[...], ...) - - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: return django.shortcuts.redirect(..., $S % request.$W[...], ...) - - pattern: return django.shortcuts.redirect(..., f"...{request.$W[...]}...", ...) - - pattern: django.shortcuts.redirect(..., request.$W, ...) - - pattern: django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) - - pattern: django.shortcuts.redirect(..., $S % request.$W, ...) - - pattern: django.shortcuts.redirect(..., f"...{request.$W}...", ...) - - pattern: | - $DATA = request.$W - ... - django.shortcuts.redirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.shortcuts.redirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.shortcuts.redirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.shortcuts.redirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.shortcuts.redirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - django.shortcuts.redirect(..., $INTERM, ...) - - pattern: $A = django.shortcuts.redirect(..., request.$W, ...) - - pattern: $A = django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) - - pattern: $A = django.shortcuts.redirect(..., $S % request.$W, ...) - - pattern: $A = django.shortcuts.redirect(..., f"...{request.$W}...", ...) - - pattern: return django.shortcuts.redirect(..., request.$W, ...) - - pattern: return django.shortcuts.redirect(..., $S.format(..., request.$W, ...), ...) - - pattern: return django.shortcuts.redirect(..., $S % request.$W, ...) - - pattern: return django.shortcuts.redirect(..., f"...{request.$W}...", ...) - - pattern: django.http.HttpResponseRedirect(..., request.$W.get(...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) - - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseRedirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseRedirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseRedirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., request.$W.get(...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: return django.http.HttpResponseRedirect(..., request.$W.get(...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) - - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) - - pattern: django.http.HttpResponseRedirect(..., request.$W(...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) - - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseRedirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseRedirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseRedirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., request.$W(...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) - - pattern: return django.http.HttpResponseRedirect(..., request.$W(...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) - - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) - - pattern: django.http.HttpResponseRedirect(..., request.$W[...], ...) - - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) - - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseRedirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseRedirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseRedirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., request.$W[...], ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) - - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) - - pattern: return django.http.HttpResponseRedirect(..., request.$W[...], ...) - - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) - - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) - - pattern: django.http.HttpResponseRedirect(..., request.$W, ...) - - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) - - pattern: django.http.HttpResponseRedirect(..., $S % request.$W, ...) - - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseRedirect(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseRedirect(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseRedirect(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseRedirect(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., request.$W, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) - - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W, ...) - - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) - - pattern: return django.http.HttpResponseRedirect(..., request.$W, ...) - - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) - - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W, ...) - - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) - - metavariable-regex: - metavariable: $W - regex: (?!get_full_path) - severity: WARNING - - id: python.django.security.injection.path-traversal.path-traversal-file-name.path-traversal-file-name - languages: - - python - message: Data from request is passed to a file name `$FILE`. This is a path traversal vulnerability, which can lead to sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or the pathlib library. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $F(...): - ... - - pattern-not-inside: | - def $F(...): - ... - os.path.realpath(...) - ... - - pattern-not-inside: | - def $F(...): - ... - os.path.abspath(...) - ... - - pattern-either: - - pattern: | - $V = request.$W.get($X) - ... - $FILE % ($V) - - pattern: | - $V = request.$W[$X] - ... - $FILE % ($V) - - pattern: | - $V = request.$W($X) - ... - $FILE % ($V) - - pattern: | - $V = request.$W - ... - $FILE % ($V) - # match format use cases - - pattern: | - $V = request.$W.get($X) - ... - $FILE.format(..., $V, ...) - - pattern: | - $V = request.$W[$X] - ... - $FILE.format(..., $V, ...) - - pattern: | - $V = request.$W($X) - ... - $FILE.format(..., $V, ...) - - pattern: | - $V = request.$W - ... - $FILE.format(..., $V, ...) - - metavariable-regex: - metavariable: $FILE - regex: .*\.(log|zip|txt|csv|xml|html).* - severity: WARNING - - id: python.django.security.injection.path-traversal.path-traversal-join.path-traversal-join - languages: - - python - message: Data from request is passed to os.path.join() and to open(). This is a path traversal vulnerability, which can lead to sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or Path library. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - subcategory: - - audit - technology: - - django - patterns: - - pattern-inside: | - def $F(...): - ... - - pattern-not-inside: | - def $F(...): - ... - os.path.abspath(...) - ... - - pattern-not-inside: | - def $F(...): - ... - os.path.realpath(...) - ... - - pattern-either: - - pattern: open(os.path.join(..., request.$W.get(...), ...), ...) - - pattern: open(os.path.join(..., request.$W(...), ...), ...) - - pattern: open(os.path.join(..., request.$W, ...), ...) - - pattern: open(os.path.join(..., request.$W[...], ...), ...) - - pattern: | - $P = os.path.join(..., request.$W.get(...), ...) - ... - open($P, ...) - - pattern: | - $P = os.path.join(..., request.$W(...), ...) - ... - open($P, ...) - - pattern: | - $P = os.path.join(..., request.$W, ...) - ... - open($P, ...) - - pattern: | - $P = os.path.join(..., request.$W[...], ...) - ... - open($P, ...) - - pattern: | - $V = request.$W.get($X) - ... - $P = os.path.join(..., $V, ...) - ... - open($P, ...) - - pattern: | - $V = request.$W($X) - ... - $P = os.path.join(..., $V, ...) - ... - open($P, ...) - - pattern: | - $V = request.$W[$X] - ... - $P = os.path.join(..., $V, ...) - ... - open($P, ...) - - pattern: | - $V = request.$W - ... - $P = os.path.join(..., $V, ...) - ... - open($P, ...) - - pattern: | - $P = request.$W.get(...) - ... - open(os.path.join(..., $P, ...), ...) - - pattern: | - $P = request.$W(...) - ... - open(os.path.join(..., $P, ...), ...) - - pattern: | - $P = request.$W - ... - open(os.path.join(..., $P, ...), ...) - - pattern: | - $P = request.$W[...] - ... - open(os.path.join(..., $P, ...), ...) - severity: WARNING - - id: python.django.security.injection.path-traversal.path-traversal-open.path-traversal-open - languages: - - python - message: Found request data in a call to 'open'. Ensure the request data is validated or sanitized, otherwise it could result in path traversal attacks and therefore sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or the pathlib library. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: open(..., request.$W.get(...), ...) - - pattern: open(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: open(..., $S % request.$W.get(...), ...) - - pattern: open(..., f"...{request.$W.get(...)}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - open(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W.get(...) - ... - open(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W.get(...) - ... - open(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W.get(...) - ... - open(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W.get(...) - ... - open(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: $A = open(..., request.$W.get(...), ...) - - pattern: $A = open(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $A = open(..., $S % request.$W.get(...), ...) - - pattern: $A = open(..., f"...{request.$W.get(...)}...", ...) - - pattern: return open(..., request.$W.get(...), ...) - - pattern: return open(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: return open(..., $S % request.$W.get(...), ...) - - pattern: return open(..., f"...{request.$W.get(...)}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - with open(..., $DATA, ...) as $FD: - ... - - pattern: open(..., request.$W(...), ...) - - pattern: open(..., $S.format(..., request.$W(...), ...), ...) - - pattern: open(..., $S % request.$W(...), ...) - - pattern: open(..., f"...{request.$W(...)}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - open(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W(...) - ... - open(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W(...) - ... - open(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W(...) - ... - open(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W(...) - ... - open(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: $A = open(..., request.$W(...), ...) - - pattern: $A = open(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $A = open(..., $S % request.$W(...), ...) - - pattern: $A = open(..., f"...{request.$W(...)}...", ...) - - pattern: return open(..., request.$W(...), ...) - - pattern: return open(..., $S.format(..., request.$W(...), ...), ...) - - pattern: return open(..., $S % request.$W(...), ...) - - pattern: return open(..., f"...{request.$W(...)}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - with open(..., $DATA, ...) as $FD: - ... - - pattern: open(..., request.$W[...], ...) - - pattern: open(..., $S.format(..., request.$W[...], ...), ...) - - pattern: open(..., $S % request.$W[...], ...) - - pattern: open(..., f"...{request.$W[...]}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - open(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W[...] - ... - open(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W[...] - ... - open(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W[...] - ... - open(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W[...] - ... - open(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: $A = open(..., request.$W[...], ...) - - pattern: $A = open(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $A = open(..., $S % request.$W[...], ...) - - pattern: $A = open(..., f"...{request.$W[...]}...", ...) - - pattern: return open(..., request.$W[...], ...) - - pattern: return open(..., $S.format(..., request.$W[...], ...), ...) - - pattern: return open(..., $S % request.$W[...], ...) - - pattern: return open(..., f"...{request.$W[...]}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - with open(..., $DATA, ...) as $FD: - ... - - pattern: open(..., request.$W, ...) - - pattern: open(..., $S.format(..., request.$W, ...), ...) - - pattern: open(..., $S % request.$W, ...) - - pattern: open(..., f"...{request.$W}...", ...) - - pattern: | - $DATA = request.$W - ... - open(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W - ... - open(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W - ... - open(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W - ... - open(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: | - $DATA = request.$W - ... - open(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - open(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - with open(..., $INTERM, ...) as $FD: - ... - - pattern: $A = open(..., request.$W, ...) - - pattern: $A = open(..., $S.format(..., request.$W, ...), ...) - - pattern: $A = open(..., $S % request.$W, ...) - - pattern: $A = open(..., f"...{request.$W}...", ...) - - pattern: return open(..., request.$W, ...) - - pattern: return open(..., $S.format(..., request.$W, ...), ...) - - pattern: return open(..., $S % request.$W, ...) - - pattern: return open(..., f"...{request.$W}...", ...) - - pattern: | - $DATA = request.$W - ... - with open(..., $DATA, ...) as $FD: - ... - severity: WARNING - - id: python.django.security.injection.raw-html-format.raw-html-format - languages: - - python - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates (`django.shortcuts.render`) which will safely render HTML instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.2/topics/http/shortcuts/#render - - https://docs.djangoproject.com/en/3.2/topics/security/#cross-site-scripting-xss-protection - subcategory: - - vuln - technology: - - django - mode: taint - pattern-sanitizers: - - pattern: django.utils.html.escape(...) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: '"$HTMLSTR" % ...' - - pattern: '"$HTMLSTR".format(...)' - - pattern: '"$HTMLSTR" + ...' - - pattern: f"$HTMLSTR{...}..." - - patterns: - - pattern-inside: | - $HTML = "$HTMLSTR" - ... - - pattern-either: - - pattern: $HTML % ... - - pattern: $HTML.format(...) - - pattern: $HTML + ... - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - pattern-sources: - - patterns: - - pattern: request.$ANYTHING - - pattern-not: request.build_absolute_uri - severity: WARNING - - id: python.django.security.injection.reflected-data-httpresponse.reflected-data-httpresponse - languages: - - python - message: Found user-controlled request data passed into HttpResponse. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: django.http.HttpResponse(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: django.http.HttpResponse(..., $S % request.$W.get(...), ...) - - pattern: django.http.HttpResponse(..., f"...{request.$W.get(...)}...", ...) - - pattern: django.http.HttpResponse(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponse(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponse(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponse(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponse(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponse(..., request.$W.get(...), ...) - - pattern: return django.http.HttpResponse(..., request.$W.get(...), ...) - - pattern: django.http.HttpResponse(..., $S.format(..., request.$W(...), ...), ...) - - pattern: django.http.HttpResponse(..., $S % request.$W(...), ...) - - pattern: django.http.HttpResponse(..., f"...{request.$W(...)}...", ...) - - pattern: django.http.HttpResponse(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponse(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponse(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponse(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponse(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponse(..., request.$W(...), ...) - - pattern: return django.http.HttpResponse(..., request.$W(...), ...) - - pattern: django.http.HttpResponse(..., $S.format(..., request.$W[...], ...), ...) - - pattern: django.http.HttpResponse(..., $S % request.$W[...], ...) - - pattern: django.http.HttpResponse(..., f"...{request.$W[...]}...", ...) - - pattern: django.http.HttpResponse(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponse(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponse(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponse(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponse(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponse(..., request.$W[...], ...) - - pattern: return django.http.HttpResponse(..., request.$W[...], ...) - - pattern: django.http.HttpResponse(..., $S.format(..., request.$W, ...), ...) - - pattern: django.http.HttpResponse(..., $S % request.$W, ...) - - pattern: django.http.HttpResponse(..., f"...{request.$W}...", ...) - - pattern: django.http.HttpResponse(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponse(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponse(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponse(..., f"...{$DATA}...", ...) - - pattern: $A = django.http.HttpResponse(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - $A = django.http.HttpResponse(..., $INTERM, ...) - - pattern: return django.http.HttpResponse(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponse(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponse(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponse(..., $INTERM, ...) - severity: WARNING - - id: python.django.security.injection.reflected-data-httpresponsebadrequest.reflected-data-httpresponsebadrequest - languages: - - python - message: Found user-controlled request data passed into a HttpResponseBadRequest. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W.get(...), ...) - - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W.get(...)}...", ...) - - pattern: django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseBadRequest(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) - - pattern: return django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W(...), ...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W(...), ...) - - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W(...)}...", ...) - - pattern: django.http.HttpResponseBadRequest(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseBadRequest(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W(...), ...) - - pattern: return django.http.HttpResponseBadRequest(..., request.$W(...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W[...], ...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W[...], ...) - - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W[...]}...", ...) - - pattern: django.http.HttpResponseBadRequest(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseBadRequest(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W[...], ...) - - pattern: return django.http.HttpResponseBadRequest(..., request.$W[...], ...) - - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W, ...), ...) - - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W, ...) - - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W}...", ...) - - pattern: django.http.HttpResponseBadRequest(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseBadRequest(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - django.http.HttpResponseBadRequest(..., $INTERM, ...) - - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W, ...) - - pattern: return django.http.HttpResponseBadRequest(..., request.$W, ...) - severity: WARNING - - id: python.django.security.injection.request-data-fileresponse.request-data-fileresponse - languages: - - python - message: Found user-controlled request data being passed into a file open, which is them passed as an argument into the FileResponse. This is dangerous because an attacker could specify an arbitrary file to read, which could result in leaking important data. Be sure to validate or sanitize the user-inputted filename in the request data before using it in FileResponse. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: django.http.FileResponse(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.http.FileResponse(..., open($DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = open($DATA, ...) - ... - django.http.FileResponse(..., $INTERM, ...) - - pattern: $A = django.http.FileResponse(..., request.$W.get(...), ...) - - pattern: return django.http.FileResponse(..., request.$W.get(...), ...) - - pattern: django.http.FileResponse(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.http.FileResponse(..., open($DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = open($DATA, ...) - ... - django.http.FileResponse(..., $INTERM, ...) - - pattern: $A = django.http.FileResponse(..., request.$W(...), ...) - - pattern: return django.http.FileResponse(..., request.$W(...), ...) - - pattern: django.http.FileResponse(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.http.FileResponse(..., open($DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = open($DATA, ...) - ... - django.http.FileResponse(..., $INTERM, ...) - - pattern: $A = django.http.FileResponse(..., request.$W[...], ...) - - pattern: return django.http.FileResponse(..., request.$W[...], ...) - - pattern: django.http.FileResponse(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - django.http.FileResponse(..., open($DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = open($DATA, ...) - ... - django.http.FileResponse(..., $INTERM, ...) - - pattern: $A = django.http.FileResponse(..., request.$W, ...) - - pattern: return django.http.FileResponse(..., request.$W, ...) - severity: WARNING - - id: python.django.security.injection.request-data-write.request-data-write - languages: - - python - message: Found user-controlled request data passed into '.write(...)'. This could be dangerous if a malicious actor is able to control data into sensitive files. For example, a malicious actor could force rolling of critical log files, or cause a denial-of-service by using up available disk space. Instead, ensure that request data is properly escaped or sanitized. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-93: Improper Neutralization of CRLF Sequences (''CRLF Injection'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - django - pattern-either: - - pattern: $F.write(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $F.write(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $F.write(..., $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $F.write(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $F.write(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - $F.write(..., $INTERM, ...) - - pattern: $A = $F.write(..., request.$W.get(...), ...) - - pattern: return $F.write(..., request.$W.get(...), ...) - - pattern: $F.write(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $F.write(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $F.write(..., $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $F.write(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $F.write(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - $F.write(..., $INTERM, ...) - - pattern: $A = $F.write(..., request.$W(...), ...) - - pattern: return $F.write(..., request.$W(...), ...) - - pattern: $F.write(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $F.write(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $F.write(..., $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $F.write(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $F.write(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - $F.write(..., $INTERM, ...) - - pattern: $A = $F.write(..., request.$W[...], ...) - - pattern: return $F.write(..., request.$W[...], ...) - - pattern: $F.write(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - $F.write(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $F.write(..., $B.$C(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $B.$C(..., $DATA, ...) - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $F.write(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - $F.write(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $F.write(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - $F.write(..., $INTERM, ...) - - pattern: $A = $F.write(..., request.$W, ...) - - pattern: return $F.write(..., request.$W, ...) - severity: WARNING - - id: python.django.security.injection.sql.sql-injection-extra.sql-injection-using-extra-where - languages: - - python - message: User-controlled data from a request is passed to 'extra()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use parameterized queries or escape the user-controlled data by using `params` and not using quote placeholders in the SQL string. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.0/ref/models/expressions/#.objects.extra - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W.get(...), ...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W.get(...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W.get(...)}...", ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) - - pattern: return $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W(...), ...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W(...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W(...)}...", ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) - - pattern: return $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W[...], ...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W[...], ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W[...]}...", ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) - - pattern: return $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W, ...), ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W, ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W}...", ...], ...) - - pattern: $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) - - pattern: return $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) - severity: WARNING - - id: python.django.security.injection.sql.sql-injection-rawsql.sql-injection-using-rawsql - languages: - - python - message: User-controlled data from request is passed to 'RawSQL()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use parameterized queries or escape the user-controlled data by using `params` and not using quote placeholders in the SQL string. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.0/ref/models/expressions/#django.db.models.expressions.RawSQL - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W.get(...), ...) - - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W.get(...)}...", ...) - - pattern: django.db.models.expressions.RawSQL(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W.get(...), ...) - - pattern: return django.db.models.expressions.RawSQL(..., request.$W.get(...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W(...), ...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W(...), ...) - - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W(...)}...", ...) - - pattern: django.db.models.expressions.RawSQL(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W(...), ...) - - pattern: return django.db.models.expressions.RawSQL(..., request.$W(...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W[...], ...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W[...], ...) - - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W[...]}...", ...) - - pattern: django.db.models.expressions.RawSQL(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - django.db.models.expressions.RawSQL(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W[...], ...) - - pattern: return django.db.models.expressions.RawSQL(..., request.$W[...], ...) - - pattern: django.db.models.expressions.RawSQL(..., $S.format(..., request.$W, ...), ...) - - pattern: django.db.models.expressions.RawSQL(..., $S % request.$W, ...) - - pattern: django.db.models.expressions.RawSQL(..., f"...{request.$W}...", ...) - - pattern: django.db.models.expressions.RawSQL(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - django.db.models.expressions.RawSQL(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.db.models.expressions.RawSQL(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.db.models.expressions.RawSQL(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.db.models.expressions.RawSQL(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - django.db.models.expressions.RawSQL(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - django.db.models.expressions.RawSQL(..., $INTERM, ...) - - pattern: $A = django.db.models.expressions.RawSQL(..., request.$W, ...) - - pattern: return django.db.models.expressions.RawSQL(..., request.$W, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - django.db.models.expressions.RawSQL($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - django.db.models.expressions.RawSQL($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - django.db.models.expressions.RawSQL($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - django.db.models.expressions.RawSQL($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - django.db.models.expressions.RawSQL($INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - django.db.models.expressions.RawSQL($INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % (..., $DATA, ...) - ... - django.db.models.expressions.RawSQL($INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % (..., $DATA, ...) - ... - django.db.models.expressions.RawSQL($INTERM, ...) - severity: WARNING - - id: python.django.security.injection.sql.sql-injection-using-db-cursor-execute.sql-injection-db-cursor-execute - languages: - - python - message: User-controlled data from a request is passed to 'execute()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use django's QuerySets, which are built with query parameterization and therefore not vulnerable to sql injection. For example, you could use `Entry.objects.filter(date=2006)`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.0/topics/security/#sql-injection-protection - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: $CURSOR.execute(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $CURSOR.execute(..., $S % request.$W.get(...), ...) - - pattern: $CURSOR.execute(..., f"...{request.$W.get(...)}...", ...) - - pattern: $CURSOR.execute(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $CURSOR.execute(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $CURSOR.execute(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $CURSOR.execute(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $CURSOR.execute(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: $A = $CURSOR.execute(..., request.$W.get(...), ...) - - pattern: return $CURSOR.execute(..., request.$W.get(...), ...) - - pattern: $CURSOR.execute(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $CURSOR.execute(..., $S % request.$W(...), ...) - - pattern: $CURSOR.execute(..., f"...{request.$W(...)}...", ...) - - pattern: $CURSOR.execute(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: $A = $CURSOR.execute(..., request.$W(...), ...) - - pattern: return $CURSOR.execute(..., request.$W(...), ...) - - pattern: $CURSOR.execute(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $CURSOR.execute(..., $S % request.$W[...], ...) - - pattern: $CURSOR.execute(..., f"...{request.$W[...]}...", ...) - - pattern: $CURSOR.execute(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: $A = $CURSOR.execute(..., request.$W[...], ...) - - pattern: return $CURSOR.execute(..., request.$W[...], ...) - - pattern: $CURSOR.execute(..., $S.format(..., request.$W, ...), ...) - - pattern: $CURSOR.execute(..., $S % request.$W, ...) - - pattern: $CURSOR.execute(..., f"...{request.$W}...", ...) - - pattern: $CURSOR.execute(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - $CURSOR.execute(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $CURSOR.execute(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $CURSOR.execute(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $CURSOR.execute(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - $CURSOR.execute(..., $INTERM, ...) - - pattern: $A = $CURSOR.execute(..., request.$W, ...) - - pattern: return $CURSOR.execute(..., request.$W, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $CURSOR.execute($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $CURSOR.execute($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $CURSOR.execute($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $CURSOR.execute($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $CURSOR.execute($INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $CURSOR.execute($INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $CURSOR.execute($INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $CURSOR.execute($INTERM, ...) - severity: WARNING - - id: python.django.security.injection.sql.sql-injection-using-raw.sql-injection-using-raw - languages: - - python - message: Data that is possible user-controlled from a python request is passed to `raw()`. This could lead to SQL injection and attackers gaining access to protected information. Instead, use django's QuerySets, which are built with query parameterization and therefore not vulnerable to sql injection. For example, you could use `Entry.objects.filter(date=2006)`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.0/topics/security/#sql-injection-protection - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: $MODEL.objects.raw(..., $S % request.$W.get(...), ...) - - pattern: $MODEL.objects.raw(..., f"...{request.$W.get(...)}...", ...) - - pattern: $MODEL.objects.raw(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: $A = $MODEL.objects.raw(..., request.$W.get(...), ...) - - pattern: return $MODEL.objects.raw(..., request.$W.get(...), ...) - - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W(...), ...), ...) - - pattern: $MODEL.objects.raw(..., $S % request.$W(...), ...) - - pattern: $MODEL.objects.raw(..., f"...{request.$W(...)}...", ...) - - pattern: $MODEL.objects.raw(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: $A = $MODEL.objects.raw(..., request.$W(...), ...) - - pattern: return $MODEL.objects.raw(..., request.$W(...), ...) - - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W[...], ...), ...) - - pattern: $MODEL.objects.raw(..., $S % request.$W[...], ...) - - pattern: $MODEL.objects.raw(..., f"...{request.$W[...]}...", ...) - - pattern: $MODEL.objects.raw(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: $A = $MODEL.objects.raw(..., request.$W[...], ...) - - pattern: return $MODEL.objects.raw(..., request.$W[...], ...) - - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W, ...), ...) - - pattern: $MODEL.objects.raw(..., $S % request.$W, ...) - - pattern: $MODEL.objects.raw(..., f"...{request.$W}...", ...) - - pattern: $MODEL.objects.raw(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - $MODEL.objects.raw(..., $INTERM, ...) - - pattern: $A = $MODEL.objects.raw(..., request.$W, ...) - - pattern: return $MODEL.objects.raw(..., request.$W, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $MODEL.objects.raw($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $MODEL.objects.raw($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $MODEL.objects.raw($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $MODEL.objects.raw($STR % (..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.raw($INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.raw($INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.raw($INTERM, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % (..., $DATA, ...) - ... - $MODEL.objects.raw($INTERM, ...) - severity: WARNING - - id: python.django.security.injection.ssrf.ssrf-injection-requests.ssrf-injection-requests - languages: - - python - message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF). To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. See https://owasp.org/www-community/attacks/Server_Side_Request_Forgery to learn more about SSRF vulnerabilities. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: requests.$METHOD(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: requests.$METHOD(..., $S % request.$W.get(...), ...) - - pattern: requests.$METHOD(..., f"...{request.$W.get(...)}...", ...) - - pattern: requests.$METHOD(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - requests.$METHOD(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - requests.$METHOD(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - requests.$METHOD(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - requests.$METHOD(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: $A = requests.$METHOD(..., request.$W.get(...), ...) - - pattern: return requests.$METHOD(..., request.$W.get(...), ...) - - pattern: requests.$METHOD(..., $S.format(..., request.$W(...), ...), ...) - - pattern: requests.$METHOD(..., $S % request.$W(...), ...) - - pattern: requests.$METHOD(..., f"...{request.$W(...)}...", ...) - - pattern: requests.$METHOD(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - requests.$METHOD(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - requests.$METHOD(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - requests.$METHOD(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - requests.$METHOD(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: $A = requests.$METHOD(..., request.$W(...), ...) - - pattern: return requests.$METHOD(..., request.$W(...), ...) - - pattern: requests.$METHOD(..., $S.format(..., request.$W[...], ...), ...) - - pattern: requests.$METHOD(..., $S % request.$W[...], ...) - - pattern: requests.$METHOD(..., f"...{request.$W[...]}...", ...) - - pattern: requests.$METHOD(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - requests.$METHOD(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - requests.$METHOD(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - requests.$METHOD(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - requests.$METHOD(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: $A = requests.$METHOD(..., request.$W[...], ...) - - pattern: return requests.$METHOD(..., request.$W[...], ...) - - pattern: requests.$METHOD(..., $S.format(..., request.$W, ...), ...) - - pattern: requests.$METHOD(..., $S % request.$W, ...) - - pattern: requests.$METHOD(..., f"...{request.$W}...", ...) - - pattern: requests.$METHOD(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - requests.$METHOD(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - requests.$METHOD(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - requests.$METHOD(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - requests.$METHOD(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - requests.$METHOD(..., $INTERM, ...) - - pattern: $A = requests.$METHOD(..., request.$W, ...) - - pattern: return requests.$METHOD(..., request.$W, ...) - severity: ERROR - - id: python.django.security.injection.ssrf.ssrf-injection-urllib.ssrf-injection-urllib - languages: - - python - message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF), which could result in attackers gaining access to private organization data. To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery - subcategory: - - vuln - technology: - - django - patterns: - - pattern-inside: | - def $FUNC(...): - ... - - pattern-either: - - pattern: urllib.request.urlopen(..., $S.format(..., request.$W.get(...), ...), ...) - - pattern: urllib.request.urlopen(..., $S % request.$W.get(...), ...) - - pattern: urllib.request.urlopen(..., f"...{request.$W.get(...)}...", ...) - - pattern: urllib.request.urlopen(..., request.$W.get(...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - urllib.request.urlopen(..., $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - urllib.request.urlopen(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR % $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - urllib.request.urlopen(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = f"...{$DATA}..." - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - urllib.request.urlopen(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W.get(...) - ... - $INTERM = $STR + $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: $A = urllib.request.urlopen(..., request.$W.get(...), ...) - - pattern: return urllib.request.urlopen(..., request.$W.get(...), ...) - - pattern: urllib.request.urlopen(..., $S.format(..., request.$W(...), ...), ...) - - pattern: urllib.request.urlopen(..., $S % request.$W(...), ...) - - pattern: urllib.request.urlopen(..., f"...{request.$W(...)}...", ...) - - pattern: urllib.request.urlopen(..., request.$W(...), ...) - - pattern: | - $DATA = request.$W(...) - ... - urllib.request.urlopen(..., $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - urllib.request.urlopen(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR % $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - urllib.request.urlopen(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = f"...{$DATA}..." - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W(...) - ... - urllib.request.urlopen(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W(...) - ... - $INTERM = $STR + $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: $A = urllib.request.urlopen(..., request.$W(...), ...) - - pattern: return urllib.request.urlopen(..., request.$W(...), ...) - - pattern: urllib.request.urlopen(..., $S.format(..., request.$W[...], ...), ...) - - pattern: urllib.request.urlopen(..., $S % request.$W[...], ...) - - pattern: urllib.request.urlopen(..., f"...{request.$W[...]}...", ...) - - pattern: urllib.request.urlopen(..., request.$W[...], ...) - - pattern: | - $DATA = request.$W[...] - ... - urllib.request.urlopen(..., $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - urllib.request.urlopen(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR % $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - urllib.request.urlopen(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = f"...{$DATA}..." - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W[...] - ... - urllib.request.urlopen(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W[...] - ... - $INTERM = $STR + $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: $A = urllib.request.urlopen(..., request.$W[...], ...) - - pattern: return urllib.request.urlopen(..., request.$W[...], ...) - - pattern: urllib.request.urlopen(..., $S.format(..., request.$W, ...), ...) - - pattern: urllib.request.urlopen(..., $S % request.$W, ...) - - pattern: urllib.request.urlopen(..., f"...{request.$W}...", ...) - - pattern: urllib.request.urlopen(..., request.$W, ...) - - pattern: | - $DATA = request.$W - ... - urllib.request.urlopen(..., $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR.format(..., $DATA, ...) - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - urllib.request.urlopen(..., $STR % $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR % $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - urllib.request.urlopen(..., f"...{$DATA}...", ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = f"...{$DATA}..." - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: | - $DATA = request.$W - ... - urllib.request.urlopen(..., $STR + $DATA, ...) - - pattern: | - $DATA = request.$W - ... - $INTERM = $STR + $DATA - ... - urllib.request.urlopen(..., $INTERM, ...) - - pattern: $A = urllib.request.urlopen(..., request.$W, ...) - - pattern: return urllib.request.urlopen(..., request.$W, ...) - severity: ERROR - - id: python.django.security.injection.tainted-sql-string.tainted-sql-string - languages: - - python - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using the Django object-relational mappers (ORM) instead of raw SQL queries. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: LOW - likelihood: MEDIUM - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.djangoproject.com/en/3.0/topics/security/#sql-injection-protection - subcategory: - - audit - technology: - - django - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR" % ... - - pattern: | - "$SQLSTR".format(...) - - pattern: | - f"$SQLSTR{...}..." - - metavariable-regex: - metavariable: $SQLSTR - regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.* - pattern-sources: - - patterns: - - pattern: request.$ANYTHING - - pattern-not: request.build_absolute_uri - severity: ERROR - - id: python.django.security.injection.tainted-url-host.tainted-url-host - languages: - - python - message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - flask - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: '"$URLSTR" % ...' - - metavariable-pattern: - language: generic - metavariable: $URLSTR - patterns: - - pattern-either: - - pattern: $SCHEME://%s - - pattern: $SCHEME://%r - - patterns: - - pattern: '"$URLSTR".format(...)' - - metavariable-pattern: - language: generic - metavariable: $URLSTR - pattern: $SCHEME:// { ... } - - patterns: - - pattern: '"$URLSTR" + ...' - - metavariable-regex: - metavariable: $URLSTR - regex: .*://$ - - patterns: - - pattern: f"$URLSTR{...}..." - - metavariable-regex: - metavariable: $URLSTR - regex: .*://$ - - patterns: - - pattern-inside: | - $URL = "$URLSTR" - ... - - pattern: $URL += ... - - metavariable-regex: - metavariable: $URLSTR - regex: .*://$ - pattern-sources: - - patterns: - - pattern: request.$ANYTHING - - pattern-not: request.build_absolute_uri - severity: WARNING - - id: python.django.security.locals-as-template-context.locals-as-template-context - languages: - - python - message: 'Using ''locals()'' as a context to ''render(...)'' is extremely dangerous. This exposes Python functions to the template that were not meant to be exposed. An attacker could use these functions to execute code that was not intended to run and could compromise the application. (This is server-side template injection (SSTI)). Do not use ''locals()''. Instead, specify each variable in a dictionary or ''django.template.Context'' object, like ''{"var1": "hello"}'' and use that instead.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://docs.djangoproject.com/en/3.2/ref/settings/#templates - - https://docs.djangoproject.com/en/3.2/topics/templates/#django.template.backends.django.DjangoTemplates - - https://docs.djangoproject.com/en/3.2/ref/templates/api/#rendering-a-context - subcategory: - - audit - technology: - - django - pattern-either: - - pattern: django.shortcuts.render(..., locals(...), ...) - - pattern: django.template.Template.render(..., locals(...), ...) - - patterns: - - pattern-inside: | - $CONTEXT = locals(...) - ... - - pattern-either: - - pattern: django.shortcuts.render(..., $CONTEXT, ...) - - pattern: django.template.Template.render(..., $CONTEXT, ...) - severity: ERROR - - id: python.django.security.nan-injection.nan-injection - languages: - - python - message: Found user input going directly into typecast for bool(), float(), or complex(). This allows an attacker to inject Python's not-a-number (NaN) into the typecast. This results in undefind behavior, particularly when doing comparisons. Either cast to a different type, or add a guard checking for all capitalizations of the string 'nan'. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-704: Incorrect Type Conversion or Cast' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://discuss.python.org/t/nan-breaks-min-max-and-sorting-functions-a-solution/2868 - - https://blog.bitdiscovery.com/2021/12/python-nan-injection/ - subcategory: - - vuln - technology: - - django - mode: taint - pattern-sanitizers: - - not_conflicting: true - pattern: $ANYTHING(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: float(...) - - pattern: bool(...) - - pattern: complex(...) - - pattern-not-inside: | - if $COND: - ... - ... - pattern-sources: - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - severity: ERROR - - id: python.django.security.passwords.password-empty-string.password-empty-string - languages: - - python - message: '''$VAR'' is the empty string and is being used to set the password on ''$MODEL''. If you meant to set an unusable password, set the password to None or call ''set_unusable_password()''.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-521: Weak Password Requirements' - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://docs.djangoproject.com/en/3.0/ref/contrib/auth/#django.contrib.auth.models.User.set_password - subcategory: - - vuln - technology: - - django - patterns: - - pattern-either: - - pattern: | - $MODEL.set_password($EMPTY) - ... - $MODEL.save() - - pattern: | - $VAR = $EMPTY - ... - $MODEL.set_password($VAR) - ... - $MODEL.save() - - metavariable-regex: - metavariable: $EMPTY - regex: (\'\'|\"\") - severity: ERROR - - fix: | - None - id: python.django.security.passwords.use-none-for-password-default.use-none-for-password-default - languages: - - python - message: '''$VAR'' is using the empty string as its default and is being used to set the password on ''$MODEL''. If you meant to set an unusable password, set the default value to ''None'' or call ''set_unusable_password()''.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-521: Weak Password Requirements' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://docs.djangoproject.com/en/3.0/ref/contrib/auth/#django.contrib.auth.models.User.set_password - subcategory: - - vuln - technology: - - django - patterns: - - pattern-either: - - pattern: | - $VAR = request.$W.get($X, $EMPTY) - ... - $MODEL.set_password($VAR) - ... - $MODEL.save(...) - - pattern: | - def $F(..., $VAR=$EMPTY, ...): - ... - $MODEL.set_password($VAR) - - metavariable-pattern: - metavariable: $EMPTY - pattern: '""' - - focus-metavariable: $EMPTY - severity: ERROR - - id: python.docker.security.audit.docker-arbitrary-container-run.docker-arbitrary-container-run - languages: - - python - message: If unverified user data can reach the `run` or `create` method it can result in running arbitrary container. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: HIGH - likelihood: LOW - references: - - https://cwe.mitre.org/data/definitions/250.html - subcategory: - - audit - technology: - - docker - patterns: - - pattern-either: - - pattern-inside: | - $CLIENT = docker.from_env() - ... - - pattern-inside: | - $CLIENT = docker.DockerClient(...) - ... - - pattern-either: - - pattern: | - $CLIENT.containers.run(...) - - pattern: | - $CLIENT.containers.create(...) - - pattern-not: | - $CLIENT.containers.run("...",...) - - pattern-not: | - $CLIENT.containers.create("...",...) - severity: WARNING - - id: python.flask.best-practice.get-class-method-with-side-effects.flask-class-method-get-side-effects - languages: - - python - message: Flask class method GET with side effects - metadata: - category: best-practice - technology: - - flask - patterns: - - pattern-either: - - pattern: | - def get(self,...): - ... - $METHOD(...) - - pattern: | - def get(self,...): - ... - $VAR = $METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (?i)(create|update|delete).* - severity: WARNING - - fix: | - flask.jsonify($...VAR) - id: python.flask.best-practice.use-jsonify.use-jsonify - languages: - - python - message: flask.jsonify() is a Flask helper method which handles the correct settings for returning JSON from Flask routes - metadata: - category: best-practice - references: - - https://flask.palletsprojects.com/en/2.2.x/api/#flask.json.jsonify - technology: - - flask - patterns: - - pattern: $JSONDUMPS - - pattern-either: - - pattern-inside: | - return json.dumps($...VAR) - - pattern-inside: | - $DATA = json.dumps($...VAR) - ... - return $DATA - - pattern-inside: | - @app.route(...) - def $X(): - ... - - metavariable-pattern: - metavariable: $JSONDUMPS - pattern: json.dumps($...VAR) - - focus-metavariable: $JSONDUMPS - severity: ERROR - - id: python.flask.caching.query-string.flask-cache-query-string - languages: - - python - message: Flask-caching doesn't cache query strings by default. You have to use `query_string=True`. Also you shouldn't cache verbs that can mutate state. - metadata: - category: caching - technology: - - flask - patterns: - - pattern-either: - - pattern: | - @app.route("...") - @cache.cached(...) - def $HANDLER(...): - ... - request.args.get(...) - - pattern: | - @app.route("...", methods=[..., "POST", ...]) - @cache.cached(...) - def $HANDLER(...): - ... - - pattern: | - @app.route("...", methods=[..., "PUT", ...]) - @cache.cached(...) - def $HANDLER(...): - ... - - pattern: | - @app.route("...", methods=[..., "DELETE", ...]) - @cache.cached(...) - def $HANDLER(...): - ... - - pattern: | - @app.route("...", methods=[..., "PATCH", ...]) - @cache.cached(...) - def $HANDLER(...): - ... - - pattern-not: | - @app.route("...") - @cache.cached(..., query_string=True) - def $HANDLER(...): - ... - request.args.get(...) - severity: WARNING - - id: python.flask.correctness.access-request-in-wrong-handler.avoid-accessing-request-in-wrong-handler - languages: - - python - message: Accessing request object inside a route handle for HTTP GET command will throw due to missing request body. - metadata: - category: correctness - technology: - - flask - patterns: - - pattern-inside: | - @app.route(..., method="GET") - def $X(...): - ... - - pattern-either: - - pattern: | - $Y = flask.request.json - - pattern: | - $Y = flask.request.form - - pattern: | - $Y = flask.request.data - severity: WARNING - - id: python.flask.correctness.same-handler-name.flask-duplicate-handler-name - languages: - - python - message: Looks like `$R` is a flask function handler that registered to two different routes. This will cause a runtime error - metadata: - category: correctness - technology: - - flask - pattern: | - @app.route("...", ...) - def $R(...): - ... - ... - @app.route("...", ...) - def $R(...): - ... - severity: WARNING - - id: python.flask.maintainability.deprecated.deprecated-apis.flask-deprecated-apis - languages: - - python - message: deprecated Flask API - metadata: - category: maintainability - technology: - - flask - pattern-either: - - pattern: | - $F = Flask(...) - ... - $F.open_session(...) - - pattern: | - $F = Flask(...) - ... - $F.save_session(...) - - pattern: | - $F = Flask(...) - ... - $F.make_null_session(...) - - pattern: | - $F = Flask(...) - ... - $F.init_jinja_globals(...) - - pattern: | - $F = Flask(...) - ... - $F.request_globals_class(...) - - pattern: | - $F = Flask(...) - ... - $F.static_path(...) - - pattern: app.open_session(...) - - pattern: app.save_session(...) - - pattern: app.make_null_session(...) - - pattern: app.init_jinja_globals(...) - - pattern: app.request_globals_class(...) - - pattern: app.static_path(...) - - pattern: app.config.from_json(...) - - pattern: flask.json_available - - pattern: flask.request.module - - pattern: flask.testing.make_test_environ_builder(...) - severity: WARNING - - id: python.flask.security.audit.app-run-param-config.avoid_app_run_with_bad_host - languages: - - python - message: Running flask app with host 0.0.0.0 could expose the server publicly. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-668: Exposure of Resource to Wrong Sphere' - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - flask - pattern-either: - - pattern: app.run(..., host="0.0.0.0", ...) - - pattern: app.run(..., "0.0.0.0", ...) - severity: WARNING - - id: python.flask.security.audit.app-run-security-config.avoid_using_app_run_directly - languages: - - python - message: top-level app.run(...) is ignored by flask. Consider putting app.run(...) behind a guard, like inside a function - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-668: Exposure of Resource to Wrong Sphere' - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - flask - patterns: - - pattern-not-inside: | - if __name__ == '__main__': - ... - - pattern-not-inside: | - def $X(...): - ... - - pattern: app.run(...) - severity: WARNING - - id: python.flask.security.audit.debug-enabled.debug-enabled - languages: - - python - message: Detected Flask app with debug=True. Do not deploy to production with this flag enabled as it will leak sensitive information. Instead, consider using Flask configuration variables or setting 'debug' using system environment variables. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-489: Active Debug Code' - impact: MEDIUM - likelihood: HIGH - owasp: A06:2017 - Security Misconfiguration - references: - - https://labs.detectify.com/2015/10/02/how-patreon-got-hacked-publicly-exposed-werkzeug-debugger/ - subcategory: - - vuln - technology: - - flask - patterns: - - pattern-inside: | - import flask - ... - - pattern: $APP.run(..., debug=True, ...) - severity: WARNING - - id: python.flask.security.audit.directly-returned-format-string.directly-returned-format-string - languages: - - python - message: Detected Flask route directly returning a formatted string. This is subject to cross-site scripting if user input can reach the string. Consider using the template engine instead and rendering pages with 'render_template()'. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - flask - mode: taint - pattern-sinks: - - patterns: - - pattern-not-inside: return "..." - - pattern-either: - - pattern: return "...".format(...) - - pattern: return "..." % ... - - pattern: return "..." + ... - - pattern: return ... + "..." - - pattern: return f"...{...}..." - - patterns: - - pattern: return $X - - pattern-either: - - pattern-inside: | - $X = "...".format(...) - ... - - pattern-inside: | - $X = "..." % ... - ... - - pattern-inside: | - $X = "..." + ... - ... - - pattern-inside: | - $X = ... + "..." - ... - - pattern-inside: | - $X = f"...{...}..." - ... - - pattern-not-inside: | - $X = "..." - ... - pattern-sources: - - pattern-either: - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $PARAM, ...): - ... - - pattern: $PARAM - - pattern: | - request.$FUNC.get(...) - - pattern: | - request.$FUNC(...) - - pattern: request.$FUNC[...] - severity: WARNING - - id: python.flask.security.audit.hardcoded-config.avoid_hardcoded_config_testing - languages: - - python - message: Hardcoded variable `TESTING` detected. Use environment variables or config files instead - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-489: Active Debug Code' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://bento.dev/checks/flask/avoid-hardcoded-config/ - - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#builtin-configuration-values - - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#environment-and-debug-features - subcategory: - - audit - technology: - - flask - pattern-either: - - pattern: $M.config['TESTING'] = True - - pattern: $M.config['TESTING'] = False - - pattern: $M.update(TESTING=True, ...) - - pattern: $M.update(TESTING=False, ...) - severity: WARNING - - id: python.flask.security.audit.hardcoded-config.avoid_hardcoded_config_secret_key - languages: - - python - message: Hardcoded variable `SECRET_KEY` detected. Use environment variables or config files instead - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-489: Active Debug Code' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://bento.dev/checks/flask/avoid-hardcoded-config/ - - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#builtin-configuration-values - - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#environment-and-debug-features - subcategory: - - audit - technology: - - flask - pattern-either: - - pattern: $M.update(SECRET_KEY="=~/.*/") - - pattern: $M.config['SECRET_KEY'] = "=~/.*/" - severity: ERROR - - id: python.flask.security.audit.hardcoded-config.avoid_hardcoded_config_env - languages: - - python - message: Hardcoded variable `ENV` detected. Set this by using FLASK_ENV environment variable - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-489: Active Debug Code' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://bento.dev/checks/flask/avoid-hardcoded-config/ - - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#builtin-configuration-values - - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#environment-and-debug-features - subcategory: - - audit - technology: - - flask - pattern-either: - - pattern: $M.update(ENV="=~/^development|production$/") - - pattern: $M.config['ENV'] = "=~/^development|production$/" - severity: WARNING - - id: python.flask.security.audit.hardcoded-config.avoid_hardcoded_config_debug - languages: - - python - message: Hardcoded variable `DEBUG` detected. Set this by using FLASK_DEBUG environment variable - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-489: Active Debug Code' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://bento.dev/checks/flask/avoid-hardcoded-config/ - - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#builtin-configuration-values - - https://flask.palletsprojects.com/en/1.1.x/config/?highlight=configuration#environment-and-debug-features - subcategory: - - audit - technology: - - flask - pattern-either: - - pattern: $M.update(DEBUG=True) - - pattern: $M.update(DEBUG=False) - - pattern: $M.config['DEBUG'] = True - - pattern: $M.config['DEBUG'] = False - severity: WARNING - - id: python.flask.security.audit.host-header-injection-python.host-header-injection-python - languages: - - python - message: The `flask.request.host` is used to construct an HTTP request. This can lead to host header injection issues. Vulnerabilities that generally occur due to this issue are authentication bypasses, password reset issues, Server-Side-Request-Forgery (SSRF), and many more. It is recommended to validate the URL before passing it to a request library, or using application logic such as authentication or password resets. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-20: Improper Input Validation' - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - references: - - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/17-Testing_for_Host_Header_Injection - - https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html - subcategory: - - audit - technology: - - flask - patterns: - - pattern-either: - - pattern: | - $X = <... "=~/.*http[s]*:///" + flask.request.host ...>; - - pattern: | - $X = <... "=~/.*http[s]*:///" + flask.request["host"] ...>; - - pattern: | - $Z = flask.request.host; - ... - $X = <... "=~/.*http[s]*:///" + $Z ...>; - - pattern: | - $Z = flask.request["host"]; - ... - $X = <... "=~/.*http[s]*:///" + $Z ...>; - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(): - ... - severity: INFO - - id: python.flask.security.audit.render-template-string.render-template-string - languages: - - python - message: Found a template created with string formatting. This is susceptible to server-side template injection and cross-site scripting attacks. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://nvisium.com/blog/2016/03/09/exploring-ssti-in-flask-jinja2.html - subcategory: - - audit - technology: - - flask - pattern: flask.render_template_string(...) - severity: WARNING - - id: python.flask.security.audit.secure-set-cookie.secure-set-cookie - languages: - - python - message: Found a Flask cookie with insecurely configured properties. By default the secure, httponly and samesite ar configured insecurely. cookies should be handled securely by setting `secure=True`, `httponly=True`, and `samesite='Lax'` in response.set_cookie(...). If these parameters are not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. Include the `secure=True`, `httponly=True`, `samesite='Lax'` arguments or set these to be true in the Flask configuration. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - functional-categories: - - web::search::cookie-config::flask - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://flask.palletsprojects.com/en/3.0.x/api/#flask.Response.set_cookie - - https://flask.palletsprojects.com/en/3.0.x/security/#set-cookie-options - subcategory: - - audit - technology: - - python - - flask - patterns: - - pattern-either: - - pattern-inside: | - $RESP = flask.make_response(...) - ... - - pattern-inside: | - $RESP = flask.Response(...) - ... - - pattern-not: $RESP.set_cookie(..., secure=$A, httponly=$B, samesite=$C, ...) - - pattern-not: $RESP.set_cookie(..., **$A) - - pattern: $RESP.set_cookie(...) - severity: WARNING - - fix: "True" - id: python.flask.security.audit.wtf-csrf-disabled.flask-wtf-csrf-disabled - languages: - - python - message: Setting 'WTF_CSRF_ENABLED' to 'False' explicitly disables CSRF protection. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - functional-categories: - - web::search::csrf-config::flask - - web::search::csrf-config::flask-wtf - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://flask-wtf.readthedocs.io/en/1.2.x/csrf/ - subcategory: - - audit - technology: - - flask - options: - symbolic_propagation: true - 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 - severity: WARNING - - id: python.flask.security.audit.xss.make-response-with-unknown-content.make-response-with-unknown-content - languages: - - python - message: Be careful with `flask.make_response()`. If this response is rendered onto a webpage, this could create a cross-site scripting (XSS) vulnerability. `flask.make_response()` will not autoescape HTML. If you are rendering HTML, write your HTML in a template file and use `flask.render_template()` which will take care of escaping. If you are returning data from an API, consider using `flask.jsonify()`. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://github.com/python-security/pyt//blob/093a077bcf12d1f58ddeb2d73ddc096623985fb0/examples/vulnerable_code/XSS_assign_to_other_var.py#L11 - - https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.make_response - - https://flask.palletsprojects.com/en/1.1.x/api/#response-objects - subcategory: - - audit - technology: - - flask - patterns: - - pattern: flask.make_response(...) - - pattern-not-inside: flask.make_response() - - pattern-not-inside: flask.make_response("...", ...) - - pattern-not-inside: 'flask.make_response({"...": "..."}, ...)' - - pattern-not-inside: flask.make_response(flask.redirect(...), ...) - - pattern-not-inside: flask.make_response(flask.render_template(...), ...) - - pattern-not-inside: flask.make_response(flask.jsonify(...), ...) - - pattern-not-inside: flask.make_response(json.dumps(...), ...) - - pattern-not-inside: | - $X = flask.render_template(...) - ... - flask.make_response($X, ...) - - pattern-not-inside: | - $X = flask.jsonify(...) - ... - flask.make_response($X, ...) - - pattern-not-inside: | - $X = json.dumps(...) - ... - flask.make_response($X, ...) - severity: WARNING - - id: python.flask.security.dangerous-template-string.dangerous-template-string - languages: - - python - message: Found a template created with string formatting. This is susceptible to server-side template injection and cross-site scripting attacks. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://nvisium.com/blog/2016/03/09/exploring-ssti-in-flask-jinja2.html - - https://pequalsnp-team.github.io/cheatsheet/flask-jinja2-ssti - subcategory: - - audit - technology: - - flask - pattern-either: - - pattern: | - $V = "...".format(...) - ... - flask.render_template_string($V, ...) - - pattern: | - $V = "...".format(...) - ... - return flask.render_template_string($V, ...), $MORE - - pattern: | - $V = "..." % $S - ... - flask.render_template_string($V, ...) - - pattern: | - $V = "..." % $S - ... - return flask.render_template_string($V, ...), $MORE - - pattern: | - $V = "..." - ... - $V += $O - ... - flask.render_template_string($V, ...) - - pattern: | - $V = "..." - ... - $V += $O - ... - return flask.render_template_string($V, ...), $MORE - - pattern: | - $V = f"...{$X}..." - ... - flask.render_template_string($V, ...) - - pattern: | - $V = f"...{$X}..." - ... - return flask.render_template_string($V, ...), $CODE - severity: ERROR - - id: python.flask.security.flask-api-method-string-format.flask-api-method-string-format - languages: - - python - message: Method $METHOD in API controller $CLASS provides user arg $ARG to requests method $REQMETHOD - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-134: Use of Externally-Controlled Format String' - impact: MEDIUM - likelihood: LOW - references: - - https://cwe.mitre.org/data/definitions/134.html - subcategory: - - audit - technology: - - flask - patterns: - - pattern-either: - - pattern: | - def $METHOD(...,$ARG,...): - ... - $STRING = "...".format(...,$ARG,...) - ... - ... = requests.$REQMETHOD($STRING,...) - - pattern: | - def $METHOD(...,$ARG,...): - ... - ... = requests.$REQMETHOD("...".format(...,$ARG,...),...) - - pattern-inside: | - class $CLASS(...): - method_decorators = ... - ... - severity: ERROR - - id: python.flask.security.hashids-with-flask-secret.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 - confidence: HIGH - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: HIGH - likelihood: LOW - 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 - subcategory: - - vuln - technology: - - flask - 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 - - id: python.flask.security.injection.csv-writer-injection.csv-writer-injection - languages: - - python - message: Detected user input into a generated CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1236: Improper Neutralization of Formula Elements in a CSV File' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/raphaelm/defusedcsv - - https://owasp.org/www-community/attacks/CSV_Injection - - https://web.archive.org/web/20220516052229/https://www.contextis.com/us/blog/comma-separated-vulnerabilities - subcategory: - - vuln - technology: - - python - - flask - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - $WRITER = csv.writer(...) - - ... - - $WRITER.$WRITE(...) - - pattern: $WRITER.$WRITE(...) - - metavariable-regex: - metavariable: $WRITE - regex: ^(writerow|writerows|writeheader)$ - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - severity: ERROR - - id: python.flask.security.injection.nan-injection.nan-injection - languages: - - python - message: Found user input going directly into typecast for bool(), float(), or complex(). This allows an attacker to inject Python's not-a-number (NaN) into the typecast. This results in undefind behavior, particularly when doing comparisons. Either cast to a different type, or add a guard checking for all capitalizations of the string 'nan'. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-704: Incorrect Type Conversion or Cast' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://discuss.python.org/t/nan-breaks-min-max-and-sorting-functions-a-solution/2868 - - https://blog.bitdiscovery.com/2021/12/python-nan-injection/ - subcategory: - - vuln - technology: - - flask - mode: taint - pattern-sanitizers: - - not_conflicting: true - pattern: $ANYTHING(...) - pattern-sinks: - - pattern-either: - - pattern: float(...) - - pattern: bool(...) - - pattern: complex(...) - pattern-sources: - - pattern-either: - - pattern: flask.request.$SOMETHING.get(...) - - pattern: flask.request.$SOMETHING[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR - severity: ERROR - - id: python.flask.security.injection.os-system-injection.os-system-injection - languages: - - python - message: User data detected in os.system. This could be vulnerable to a command injection and should be avoided. If this must be done, use the 'subprocess' module instead and pass the arguments as a list. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/Command_Injection - subcategory: - - audit - technology: - - flask - pattern-either: - - patterns: - - pattern: os.system(...) - - pattern-either: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - os.system(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - $INTERM = <... $ROUTEVAR ...> - ... - os.system(..., <... $INTERM ...>, ...) - - pattern: os.system(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: os.system(..., <... flask.request.$W[...] ...>, ...) - - pattern: os.system(..., <... flask.request.$W(...) ...>, ...) - - pattern: os.system(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - os.system(<... $INTERM ...>) - - pattern: os.system(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - os.system(<... $INTERM ...>) - - pattern: os.system(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - os.system(<... $INTERM ...>) - - pattern: os.system(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - os.system(<... $INTERM ...>) - - pattern: os.system(...) - severity: ERROR - - id: python.flask.security.injection.path-traversal-open.path-traversal-open - languages: - - python - message: Found request data in a call to 'open'. Ensure the request data is validated or sanitized, otherwise it could result in path traversal attacks. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - subcategory: - - audit - technology: - - flask - pattern-either: - - patterns: - - pattern: open(...) - - pattern-either: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - open(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - with open(..., <... $ROUTEVAR ...>, ...) as $FD: - ... - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - $INTERM = <... $ROUTEVAR ...> - ... - open(..., <... $INTERM ...>, ...) - - pattern: open(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: open(..., <... flask.request.$W[...] ...>, ...) - - pattern: open(..., <... flask.request.$W(...) ...>, ...) - - pattern: open(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - open(<... $INTERM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - open(<... $INTERM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - open(<... $INTERM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - open(<... $INTERM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - with open(<... $INTERM ...>, ...) as $F: - ... - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - with open(<... $INTERM ...>, ...) as $F: - ... - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - with open(<... $INTERM ...>, ...) as $F: - ... - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - with open(<... $INTERM ...>, ...) as $F: - ... - - pattern: open(...) - severity: ERROR - - id: python.flask.security.injection.raw-html-concat.raw-html-format - languages: - - python - message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates (`flask.render_template`) which will safely render HTML instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://flask.palletsprojects.com/en/2.0.x/security/#cross-site-scripting-xss - subcategory: - - vuln - technology: - - flask - mode: taint - pattern-sanitizers: - - pattern: jinja2.escape(...) - - pattern: flask.escape(...) - - pattern: flask.render_template("~=/.*\.html", ...) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: '"$HTMLSTR" % ...' - - pattern: '"$HTMLSTR".format(...)' - - pattern: '"$HTMLSTR" + ...' - - pattern: f"$HTMLSTR{...}..." - - patterns: - - pattern-inside: | - $HTML = "$HTMLSTR" - ... - - pattern-either: - - pattern: $HTML % ... - - pattern: $HTML.format(...) - - pattern: $HTML + ... - - metavariable-pattern: - language: generic - metavariable: $HTMLSTR - pattern: <$TAG ... - pattern-sources: - - patterns: - - pattern-either: - - pattern: flask.request.$ANYTHING - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR - severity: WARNING - - id: python.flask.security.injection.ssrf-requests.ssrf-requests - languages: - - python - message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF). To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery - subcategory: - - vuln - technology: - - flask - pattern-either: - - patterns: - - pattern: requests.$FUNC(...) - - pattern-either: - - pattern-inside: | - @$APP.$ROUTE_METHOD($ROUTE, ...) - def $ROUTE_FUNC(..., $ROUTEVAR, ...): - ... - requests.$FUNC(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.$ROUTE_METHOD($ROUTE, ...) - def $ROUTE_FUNC(..., $ROUTEVAR, ...): - ... - $INTERM = <... $ROUTEVAR ...> - ... - requests.$FUNC(..., <... $INTERM ...>, ...) - - metavariable-regex: - metavariable: $ROUTE_METHOD - regex: ^(route|get|post|put|delete|patch)$ - - pattern: requests.$FUNC(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: requests.$FUNC(..., <... flask.request.$W[...] ...>, ...) - - pattern: requests.$FUNC(..., <... flask.request.$W(...) ...>, ...) - - pattern: requests.$FUNC(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - requests.$FUNC(<... $INTERM ...>, ...) - - pattern: requests.$FUNC(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - requests.$FUNC(<... $INTERM ...>, ...) - - pattern: requests.$FUNC(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - requests.$FUNC(<... $INTERM ...>, ...) - - pattern: requests.$FUNC(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - requests.$FUNC(<... $INTERM ...>, ...) - - pattern: requests.$FUNC(...) - severity: ERROR - - id: python.flask.security.injection.subprocess-injection.subprocess-injection - languages: - - python - message: Detected user input entering a `subprocess` call unsafely. This could result in a command injection vulnerability. An attacker could use this vulnerability to execute arbitrary commands on the host, which allows them to download malware, scan sensitive data, or run any command they wish on the server. Do not let users choose the command to run. In general, prefer to use Python API versions of system commands. If you must use subprocess, use a dictionary to allowlist a set of commands. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - flask - mode: taint - options: - symbolic_propagation: true - pattern-sanitizers: - - patterns: - - pattern: $DICT[$KEY] - - focus-metavariable: $KEY - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: subprocess.$FUNC(...) - - pattern-not: subprocess.$FUNC("...", ...) - - pattern-not: subprocess.$FUNC(["...", ...], ...) - - pattern-not-inside: | - $CMD = ["...", ...] - ... - subprocess.$FUNC($CMD, ...) - - patterns: - - pattern: subprocess.$FUNC(["$SHELL", "-c", ...], ...) - - metavariable-regex: - metavariable: $SHELL - regex: ^(sh|bash|ksh|csh|tcsh|zsh)$ - - patterns: - - pattern: subprocess.$FUNC(["$INTERPRETER", ...], ...) - - metavariable-regex: - metavariable: $INTERPRETER - regex: ^(python|python\d)$ - pattern-sources: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - severity: ERROR - - id: python.flask.security.injection.tainted-sql-string.tainted-sql-string - languages: - - python - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as SQLAlchemy which will protect your queries. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-704: Incorrect Type Conversion or Cast' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql - - https://www.tutorialspoint.com/sqlalchemy/sqlalchemy_quick_guide.htm - - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-more-specific-text-with-table-expression-literal-column-and-expression-column - subcategory: - - vuln - technology: - - sqlalchemy - - flask - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR" % ... - - pattern: | - "$SQLSTR".format(...) - - pattern: | - f"$SQLSTR{...}..." - - metavariable-regex: - metavariable: $SQLSTR - regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.* - pattern-sources: - - patterns: - - pattern-either: - - pattern: flask.request.$ANYTHING - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR - severity: ERROR - - id: python.flask.security.injection.tainted-url-host.tainted-url-host - languages: - - python - message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - flask - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: '"$URLSTR" % ...' - - metavariable-pattern: - language: generic - metavariable: $URLSTR - patterns: - - pattern-either: - - pattern: $SCHEME://%s - - pattern: $SCHEME://%r - - patterns: - - pattern: '"$URLSTR".format(...)' - - metavariable-pattern: - language: generic - metavariable: $URLSTR - pattern: $SCHEME:// { ... } - - patterns: - - pattern: '"$URLSTR" + ...' - - metavariable-regex: - metavariable: $URLSTR - regex: .*://$ - - patterns: - - pattern: f"$URLSTR{...}..." - - metavariable-regex: - metavariable: $URLSTR - regex: .*://$ - - patterns: - - pattern-inside: | - $URL = "$URLSTR" - ... - - pattern: $URL += ... - - metavariable-regex: - metavariable: $URLSTR - regex: .*://$ - pattern-sources: - - patterns: - - pattern-either: - - pattern: flask.request.$ANYTHING - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR - severity: WARNING - - id: python.flask.security.injection.user-eval.eval-injection - languages: - - python - message: Detected user data flowing into eval. This is code injection and should be avoided. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html - subcategory: - - vuln - technology: - - flask - pattern-either: - - patterns: - - pattern: eval(...) - - pattern-either: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - eval(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - $INTERM = <... $ROUTEVAR ...> - ... - eval(..., <... $INTERM ...>, ...) - - pattern: eval(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: eval(..., <... flask.request.$W[...] ...>, ...) - - pattern: eval(..., <... flask.request.$W(...) ...>, ...) - - pattern: eval(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - eval(..., <... $INTERM ...>, ...) - - pattern: eval(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - eval(..., <... $INTERM ...>, ...) - - pattern: eval(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - eval(..., <... $INTERM ...>, ...) - - pattern: eval(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - eval(..., <... $INTERM ...>, ...) - - pattern: eval(...) - severity: ERROR - - id: python.flask.security.injection.user-exec.exec-injection - languages: - - python - message: Detected user data flowing into exec. This is code injection and should be avoided. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://nedbatchelder.com/blog/201206/exec_really_is_dangerous.html - subcategory: - - vuln - technology: - - flask - pattern-either: - - patterns: - - pattern: exec(...) - - pattern-either: - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - exec(..., <... $ROUTEVAR ...>, ...) - - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - $INTERM = <... $ROUTEVAR ...> - ... - exec(..., <... $INTERM ...>, ...) - - pattern: exec(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: exec(..., <... flask.request.$W[...] ...>, ...) - - pattern: exec(..., <... flask.request.$W(...) ...>, ...) - - pattern: exec(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W.get(...) ...> - ... - exec(..., <... $INTERM ...>, ...) - - pattern: exec(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W[...] ...> - ... - exec(..., <... $INTERM ...>, ...) - - pattern: exec(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W(...) ...> - ... - exec(..., <... $INTERM ...>, ...) - - pattern: exec(...) - - patterns: - - pattern-inside: | - $INTERM = <... flask.request.$W ...> - ... - exec(..., <... $INTERM ...>, ...) - - pattern: exec(...) - severity: ERROR - - id: python.flask.security.insecure-deserialization.insecure-deserialization - languages: - - python - message: Detected the use of an insecure deserialization library in a Flask route. These libraries are prone to code execution vulnerabilities. Ensure user data does not enter this function. To fix this, try to avoid serializing whole objects. Consider instead using a serializer such as JSON. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.python.org/3/library/pickle.html - subcategory: - - audit - technology: - - flask - patterns: - - pattern-inside: | - @app.route(...) - def $X(...): - ... - - pattern-not: $MODULE.$FUNC("...") - - pattern-not: $MODULE.$FUNC(open("...", ...)) - - pattern-either: - - pattern: pickle.$FUNC(...) - - pattern: _pickle.$FUNC(...) - - pattern: cPickle.$FUNC(...) - - pattern: dill.$FUNC(...) - - pattern: shelve.$FUNC(...) - - pattern: yaml.load(...) - severity: ERROR - - id: python.flask.security.open-redirect.open-redirect - languages: - - python - message: Data from request is passed to redirect(). This is an open redirect and could be exploited. Consider using 'url_for()' to generate links to known locations. If you must use a URL to unknown pages, consider using 'urlparse()' or similar and checking if the 'netloc' property is the same as your site's host name. See the references for more information. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://flask-login.readthedocs.io/en/latest/#login-example - - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html#dangerous-url-redirect-example-1 - - https://docs.python.org/3/library/urllib.parse.html#url-parsing - subcategory: - - audit - technology: - - flask - patterns: - - pattern-inside: | - @$APP.route(...) - def $X(...): - ... - - pattern-not-inside: | - @$APP.route(...) - def $X(...): - ... - if <... werkzeug.urls.url_parse($V) ...>: - ... - - pattern-either: - - pattern: flask.redirect(<... flask.request.$W.get(...) ...>, ...) - - pattern: flask.redirect(<... flask.request.$W[...] ...>, ...) - - pattern: flask.redirect(<... flask.request.$W(...) ...>, ...) - - pattern: flask.redirect(<... flask.request.$W ...>, ...) - - pattern: | - $V = flask.request.$W.get(...) - ... - flask.redirect(<... $V ...>, ...) - - pattern: | - $V = flask.request.$W[...] - ... - flask.redirect(<... $V ...>, ...) - - pattern: | - $V = flask.request.$W(...) - ... - flask.redirect(<... $V ...>, ...) - - pattern: | - $V = flask.request.$W - ... - flask.redirect(<... $V ...>, ...) - - pattern-not: flask.redirect(flask.request.path) - - pattern-not: flask.redirect(flask.request.path + ...) - - pattern-not: flask.redirect(f"{flask.request.path}...") - severity: ERROR - - id: python.flask.security.secure-static-file-serve.avoid_send_file_without_path_sanitization - languages: - - python - message: Detected a user-controlled `filename` that could flow to `flask.send_file()` function. This could lead to an attacker reading arbitrary file from the system, leaking private information. Make sure to properly sanitize filename or use `flask.send_from_directory` - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-73: External Control of File Name or Path' - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit - technology: - - flask - patterns: - - pattern-inside: | - @app.route(...) - def $X(filename): - ... - - pattern: flask.send_file(filename, ...) - severity: WARNING - - id: python.flask.security.unsanitized-input.response-contains-unsanitized-input - languages: - - python - message: Flask response reflects unsanitized user input. This could lead to a cross-site scripting vulnerability (https://owasp.org/www-community/attacks/xss/) in which an attacker causes arbitrary code to be executed in the user's browser. To prevent, please sanitize the user input, e.g. by rendering the response in a Jinja2 template (see considerations in https://flask.palletsprojects.com/en/1.0.x/security/). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://flask.palletsprojects.com/en/1.0.x/security/ - - https://owasp.org/www-community/attacks/xss/ - subcategory: - - audit - technology: - - flask - pattern-either: - - pattern: | - $X = flask.request.args.get(...) - ... - flask.make_response("...".format($X)) - - pattern: | - $X = flask.request.args.get(...) - ... - flask.make_response(f"...{$X}...") - - pattern: | - $X = flask.request.args.get(...) - ... - flask.make_response(f"...{$X}") - - pattern: | - $X = flask.request.args.get(...) - ... - flask.make_response(f"{$X}...") - severity: WARNING - - id: python.flask.security.xss.audit.direct-use-of-jinja2.direct-use-of-jinja2 - languages: - - python - message: Detected direct use of jinja2. If not done properly, this may bypass HTML escaping which opens up the application to cross-site scripting (XSS) vulnerabilities. Prefer using the Flask method 'render_template()' and templates with a '.html' extension in order to prevent XSS. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://jinja.palletsprojects.com/en/2.11.x/api/#basics - subcategory: - - audit - technology: - - flask - pattern-either: - - pattern: jinja2.Environment(...) - - pattern: jinja2.Template.render(...) - - patterns: - - pattern-inside: | - $TEMPLATE = $ENV.get_template(...) - ... - - pattern: $TEMPLATE.render(...) - - patterns: - - pattern-inside: | - $TEMPLATE = jinja2.Template(...) - ... - - pattern: $TEMPLATE.render(...) - severity: WARNING - - id: python.flask.security.xss.audit.explicit-unescape-with-markup.explicit-unescape-with-markup - languages: - - python - message: Detected explicitly unescaped content using 'Markup()'. This permits the unescaped data to include unescaped HTML which could result in cross-site scripting. Ensure this data is not externally controlled, or consider rewriting to not use 'Markup()'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://tedboy.github.io/flask/generated/generated/flask.Markup.html - subcategory: - - audit - technology: - - flask - pattern-either: - - pattern: flask.Markup.unescape(...) - - pattern: $MARKUPOBJ.unescape() - - patterns: - - pattern-either: - - pattern: flask.Markup($Q) - - pattern: markupsafe.Markup($Q) - - metavariable-pattern: - metavariable: $Q - patterns: - - pattern-not: '"..."' - severity: WARNING - - id: python.flask.security.xss.audit.template-autoescape-off.template-autoescape-off - languages: - - regex - message: Detected a segment of a Flask template where autoescaping is explicitly disabled with '{% autoescape off %}'. This allows rendering of raw HTML in this segment. Ensure no user data is rendered here, otherwise this is a cross-site scripting (XSS) vulnerability, or turn autoescape on. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://flask.palletsprojects.com/en/1.1.x/templating/#controlling-autoescaping - - https://flask.palletsprojects.com/en/1.1.x/templating/#jinja-setup - subcategory: - - audit - technology: - - flask - paths: - include: - - '*.html' - pattern-regex: '{%\s*autoescape\s+false\s*%}' - severity: WARNING - - id: python.flask.security.xss.audit.template-href-var.template-href-var - languages: - - generic - message: Detected a template variable used in an anchor tag with the 'href' attribute. This allows a malicious actor to input the 'javascript:' URI and is subject to cross- site scripting (XSS) attacks. Use 'url_for()' to safely generate a URL. You may also consider setting the Content Security Policy (CSP) header. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss - - https://content-security-policy.com/ - subcategory: - - audit - technology: - - flask - paths: - include: - - '*.html' - patterns: - - pattern-inside: - - pattern-either: - - pattern: href = {{ ... }} - - pattern: href = "{{ ... }}" - - pattern: href = '{{ ... }}' - - pattern-not-inside: href = {{ url_for(...) ... }} - - pattern-not-inside: href = "{{ url_for(...) ... }}" - - pattern-not-inside: href = '{{ url_for(...) ... }}' - severity: WARNING - - id: python.flask.security.xss.audit.template-unescaped-with-safe.template-unescaped-with-safe - languages: - - regex - message: Detected a segment of a Flask template where autoescaping is explicitly disabled with '| safe' filter. This allows rendering of raw HTML in this segment. Ensure no user data is rendered here, otherwise this is a cross-site scripting (XSS) vulnerability. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss - subcategory: - - audit - technology: - - flask - paths: - include: - - '*.html' - pattern-regex: '{{.*?\|\s*safe(\s*}})?' - severity: WARNING - - fix: | - ="{{$...VAR}}" - id: python.flask.security.xss.audit.template-unquoted-attribute-var.template-unquoted-attribute-var - languages: - - generic - message: 'Detected a unquoted template variable as an attribute. If unquoted, a malicious actor could inject custom JavaScript handlers. To fix this, add quotes around the template expression, like this: "{{ $...VAR }}".' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss - subcategory: - - audit - technology: - - flask - paths: - include: - - '*.html' - - '*.py' - patterns: - - pattern: ={{$...VAR}} - - pattern-inside: | - <$TAG ... > - - metavariable-pattern: - metavariable: $...VAR - pattern-either: - - pattern: | - request.$VALUE.get(...) - - pattern: | - request.$VALUE['...'] - - patterns: - - pattern: $REQ - - pattern-either: - - pattern-inside: "$REQ = request.$VALUE.get(...)\n... \n" - - pattern-inside: "$REQ = request.$VALUE['...']\n... \n" - severity: WARNING - - fix: | - True - id: python.jinja2.security.audit.autoescape-disabled-false.incorrect-autoescape-disabled - languages: - - python - message: Detected a Jinja2 environment with 'autoescaping' disabled. This is dangerous if you are rendering to a browser because this allows for cross-site scripting (XSS) attacks. If you are in a web context, enable 'autoescaping' by setting 'autoescape=True.' You may also consider using 'jinja2.select_autoescape()' to only enable automatic escaping for certain file extensions. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-116: Improper Encoding or Escaping of Output' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://jinja.palletsprojects.com/en/2.11.x/api/#basics - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html - subcategory: - - vuln - technology: - - jinja2 - patterns: - - pattern: jinja2.Environment(... , autoescape=$VAL, ...) - - pattern-not: jinja2.Environment(... , autoescape=True, ...) - - pattern-not: jinja2.Environment(... , autoescape=jinja2.select_autoescape(...), ...) - - focus-metavariable: $VAL - severity: WARNING - - fix-regex: - regex: (.*)\) - replacement: \1, autoescape=True) - id: python.jinja2.security.audit.missing-autoescape-disabled.missing-autoescape-disabled - languages: - - python - message: Detected a Jinja2 environment without autoescaping. Jinja2 does not autoescape by default. This is dangerous if you are rendering to a browser because this allows for cross-site scripting (XSS) attacks. If you are in a web context, enable autoescaping by setting 'autoescape=True.' You may also consider using 'jinja2.select_autoescape()' to only enable automatic escaping for certain file extensions. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-116: Improper Encoding or Escaping of Output' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://jinja.palletsprojects.com/en/2.11.x/api/#basics - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html - subcategory: - - vuln - technology: - - jinja2 - patterns: - - pattern-not: jinja2.Environment(..., autoescape=$VAL, ...) - - pattern: jinja2.Environment(...) - severity: WARNING - - id: python.jwt.security.audit.jwt-exposed-data.jwt-python-exposed-data - languages: - - python - message: The object is passed strictly to jwt.encode(...) Make sure that sensitive information is not exposed through JWT token payload. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - patterns: - - pattern-inside: | - def $FUNC(...,$INPUT,...): - ... - - pattern: jwt.encode($INPUT,...) - severity: WARNING - - id: python.jwt.security.jwt-exposed-credentials.jwt-python-exposed-credentials - languages: - - python - message: Password is exposed through JWT token payload. This is not encrypted and the password could be compromised. Do not store passwords in JWT tokens. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://cwe.mitre.org/data/definitions/522.html - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - pattern-either: - - pattern: | - jwt.encode({...,"password":$P,...},...) - - pattern: | - $PAYLOAD = {...,"password":$P,...} - ... - jwt.encode($PAYLOAD,...) - severity: ERROR - - id: python.jwt.security.jwt-hardcode.jwt-python-hardcoded-secret - languages: - - python - message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - vuln - technology: - - jwt - patterns: - - pattern: | - jwt.encode($X, $SECRET, ...) - - focus-metavariable: $SECRET - - pattern: | - "..." - severity: ERROR - - id: python.jwt.security.jwt-none-alg.jwt-python-none-alg - languages: - - python - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - vuln - technology: - - jwt - pattern-either: - - pattern: | - jwt.encode(...,algorithm="none",...) - - pattern: jwt.decode(...,algorithms=[...,"none",...],...) - severity: ERROR - - fix: | - True - id: python.jwt.security.unverified-jwt-decode.unverified-jwt-decode - languages: - - python - message: Detected JWT token decoded with 'verify=False'. This bypasses any integrity checks for the token which means the token could be tampered with by malicious actors. Ensure that the JWT token is verified. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-287: Improper Authentication' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A02:2017 - Broken Authentication - - A07:2021 - Identification and Authentication Failures - references: - - https://github.com/we45/Vulnerable-Flask-App/blob/752ee16087c0bfb79073f68802d907569a1f0df7/app/app.py#L96 - subcategory: - - audit - technology: - - jwt - patterns: - - pattern-either: - - patterns: - - pattern: | - jwt.decode(..., options={..., "verify_signature": $BOOL, ...}, ...) - - metavariable-pattern: - metavariable: $BOOL - pattern: | - False - - focus-metavariable: $BOOL - - patterns: - - pattern: | - $OPTS = {..., "verify_signature": $BOOL, ...} - ... - jwt.decode(..., options=$OPTS, ...) - - metavariable-pattern: - metavariable: $BOOL - pattern: | - False - - focus-metavariable: $BOOL - severity: ERROR - - id: python.lang.best-practice.hardcoded-tmp-path.hardcoded-tmp-path - languages: - - python - message: Detected hardcoded temp directory. Consider using 'tempfile.TemporaryFile' instead. - metadata: - category: best-practice - references: - - https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryFile - technology: - - python - pattern: open("=~/^\/tmp.*/", ...) - severity: WARNING - - id: python.lang.best-practice.logging-error-without-handling.logging-error-without-handling - languages: - - python - message: Errors should only be logged when handled. The code logs the error and propogates the exception, consider reducing the level to warning or info. - metadata: - category: best-practice - technology: - - python - patterns: - - pattern-inside: | - try: - ... - except ...: - ... - ... - - pattern-either: - - pattern: | - logger.$FUNC(...) - ... - raise - - pattern: | - logger.$FUNC(...) - ... - raise $EX - - pattern: | - logger.$FUNC(...) - ... - raise $EX from $EX2 - - metavariable-regex: - metavariable: $FUNC - regex: (error|exception) - severity: WARNING - - id: python.lang.best-practice.manual-collections-create.manual-defaultdict-dict-create - languages: - - python - message: manually creating a defaultdict - use collections.defaultdict(dict) - metadata: - category: best-practice - technology: - - python - pattern-either: - - pattern: | - $DICT = {} - ... - for $KEY, $VALUE in $OTHERDICT.items(): - ... - if $KEY not in $DICT: - ... - $DICT[$KEY] = {} - ... - $DICT[$KEY].update(...) - - pattern: | - $DICT = {} - ... - for $KEY, $VALUE in $OTHERDICT.items(): - ... - $DICT.setdefault($KEY, {}).update(...) - severity: WARNING - - id: python.lang.best-practice.manual-collections-create.manual-defaultdict-set-create - languages: - - python - message: manually creating a defaultdict - use collections.defaultdict(set) - metadata: - category: best-practice - technology: - - python - pattern-either: - - pattern: | - $DICT = {} - ... - for $KEY, $VALUE in $OTHERDICT.items(): - ... - if $KEY not in $DICT: - ... - $DICT[$KEY] = set() - ... - $DICT[$KEY].add(...) - - pattern: | - $DICT = {} - ... - for $KEY, $VALUE in $OTHERDICT.items(): - ... - $DICT.setdefault($KEY, set()).add(...) - severity: WARNING - - id: python.lang.best-practice.manual-collections-create.manual-defaultdict-list-create - languages: - - python - message: manually creating a defaultdict - use collections.defaultdict(list) - metadata: - category: best-practice - technology: - - python - pattern-either: - - pattern: | - $DICT = {} - ... - for $KEY, $VALUE in $OTHERDICT.items(): - ... - if $KEY not in $DICT: - ... - $DICT[$KEY] = [] - ... - $DICT[$KEY].append(...) - - pattern: | - $DICT = {} - ... - for $KEY, $VALUE in $OTHERDICT.items(): - ... - $DICT.setdefault($KEY, []).append(...) - severity: WARNING - - id: python.lang.best-practice.manual-collections-create.manual-counter-create - languages: - - python - message: manually creating a counter - use collections.Counter - metadata: - category: best-practice - technology: - - python - pattern: | - $DICT = {} - ... - for $KEY, $VALUE in $OTHERDICT.items(): - ... - if $KEY not in $DICT: - ... - $DICT[$KEY] = 0 - ... - $DICT[$KEY] += 1 - severity: WARNING - - id: python.lang.best-practice.missing-hash-with-eq.missing-hash-with-eq - languages: - - python - message: 'Class `$A` has defined `__eq__` which means it should also have defined `__hash__`; ' - metadata: - category: best-practice - technology: - - python - patterns: - - pattern-not-inside: | - class A(...): - ... - def __hash__(self): - ... - ... - def __eq__(self, $O): - ... - - pattern: | - class A(...): - ... - def __eq__(self, $O): ... - ... - severity: WARNING - - id: python.lang.best-practice.open-never-closed.open-never-closed - languages: - - python - message: file object opened without corresponding close - metadata: - category: best-practice - technology: - - python - patterns: - - pattern-not-inside: | - $F = open(...) - ... - $F.close() - - pattern-not-inside: | - $F = io.open(...) - ... - $F.close() - - pattern-not-inside: | - $F = tarfile.open(...) - ... - $F.close() - - pattern-not-inside: | - $F = ZipFile.open(...) - ... - $F.close() - - pattern-not-inside: | - $F = tempfile.TemporaryFile(...) - ... - $F.close() - - pattern-not-inside: | - $F = tempfile.NamedTemporaryFile(...) - ... - $F.close() - - pattern-not-inside: | - $F = tempfile.SpooledTemporaryFile(...) - ... - $F.close() - - pattern-not-inside: | - $F = open(...) - ... - try: - ... - finally: - $F.close() - - pattern-not-inside: | - $F = io.open(...) - ... - try: - ... - finally: - $F.close() - - pattern-not-inside: | - $F = tarfile.open(...) - ... - try: - ... - finally: - $F.close() - - pattern-not-inside: | - $F = ZipFile.open(...) - ... - try: - ... - finally: - $F.close() - - pattern-not-inside: | - $F = tempfile.TemporaryFile(...) - ... - try: - ... - finally: - $F.close() - - pattern-not-inside: | - $F = tempfile.NamedTemporaryFile(...) - ... - try: - ... - finally: - $F.close() - - pattern-not-inside: | - $F = tempfile.SpooledTemporaryFile(...) - ... - try: - ... - finally: - $F.close() - - pattern-either: - - pattern: $F = open(...) - - pattern: $F = io.open(...) - - pattern: $F = tarfile.open(...) - - pattern: $F = ZipFile.open(...) - - pattern: $F = tempfile.TemporaryFile(...) - - pattern: $F = tempfile.NamedTemporaryFile(...) - - pattern: $F = tempfile.SpooledTemporaryFile(...) - severity: ERROR - - id: python.lang.best-practice.pass-body.pass-body-fn - languages: - - python - message: '`pass` is the body of function $X. Consider removing this or raise NotImplementedError() if this is a TODO' - metadata: - category: best-practice - technology: - - python - patterns: - - pattern-not-inside: | - def __init__(self, ...): - ... - - pattern-not-inside: | - class $A: - ... - - pattern: | - def $X(...): - pass - severity: WARNING - - id: python.lang.best-practice.pass-body.pass-body-range - languages: - - python - message: '`pass` is the body of for $X in $Y. Consider removing this or raise NotImplementedError() if this is a TODO' - metadata: - category: best-practice - technology: - - python - pattern: | - for $X in $Y: - pass - severity: WARNING - - id: python.lang.best-practice.pdb.python-debugger-found - languages: - - python - message: Importing the python debugger; did you mean to leave this in? - metadata: - category: best-practice - technology: - - python - pattern-either: - - pattern: import pdb - - pattern: pdb.set_trace() - severity: WARNING - - id: python.lang.best-practice.sleep.arbitrary-sleep - languages: - - python - message: time.sleep() call; did you mean to leave this in? - metadata: - category: best-practice - technology: - - python - patterns: - - pattern-not: time.sleep($F(...)) - - pattern-either: - - pattern: | - time.sleep($X: int) - - pattern: | - time.sleep($X: float) - severity: ERROR - - id: python.lang.best-practice.unspecified-open-encoding.unspecified-open-encoding - languages: - - python - message: Missing 'encoding' parameter. 'open()' uses device locale encodings by default, corrupting files with special characters. Specify the encoding to ensure cross-platform support when opening files in text mode (e.g. encoding="utf-8"). - metadata: - category: best-practice - references: - - https://www.python.org/dev/peps/pep-0597/ - - https://docs.python.org/3/library/functions.html#open - technology: - - python - patterns: - - pattern-inside: open(...) - - pattern-not: open(..., encoding="...", ...) - - pattern-not: open($F, "...", $B, "...", ...) - - pattern-either: - - pattern: open($FILE) - - patterns: - - pattern: open($FILE, ...) - - pattern-not: open($FILE, $M, ...) - - pattern-not-regex: open\(.*(?:encoding|mode)=.*\) - - patterns: - - pattern: open($FILE, $MODE, ...) - - metavariable-regex: - metavariable: $MODE - regex: (?!.*b.*) - - patterns: - - pattern: open($FILE, ..., mode=$MODE, ...) - - metavariable-regex: - metavariable: $MODE - regex: (?!.*b.*) - severity: WARNING - - id: python.lang.compatibility.python36.python36-compatibility-ssl - languages: - - python - message: this function is only available on Python 3.6+ - metadata: - category: compatibility - technology: - - python - pattern: ssl.get_ciphers() - severity: ERROR - - id: python.lang.compatibility.python36.python36-compatibility-popen1 - languages: - - python - message: the `errors` argument to Popen is only available on Python 3.6+ - metadata: - category: compatibility - technology: - - python - pattern: subprocess.Popen(errors=$X, ...) - severity: ERROR - - id: python.lang.compatibility.python36.python36-compatibility-popen2 - languages: - - python - message: the `encoding` argument to Popen is only available on Python 3.6+ - metadata: - category: compatibility - technology: - - python - pattern: subprocess.Popen(encoding=$X, ...) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-importlib - languages: - - python - message: source_hash' is only available on Python 3.7+. This does not work in lower versions, and therefore is not backwards compatible. Instead, use another hash function. - metadata: - category: compatibility - technology: - - python - pattern: importlib.source_hash() - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-importlib2 - languages: - - python - message: Found 'importlib.resources', which is a module only available on Python 3.7+. This does not work in lower versions, and therefore is not backwards compatible. Use importlib_resources instead for older Python versions. - metadata: - category: compatibility - technology: - - python - pattern: import importlib.resources - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-httpconn - languages: - - python - message: Found usage of the 'blocksize' argument in a HTTPConnection call. This is only available on Python 3.7+ and is therefore not backwards compatible. Remove this in order for this code to work in Python 3.6 and below. - metadata: - category: compatibility - technology: - - python - pattern: http.client.HTTPConnection(blocksize=$X,...) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-httpsconn - languages: - - python - message: Found usage of the 'blocksize' argument in a HTTPSConnection call. This is only available on Python 3.7+ and is therefore not backwards compatible. Remove this in order for this code to work in Python 3.6 and below. - metadata: - category: compatibility - technology: - - python - pattern: http.client.HTTPSConnection(blocksize=$X,...) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-importlib3 - languages: - - python - message: Found usage of 'importlib.abc.ResourceReader'. This module is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use another loader. - metadata: - category: compatibility - technology: - - python - pattern: import importlib.abc.ResourceReader - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-textiowrapper - languages: - - python - message: Found usage of 'importlib.abc.ResourceReader'. This module is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use another loader. - metadata: - category: compatibility - technology: - - python - pattern: TextIOWrapper.reconfigure(...) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-ipv6network1 - languages: - - python - message: IPv6Network.subnet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the subnet is in 'subnets'. - metadata: - category: compatibility - technology: - - python - pattern: ipaddress.IPv6Network.subnet_of($X) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-ipv6network2 - languages: - - python - message: IPv6Network.supernet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the supernet is in 'supernet'. - metadata: - category: compatibility - technology: - - python - pattern: ipaddress.IPv6Network.supernet_of($X) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-ipv4network1 - languages: - - python - message: IPv4Network.subnet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the subnet is in 'subnets'. - metadata: - category: compatibility - technology: - - python - pattern: ipaddress.IPv4Network.subnet_of($X) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-ipv4network2 - languages: - - python - message: IPv4Network.supernet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the supernet is in 'supernet'. - metadata: - category: compatibility - technology: - - python - pattern: ipaddress.IPv4Network.supernet_of($X) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-locale1 - languages: - - python - message: Found usage of the 'monetary' argument in a function call of 'locale.format_string'. This is only available on Python 3.7+ and is therefore not backwards compatible. Instead, remove the 'monetary' argument. - metadata: - category: compatibility - technology: - - python - pattern: locale.format_string(monetary=$X, ...) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-math1 - languages: - - python - message: math.remainder is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use math.fmod() or calculate $X - n* $Y. - metadata: - category: compatibility - technology: - - python - pattern: math.remainder($X, $Y) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-multiprocess1 - languages: - - python - message: multiprocessing.Process.close() is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use join(). - metadata: - category: compatibility - technology: - - python - pattern: multiprocessing.Process.close() - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-multiprocess2 - languages: - - python - message: multiprocessing.Process.kill() is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use terminate(). - metadata: - category: compatibility - technology: - - python - pattern: multiprocessing.Process.kill() - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-os1 - languages: - - python - message: os.preadv() is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use a combination of os.readv() and os.pread(). - metadata: - category: compatibility - technology: - - python - pattern: os.preadv(...) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-os2-ok2 - languages: - - python - message: os.pwritev() is only available on Python 3.3+ and is therefore not backwards compatible. Instead, use a combination of pwrite() and writev(). - metadata: - category: compatibility - technology: - - python - patterns: - - pattern-not-inside: | - if hasattr(os, 'pwritev'): - ... - - pattern: os.pwritev(...) - severity: ERROR - - id: python.lang.compatibility.python37.python37-compatibility-pdb - languages: - - python - message: pdb.set_trace() with the header argument is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use set_trace() without the header argument. - metadata: - category: compatibility - technology: - - python - pattern: pdb.set_trace(header=$X, ...) - severity: ERROR - - id: python.lang.correctness.baseclass-attribute-override.baseclass-attribute-override - languages: - - python - message: Class $C inherits from both `$A` and `$B` which both have a method named `$F`; one of these methods will be overwritten. - metadata: - category: correctness - references: - - https://docs.python.org/3/tutorial/classes.html#multiple-inheritance - technology: - - python - patterns: - - pattern-inside: | - class $A(...): - ... - def $F(...): - ... - ... - ... - - pattern-inside: | - class $B(...): - ... - def $F(...): - ... - ... - ... - - pattern: | - class $C(..., $A, ..., $B, ...): - ... - - focus-metavariable: $C - severity: WARNING - - id: python.lang.correctness.cannot-cache-generators.cannot-cache-generators - languages: - - python - message: Generators can only be consumed once, so in most cases, caching them will cause an error when the already-consumed generator is retrieved from cache. - metadata: - category: correctness - technology: - - python - patterns: - - pattern-inside: | - @functools.lru_cache(...) - def $FUNC(...): - ... - yield ... - - pattern: functools.lru_cache(...) - severity: WARNING - - id: python.lang.correctness.common-mistakes.default-mutable-dict.default-mutable-dict - languages: - - python - message: 'Function $F mutates default dict $D. Python only instantiates default function arguments once and shares the instance across the function calls. If the default function argument is mutated, that will modify the instance used by all future function calls. This can cause unexpected results, or lead to security vulnerabilities whereby one function consumer can view or modify the data of another function consumer. Instead, use a default argument (like None) to indicate that no argument was provided and instantiate a new dictionary at that time. For example: `if $D is None: $D = {}`.' - metadata: - category: correctness - references: - - https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments - technology: - - python - options: - symbolic_propagation: true - patterns: - - pattern-not-inside: | - def $A(...): - ... - def $F(..., $D={}, ...): - ... - - pattern-inside: | - def $F(..., $D={}, ...): - ... - - pattern-not-inside: | - $D = {} - ... - - pattern-not-inside: | - $D = dict(...) - ... - - pattern-not-inside: | - $D = $D.copy() - ... - - pattern-not-inside: | - $D = copy.deepcopy($D) - ... - - pattern-not-inside: | - $D = copy.copy($D) - ... - - pattern-not-inside: | - $D = dict.copy($D) - ... - - pattern-not-inside: | - $D = {... for ... in ...} - ... - - pattern-not-inside: | - $D = $D or {} - ... - - pattern-either: - - pattern: | - $D[...] = ... - - pattern: | - $D.update(...) - - pattern: | - $D.setdefault(...) - severity: ERROR - - id: python.lang.correctness.common-mistakes.default-mutable-list.default-mutable-list - languages: - - python - message: 'Function $F mutates default list $D. Python only instantiates default function arguments once and shares the instance across the function calls. If the default function argument is mutated, that will modify the instance used by all future function calls. This can cause unexpected results, or lead to security vulnerabilities whereby one function consumer can view or modify the data of another function consumer. Instead, use a default argument (like None) to indicate that no argument was provided and instantiate a new list at that time. For example: `if $D is None: $D = []`.' - metadata: - category: correctness - references: - - https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments - technology: - - python - options: - symbolic_propagation: true - patterns: - - pattern-not-inside: | - def $A(...): - ... - def $F(..., $D=[], ...): - ... - - pattern-inside: | - def $F(..., $D=[], ...): - ... - - pattern-not-inside: | - $D = [] - ... - - pattern-not-inside: | - $D = [...] - ... - - pattern-not-inside: | - $D = list(...) - ... - - pattern-not-inside: | - $D = copy.deepcopy($D) - ... - - pattern-not-inside: | - $D = copy.copy($D) - ... - - pattern-not-inside: | - $D = list.copy($D) - ... - - pattern-not-inside: | - $D = $D[:] - ... - - pattern-not-inside: | - $D = [... for ... in ...] - ... - - pattern-not-inside: | - $D = $D or [] - ... - - pattern-either: - - pattern: | - $D.append(...) - - pattern: | - $D.extend(...) - - pattern: | - $D.insert(...) - severity: ERROR - - id: python.lang.correctness.common-mistakes.is-comparison-string.identical-is-comparison - languages: - - python - message: Found identical comparison using is. Ensure this is what you intended. - metadata: - category: correctness - technology: - - python - pattern: $S is $S - severity: ERROR - - id: python.lang.correctness.common-mistakes.is-comparison-string.string-is-comparison - languages: - - python - message: Found string comparison using 'is' operator. The 'is' operator is for reference equality, not value equality, and therefore should not be used to compare strings. For more information, see https://github.com/satwikkansal/wtfpython#-how-not-to-use-is-operator" - metadata: - category: correctness - technology: - - python - patterns: - - pattern-not: $S is None - - pattern-not: type($X) is $T - - pattern-not: $S is True - - pattern-not: $S is False - - pattern-not: $S is "" - - pattern-either: - - pattern: $S is "..." - - pattern: '"..." is $S' - severity: ERROR - - id: python.lang.correctness.common-mistakes.is-not-is-not.is-not-is-not - languages: - - python - message: In Python 'X is not ...' is different from 'X is (not ...)'. In the latter the 'not' converts the '...' directly to boolean. - metadata: - category: correctness - technology: - - python - pattern: $S is (not ...) - severity: ERROR - - id: python.lang.correctness.common-mistakes.string-concat-in-list.string-concat-in-list - languages: - - python - message: Detected strings that are implicitly concatenated inside a list. Python will implicitly concatenate strings when not explicitly delimited. Was this supposed to be individual elements of the list? - metadata: - category: correctness - technology: - - python - patterns: - - pattern-either: - - pattern-inside: '[...]' - - pattern-inside: '{...}' - - pattern: '"..." "..."' - - pattern-not-inside: f"..." - - pattern-not-inside: '{..., $KEY: $VALUE, ...}' - severity: WARNING - - id: python.lang.correctness.concurrent.uncaught-executor-exceptions - languages: - - python - message: 'Values returned by thread pool map must be read in order to raise exceptions. Consider using `for _ in $EXECUTOR.map(...): pass`.' - metadata: - category: correctness - references: - - https://superfastpython.com/threadpoolexecutor-exception-handling/ - technology: - - python - patterns: - - pattern-inside: | - with concurrent.futures.thread.ThreadPoolExecutor(...) as $EXECUTOR: - ... - - pattern-not-inside: | - $VAR = $EXECUTOR.map(...) - ... - for ... in $VAR: - ... - - pattern-not-inside: | - $VAR = $EXECUTOR.map(...) - ... - [... for ... in $VAR] - - pattern-not-inside: | - [... for ... in $EXECUTOR.map(...)] - - pattern-not-inside: | - for $IT in $EXECUTOR.map(...): - ... - - pattern: $EXECUTOR.map(...) - severity: WARNING - - id: python.lang.correctness.dict-modify-iterating.dict-del-while-iterate - languages: - - python - message: 'It appears that `$DICT[$KEY]` is a dict with items being deleted while in a for loop. This is usually a bad idea and will likely lead to a RuntimeError: dictionary changed size during iteration' - metadata: - category: correctness - references: - - https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects - technology: - - python - pattern-either: - - pattern: | - for $KEY, $VALUE in $DICT.items(): - ... - del $DICT[$KEY] - - pattern: | - for $KEY in $DICT.keys(): - ... - del $DICT[$KEY] - severity: WARNING - - id: python.lang.correctness.exceptions.exceptions.raise-not-base-exception - languages: - - python - message: In Python3, a runtime `TypeError` will be thrown if you attempt to raise an object or class which does not inherit from `BaseException` - metadata: - category: correctness - technology: - - python - pattern-either: - - pattern: raise "..." - - pattern: | - $X: BaseException - raise $X(...) - - patterns: - - pattern: raise $EXCEPTION - - metavariable-regex: - metavariable: $EXCEPTION - regex: '[0-9]*\.?[0-9]+' - severity: ERROR - - fix: sys.exit($X) - id: python.lang.correctness.exit.use-sys-exit - languages: - - python - message: Detected use of `exit`. Use `sys.exit` over the python shell `exit` built-in. `exit` is a helper for the interactive shell and may not be available on all Python implementations. - metadata: - category: correctness - references: - - https://stackoverflow.com/questions/6501121/difference-between-exit-and-sys-exit-in-python - technology: - - python - patterns: - - pattern: exit($X) - - pattern-not: sys.exit($X) - severity: WARNING - - id: python.lang.correctness.file-object-redefined-before-close.file-object-redefined-before-close - languages: - - python - message: Detected a file object that is redefined and never closed. This could leak file descriptors and unnecessarily consume system resources. - metadata: - category: correctness - technology: - - python - patterns: - - pattern: | - $F = open($X, ...) - ... - $F = open($Y, ...) - - pattern-not: | - $F = open($X, ...) - ... - $F.close() - ... - $F = open($Y, ...) - severity: WARNING - - id: python.lang.correctness.list-modify-iterating.list-modify-while-iterate - languages: - - python - message: It appears that `$LIST` is a list that is being modified while in a for loop. This will likely cause a runtime error or an infinite loop. - metadata: - category: correctness - references: - - https://unspecified.wordpress.com/2009/02/12/thou-shalt-not-modify-a-list-during-iteration/ - technology: - - python - pattern-either: - - pattern: | - for $ELEMENT in $LIST: - ... - $LIST.pop(...) - - pattern: | - for $ELEMENT in $LIST: - ... - $LIST.push(...) - - pattern: | - for $ELEMENT in $LIST: - ... - $LIST.append(...) - - pattern: | - for $ELEMENT in $LIST: - ... - $LIST.extend(...) - - pattern: | - for $ELEMENT in $LIST: - ... - $LIST.remove(...) - severity: ERROR - - id: python.lang.correctness.pdb.pdb-remove - languages: - - python - message: pdb is an interactive debugging tool and you may have forgotten to remove it before committing your code - metadata: - category: correctness - technology: - - python - pattern-either: - - pattern: pdb.$X(...) - - pattern: pdb.Pdb.$X(...) - severity: WARNING - - id: python.lang.correctness.pytest-assert_match-after-path-patch.pytest-assert_match-after-path-patch - languages: - - python - message: snapshot.assert_match makes use of pathlib to create files. Patching $METHOD may result in unexpected snapshot behavior - metadata: - category: correctness - references: - - https://github.com/returntocorp/semgrep/pull/5459 - - https://pypi.org/project/pytest-snapshot/ - technology: - - python - patterns: - - pattern-inside: | - import pytest - ... - - pattern-either: - - pattern-inside: | - mocker.patch("pathlib.Path", $MOCKED_VALUE) - ... - - pattern-inside: | - mocker.patch.object(pathlib.Path, $METHOD, $MOCKED_VALUE) - ... - - pattern: snapshot.assert_match(...) - severity: WARNING - - id: python.lang.correctness.return-in-init.return-in-init - languages: - - python - message: '`return` should never appear inside a class __init__ function. This will cause a runtime error.' - metadata: - category: correctness - technology: - - python - patterns: - - pattern-inside: | - class $A(...): - ... - - pattern-inside: | - def __init__(...): - ... - - pattern-not-inside: | - def __init__(...): - ... - def $F(...): - ... - - patterns: - - pattern: return ... - - pattern-not: return - - pattern-not: return None - severity: ERROR - - id: python.lang.correctness.return-in-init.yield-in-init - languages: - - python - message: '`yield` should never appear inside a class __init__ function. This will cause a runtime error.' - metadata: - category: correctness - technology: - - python - patterns: - - pattern-inside: | - class $A(...): - ... - - pattern-inside: | - def __init__(...): - ... - - pattern-not-inside: | - def __init__(...): - ... - def $F(...): - ... - - pattern-either: - - pattern: yield ... - - pattern: yield - severity: ERROR - - id: python.lang.correctness.sync-sleep-in-async-code.sync-sleep-in-async-code - languages: - - python - message: Synchronous time.sleep in async code will block the event loop and not allow other tasks to execute. Use asyncio.sleep() instead. - metadata: - category: best-practice - technology: - - python - patterns: - - pattern: time.sleep(...) - - pattern-inside: | - async def $F(...): - ... - - pattern-not-inside: | - async def $F(...): - def $INNER(...): - ... - severity: WARNING - - id: python.lang.correctness.tempfile.flush.tempfile-without-flush - languages: - - python - message: Using '$F.name' without '.flush()' or '.close()' may cause an error because the file may not exist when '$F.name' is used. Use '.flush()' or close the file before using '$F.name'. - metadata: - category: correctness - technology: - - python - pattern-either: - - patterns: - - pattern-not-inside: | - $F = tempfile.NamedTemporaryFile(...) - ... - $F.write(...) - ... - $F.flush() - ... - $F.name - - pattern-not-inside: | - $F = tempfile.NamedTemporaryFile(...) - ... - $F.write(...) - ... - $F.close() - ... - $F.name - - pattern-not-inside: | - $F = tempfile.NamedTemporaryFile(..., delete=False, ...) - ... - $F.close() - ... - $F.name - - pattern-inside: | - $F = tempfile.NamedTemporaryFile(...) - ... - - pattern: | - $F.name - - patterns: - - pattern-not-inside: | - with tempfile.NamedTemporaryFile(...) as $F: - ... - $F.write(...) - ... - $F.flush() - ... - $F.name - - pattern-not-inside: | - with tempfile.NamedTemporaryFile(...) as $F: - ... - $F.write(...) - ... - $F.close() - ... - $F.name - - pattern-not-inside: | - with tempfile.NamedTemporaryFile(...) as $F: - ... - $MODULE.dump(..., $F, ...) - ... - $F.flush() - ... - $F.name - - pattern-not-inside: | - with tempfile.NamedTemporaryFile(...) as $F: - ... - $MODULE.dump(..., $F, ...) - ... - $F.close() - ... - $F.name - - pattern-inside: | - with tempfile.NamedTemporaryFile(...) as $F: - ... - - pattern: | - $F.name - severity: ERROR - - id: python.lang.correctness.tempfile.mktemp.tempfile-insecure - languages: - - python - message: 'Use tempfile.NamedTemporaryFile instead. From the official Python documentation: THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED. The file name may refer to a file that did not exist at some point, but by the time you get around to creating it, someone else may have beaten you to the punch.' - metadata: - category: correctness - technology: - - python - pattern: tempfile.mktemp(...) - severity: ERROR - - id: python.lang.correctness.test-is-missing-assert.test-is-missing-assert - languages: - - python - message: Comparison without assertion. The result of this comparison is not used. Perhaps this expression is missing an `assert` keyword. - metadata: - category: correctness - technology: - - python - paths: - include: - - test*.py - patterns: - - pattern: $A == $B - - pattern-not-inside: assert ... - - pattern-not-inside: $X = ... - - pattern-not-inside: $X += ... - - pattern-not-inside: $X |= ... - - pattern-not-inside: $X &= ... - - pattern-not-inside: yield $X - - pattern-not-inside: $X and $Y - - pattern-not-inside: $X or $Y - - pattern-not-inside: return ... - - pattern-not-inside: $FUNC(...) - - pattern-not-inside: | - while $EXPR: - ... - - pattern-not-inside: | - with (...): - ... - - pattern-not-inside: | - [...] - - pattern-not-inside: | - $EXPR[...] - - pattern-not-inside: | - if ...: - ... - severity: WARNING - - fix: check_call - id: python.lang.correctness.unchecked-returns.unchecked-subprocess-call - languages: - - python - message: This is not checking the return value of this subprocess call; if it fails no exception will be raised. Consider subprocess.check_call() instead - metadata: - category: correctness - references: - - https://docs.python.org/3/library/subprocess.html#subprocess.check_call - technology: - - python - patterns: - - pattern: subprocess.$CALL(...) - - pattern-not-inside: $S = subprocess.call(...) - - pattern-not-inside: subprocess.call(...) == $X - - pattern-not-inside: return subprocess.call(...) - - metavariable-pattern: - metavariable: $CALL - pattern: call - - focus-metavariable: $CALL - severity: WARNING - - id: python.lang.correctness.useless-comparison.no-strings-as-booleans - languages: - - python - message: Using strings as booleans in Python has unexpected results. `"one" and "two"` will return "two". `"one" or "two"` will return "one". In Python, strings are truthy, and strings with a non-zero length evaluate to True. - metadata: - category: correctness - technology: - - python - pattern-either: - - pattern: | - if <... "..." and ... ...>: - ... - - pattern: | - if <... "..." or ... ...>: - ... - - patterns: - - pattern-not: | - if $X in "...": - ... - - pattern: | - if "...": - ... - severity: ERROR - - id: python.lang.correctness.useless-eqeq.useless-eqeq - languages: - - python - message: 'This expression is always True: `$X == $X` or `$X != $X`. If testing for floating point NaN, use `math.isnan($X)`, or `cmath.isnan($X)` if the number is complex.' - metadata: - category: correctness - technology: - - python - patterns: - - pattern-not-inside: | - def __eq__(...): - ... - - pattern-not-inside: | - def __cmp__(...): - ... - - pattern-not-inside: assert(...) - - pattern-not-inside: assert ..., ... - - pattern-not-inside: assertTrue(...) - - pattern-not-inside: assertFalse(...) - - pattern-either: - - pattern: $X == $X - - pattern: $X != $X - - pattern-not: 1 == 1 - severity: INFO - - id: python.lang.correctness.writing-to-file-in-read-mode.writing-to-file-in-read-mode - languages: - - python - message: The file object '$FD' was opened in read mode, but is being written to. This will cause a runtime error. - metadata: - category: correctness - technology: - - python - patterns: - - pattern-either: - - pattern-inside: | - $FD = open($NAME, "r", ...) - ... - - pattern-inside: | - $FD = open($NAME, "rb", ...) - ... - - pattern-inside: | - with open($NAME, "r", ...) as $FD: - ... - - pattern-inside: | - with open($NAME, "rb", ...) as $FD: - ... - - pattern: $FD.write(...) - severity: ERROR - - id: python.lang.maintainability.improper-list-concat.improper-list-concat - languages: - - python - message: 'This expression will evaluate to be ONLY value the of the `else` clause if the condition `$EXPRESSION` is false. If you meant to do list concatenation, put parentheses around the entire concatenation expression, like this: `[''a'', ''b'', ''c''] + ([''d''] if x else [''e''])`. If this is the intended behavior, the expression may be confusing to others, and you may wish to add parentheses for readability.' - metadata: - category: maintainability - technology: - - python - pattern: '[...] + [...] if $EXPRESSION else [...]' - severity: INFO - - id: python.lang.maintainability.is-function-without-parentheses.is-function-without-parentheses - languages: - - python - message: Is "$FUNC" a function or an attribute? If it is a function, you may have meant $X.$FUNC() because $X.$FUNC is always true. - metadata: - category: maintainability - technology: - - python - patterns: - - pattern: $X.$FUNC - - pattern-not-inside: $X.$FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: is_.* - severity: WARNING - - id: python.lang.maintainability.return.code-after-unconditional-return - languages: - - python - message: code after return statement will not be executed - metadata: - category: maintainability - technology: - - python - pattern: | - return ... - $S - severity: WARNING - - id: python.lang.maintainability.return.return-not-in-function - languages: - - python - message: '`return` only makes sense inside a function' - metadata: - category: maintainability - technology: - - python - patterns: - - pattern-not-inside: | - def $F(...): - ... - # TODO: first pattern should just automatically include this one - - pattern-not-inside: | - def $F(...) -> $Y: - ... - - pattern: return ... - severity: WARNING - - id: python.lang.maintainability.useless-assign-keyed.useless-assignment-keyed - languages: - - python - message: key `$Y` in `$X` is assigned twice; the first assignment is useless - metadata: - category: maintainability - technology: - - python - pattern-either: - - pattern: | - $X[$Y] = ... - $X[$Y] = ... - - pattern: | - $X[$Y][$Z] = ... - $X[$Y][$Z] = ... - severity: INFO - - id: python.lang.maintainability.useless-ifelse.useless-if-conditional - languages: - - python - message: if block checks for the same condition on both branches (`$X`) - metadata: - category: maintainability - references: - - https://docs.python.org/3/tutorial/controlflow.html - technology: - - python - pattern: | - if $X: - ... - elif $X: - ... - severity: WARNING - - id: python.lang.maintainability.useless-ifelse.useless-if-body - languages: - - python - message: Useless if statement; both blocks have the same body - metadata: - category: maintainability - references: - - https://docs.python.org/3/tutorial/controlflow.html - technology: - - python - pattern: | - if $X: - $S - else: - $S - severity: WARNING - - id: python.lang.maintainability.useless-innerfunction.useless-inner-function - languages: - - python - message: function `$FF` is defined inside a function but never used - metadata: - category: maintainability - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - technology: - - python - patterns: - - pattern-not-inside: | - def $F(...): - ... - def $FF(...): - ... - ... - <... $FF ...> - - pattern-not-inside: | - def $F(...): - ... - class $CLAZZ(...): - ... - - pattern-inside: | - def $F(...): - ... - def $FF(...): - ... - ... - - pattern: | - def $FF(...): - ... - - pattern-not: | - @$DECORATOR - def $FF(...): - ... - severity: ERROR - - id: python.lang.maintainability.useless-literal-set.useless-literal-set - languages: - - python - message: '`$X` is uselessly assigned twice inside the creation of the set' - metadata: - category: maintainability - references: - - https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset - technology: - - python - patterns: - - pattern: | - set(..., ($X, $A), ..., ($X, $B), ...) - - focus-metavariable: $X - severity: ERROR - - id: python.lang.maintainability.useless-literal.useless-literal - languages: - - python - message: key `$X` is uselessly assigned twice - metadata: - category: maintainability - references: - - https://docs.python.org/3/library/stdtypes.html#mapping-types-dict - technology: - - python - patterns: - - pattern-either: - - pattern: | - {..., $X: $A, ..., $X: $B, ...} - - pattern: | - dict(..., ($X, $A), ..., ($X, $B), ...) - - focus-metavariable: $X - severity: WARNING - - id: python.lang.security.audit.conn_recv.multiprocessing-recv - languages: - - python - message: 'The Connection.recv() method automatically unpickles the data it receives, which can be a security risk unless you can trust the process which sent the message. Therefore, unless the connection object was produced using Pipe() you should only use the recv() and send() methods after performing some sort of authentication. See more dettails: https://docs.python.org/3/library/multiprocessing.html?highlight=security#multiprocessing.connection.Connection' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.python.org/3/library/multiprocessing.html?highlight=security#multiprocessing.connection.Connection - subcategory: - - audit - technology: - - python - pattern-either: - - pattern: multiprocessing.connection.Connection.recv(...) - - pattern: multiprocessing.connection.Client.recv(...) - - pattern: | - $C = multiprocessing.connection.Client(...) - ... - $C.recv(...) - severity: WARNING - - id: python.lang.security.audit.dangerous-annotations-usage.dangerous-annotations-usage - languages: - - python - message: Annotations passed to `typing.get_type_hints` are evaluated in `globals` and `locals` namespaces. Make sure that no arbitrary value can be written as the annotation and passed to `typing.get_type_hints` function. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://docs.python.org/3/library/typing.html#typing.get_type_hints - subcategory: - - audit - technology: - - python - patterns: - - pattern: | - $C.__annotations__[$NAME] = $X - - pattern-not: | - $C.__annotations__[$NAME] = "..." - - pattern-not: | - $C.__annotations__[$NAME] = typing.$Y - - metavariable-regex: - metavariable: $X - regex: (?!(int|float|complex|list|tuple|range|str|bytes|bytearray|memoryview|set|frozenset|dict)) - severity: INFO - - id: python.lang.security.audit.dangerous-asyncio-create-exec-audit.dangerous-asyncio-create-exec-audit - languages: - - python - message: Detected 'create_subprocess_exec' function without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.create_subprocess_exec - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - audit - technology: - - python - pattern-either: - - patterns: - - pattern-not: asyncio.create_subprocess_exec($PROG, "...", ...) - - pattern-not: asyncio.create_subprocess_exec($PROG, ["...",...], ...) - - pattern: asyncio.create_subprocess_exec(...) - - patterns: - - pattern-not: asyncio.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) - - pattern: asyncio.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) - - patterns: - - pattern-not: asyncio.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) - - pattern: asyncio.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) - - patterns: - - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, "...", ...) - - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, ["...",...], ...) - - pattern: asyncio.subprocess.create_subprocess_exec(...) - - patterns: - - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) - - pattern: asyncio.subprocess.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) - - patterns: - - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) - - pattern: asyncio.subprocess.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) - severity: ERROR - - id: python.lang.security.audit.dangerous-asyncio-create-exec-tainted-env-args.dangerous-asyncio-create-exec-tainted-env-args - languages: - - python - message: Detected 'create_subprocess_exec' function with user controlled data. You may consider using 'shlex.escape()'. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.create_subprocess_exec - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - pattern-either: - - patterns: - - pattern-not: asyncio.create_subprocess_exec($PROG, "...", ...) - - pattern-not: asyncio.create_subprocess_exec($PROG, ["...",...], ...) - - pattern: asyncio.create_subprocess_exec(...) - - patterns: - - pattern-not: asyncio.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) - - pattern: asyncio.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) - - patterns: - - pattern-not: asyncio.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) - - pattern: asyncio.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) - - patterns: - - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, "...", ...) - - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, ["...",...], ...) - - pattern: asyncio.subprocess.create_subprocess_exec(...) - - patterns: - - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) - - pattern: asyncio.subprocess.create_subprocess_exec($PROG, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) - - patterns: - - pattern-not: asyncio.subprocess.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) - - pattern: asyncio.subprocess.create_subprocess_exec($PROG, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.audit.dangerous-asyncio-exec-audit.dangerous-asyncio-exec-audit - languages: - - python - message: Detected subprocess function '$LOOP.subprocess_exec' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - audit - technology: - - python - pattern-either: - - patterns: - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "...", ...) - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["...",...], ...) - - pattern: $LOOP.subprocess_exec(...) - - patterns: - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) - - pattern: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) - - patterns: - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) - - pattern: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) - severity: ERROR - - id: python.lang.security.audit.dangerous-asyncio-exec-tainted-env-args.dangerous-asyncio-exec-tainted-env-args - languages: - - python - message: Detected subprocess function '$LOOP.subprocess_exec' with user controlled data. You may consider using 'shlex.escape()'. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - pattern-either: - - patterns: - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "...", ...) - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["...",...], ...) - - pattern: $LOOP.subprocess_exec(...) - - patterns: - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) - - pattern: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) - - patterns: - - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) - - pattern: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.audit.dangerous-asyncio-shell-audit.dangerous-asyncio-shell-audit - languages: - - python - message: Detected asyncio subprocess function without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.python.org/3/library/asyncio-subprocess.html - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - audit - technology: - - python - patterns: - - pattern-either: - - pattern: $LOOP.subprocess_shell($PROTOCOL, $CMD) - - pattern: asyncio.subprocess.create_subprocess_shell($CMD, ...) - - pattern: asyncio.create_subprocess_shell($CMD, ...) - - pattern-not-inside: | - $CMD = "..." - ... - - pattern-not: $LOOP.subprocess_shell($PROTOCOL, "...") - - pattern-not: asyncio.subprocess.create_subprocess_shell("...", ...) - - pattern-not: asyncio.create_subprocess_shell("...", ...) - severity: ERROR - - id: python.lang.security.audit.dangerous-asyncio-shell-tainted-env-args.dangerous-asyncio-shell-tainted-env-args - languages: - - python - message: Detected asyncio subprocess function with user controlled data. You may consider using 'shlex.escape()'. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.python.org/3/library/asyncio-subprocess.html - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: $LOOP.subprocess_shell($PROTOCOL, $CMD) - - pattern-inside: asyncio.subprocess.create_subprocess_shell($CMD, ...) - - pattern-inside: asyncio.create_subprocess_shell($CMD, ...) - - focus-metavariable: $CMD - - pattern-not-inside: | - $CMD = "..." - ... - - pattern-not: $LOOP.subprocess_shell($PROTOCOL, "...") - - pattern-not: asyncio.subprocess.create_subprocess_shell("...", ...) - - pattern-not: asyncio.create_subprocess_shell("...", ...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.audit.dangerous-code-run-audit.dangerous-interactive-code-run-audit - languages: - - python - message: Found dynamic content inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. Ensure no external data reaches here. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - audit - technology: - - python - patterns: - - pattern-either: - - pattern: | - $X.push($PAYLOAD,...) - - pattern: | - $X.runsource($PAYLOAD,...) - - pattern: | - $X.runcode(code.compile_command($PAYLOAD),...) - - pattern: | - $PL = code.compile_command($PAYLOAD,...) - ... - $X.runcode($PL,...) - - pattern-either: - - pattern-inside: | - $X = code.InteractiveConsole(...) - ... - - pattern-inside: | - $X = code.InteractiveInterpreter(...) - ... - - pattern-not: | - $X.push("...",...) - - pattern-not: | - $X.runsource("...",...) - - pattern-not: | - $X.runcode(code.compile_command("..."),...) - - pattern-not: | - $PL = code.compile_command("...",...) - ... - $X.runcode($PL,...) - severity: WARNING - - id: python.lang.security.audit.dangerous-code-run-tainted-env-args.dangerous-interactive-code-run-tainted-env-args - languages: - - python - message: Found user controlled data inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $X = code.InteractiveConsole(...) - ... - - pattern-inside: | - $X = code.InteractiveInterpreter(...) - ... - - pattern-either: - - pattern-inside: | - $X.push($PAYLOAD,...) - - pattern-inside: | - $X.runsource($PAYLOAD,...) - - pattern-inside: | - $X.runcode(code.compile_command($PAYLOAD),...) - - pattern-inside: | - $PL = code.compile_command($PAYLOAD,...) - ... - $X.runcode($PL,...) - - pattern: $PAYLOAD - - pattern-not: | - $X.push("...",...) - - pattern-not: | - $X.runsource("...",...) - - pattern-not: | - $X.runcode(code.compile_command("..."),...) - - pattern-not: | - $PL = code.compile_command("...",...) - ... - $X.runcode($PL,...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: WARNING - - id: python.lang.security.audit.dangerous-os-exec-audit.dangerous-os-exec-audit - languages: - - python - message: Found dynamic content when spawning a process. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - audit - technology: - - python - pattern-either: - - patterns: - - pattern-not: os.$METHOD("...", ...) - - pattern: os.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (execl|execle|execlp|execlpe|execv|execve|execvp|execvpe) - - patterns: - - pattern-not: os.$METHOD("...", [$PATH,"...","...",...],...) - - pattern: os.$METHOD($BASH,[$PATH,"-c",$CMD,...],...) - - metavariable-regex: - metavariable: $METHOD - regex: (execv|execve|execvp|execvpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-not: os.$METHOD("...", $PATH, "...", "...",...) - - pattern: os.$METHOD($BASH, $PATH, "-c", $CMD,...) - - metavariable-regex: - metavariable: $METHOD - regex: (execl|execle|execlp|execlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - severity: ERROR - - id: python.lang.security.audit.dangerous-os-exec-tainted-env-args.dangerous-os-exec-tainted-env-args - languages: - - python - message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-not: os.$METHOD("...", ...) - - pattern: os.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (execl|execle|execlp|execlpe|execv|execve|execvp|execvpe) - - patterns: - - pattern-not: os.$METHOD("...", [$PATH,"...","...",...],...) - - pattern-inside: os.$METHOD($BASH,[$PATH,"-c",$CMD,...],...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (execv|execve|execvp|execvpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-not: os.$METHOD("...", $PATH, "...", "...",...) - - pattern-inside: os.$METHOD($BASH, $PATH, "-c", $CMD,...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (execl|execle|execlp|execlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.audit.dangerous-spawn-process-audit.dangerous-spawn-process-audit - languages: - - python - message: Found dynamic content when spawning a process. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html - subcategory: - - audit - technology: - - python - pattern-either: - - patterns: - - pattern-not: os.$METHOD($MODE, "...", ...) - - pattern: os.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) - - patterns: - - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...) - - pattern: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...) - - metavariable-regex: - metavariable: $METHOD - regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...) - - pattern: os.$METHOD($MODE, $BASH, "-c", $CMD,...) - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - severity: ERROR - - id: python.lang.security.audit.dangerous-spawn-process-tainted-env-args.dangerous-spawn-process-tainted-env-args - languages: - - python - message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-not: os.$METHOD($MODE, "...", ...) - - pattern-inside: os.$METHOD($MODE, $CMD, ...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) - - patterns: - - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...) - - pattern-inside: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...) - - pattern-inside: os.$METHOD($MODE, $BASH, "-c", $CMD,...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.audit.dangerous-subinterpreters-run-string-audit.dangerous-subinterpreters-run-string-audit - languages: - - python - message: Found dynamic content in `run_string`. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. Ensure no external data reaches here. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://bugs.python.org/issue43472 - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - audit - technology: - - python - patterns: - - pattern: | - _xxsubinterpreters.run_string($ID, $PAYLOAD, ...) - - pattern-not: | - _xxsubinterpreters.run_string($ID, "...", ...) - severity: WARNING - - id: python.lang.security.audit.dangerous-subinterpreters-run-string-tainted-env-args.dangerous-subinterpreters-run-string-tainted-env-args - languages: - - python - message: Found user controlled content in `run_string`. This is dangerous because it allows a malicious actor to run arbitrary Python code. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://bugs.python.org/issue43472 - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-inside: | - _xxsubinterpreters.run_string($ID, $PAYLOAD, ...) - - pattern-not: | - _xxsubinterpreters.run_string($ID, "...", ...) - - pattern: $PAYLOAD - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: WARNING - - id: python.lang.security.audit.dangerous-subprocess-use-audit.dangerous-subprocess-use-audit - languages: - - python - message: Detected subprocess function '$FUNC' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess - - https://docs.python.org/3/library/subprocess.html - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - audit - technology: - - python - pattern-either: - - patterns: - - pattern-not: subprocess.$FUNC("...", ...) - - pattern-not: subprocess.$FUNC(["...",...], ...) - - pattern-not: subprocess.$FUNC(("...",...), ...) - - pattern-not: - patterns: - - pattern-not-inside: | - $ARR = ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...] - ... - - pattern-inside: | - $ARR = [...] - ... - - pattern-either: - - pattern: subprocess.$FUNC(*$ARR, ...) - - pattern: subprocess.$FUNC([*$ARR, ...]) - - pattern-not: subprocess.CalledProcessError(...) - - pattern-not: subprocess.SubprocessError(...) - - pattern: subprocess.$FUNC(...) - - patterns: - - pattern: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",...) - - pattern-not: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...) - - patterns: - - pattern-either: - - pattern: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",...],...) - - pattern: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",...),...) - - pattern-not: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...],...) - - pattern-not: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...),...) - - patterns: - - pattern: subprocess.$FUNC("=~/(python)/",...) - - pattern-not: subprocess.$FUNC("=~/(python)/","...",...) - - patterns: - - pattern-either: - - pattern: subprocess.$FUNC(["=~/(python)/",...],...) - - pattern: subprocess.$FUNC(("=~/(python)/",...),...) - - pattern-not: subprocess.$FUNC(["=~/(python)/","...",...],...) - - pattern-not: subprocess.$FUNC(("=~/(python)/","...",...),...) - severity: ERROR - - id: python.lang.security.audit.dangerous-subprocess-use-tainted-env-args.dangerous-subprocess-use-tainted-env-args - languages: - - python - message: Detected subprocess function '$FUNC' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.escape()'. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess - - https://docs.python.org/3/library/subprocess.html - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-not: subprocess.$FUNC("...", ...) - - pattern-not: subprocess.$FUNC(["...",...], ...) - - pattern-not: subprocess.$FUNC(("...",...), ...) - - pattern-not: subprocess.CalledProcessError(...) - - pattern-not: subprocess.SubprocessError(...) - - pattern: subprocess.$FUNC($CMD, ...) - - patterns: - - pattern-not: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...) - - pattern: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD) - - patterns: - - pattern-not: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...],...) - - pattern-not: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...),...) - - pattern-either: - - pattern: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD], ...) - - pattern: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD), ...) - - patterns: - - pattern-not: subprocess.$FUNC("=~/(python)/","...",...) - - pattern: subprocess.$FUNC("=~/(python)/", $CMD) - - patterns: - - pattern-not: subprocess.$FUNC(["=~/(python)/","...",...],...) - - pattern-not: subprocess.$FUNC(("=~/(python)/","...",...),...) - - pattern-either: - - pattern: subprocess.$FUNC(["=~/(python)/", $CMD],...) - - pattern: subprocess.$FUNC(("=~/(python)/", $CMD),...) - - focus-metavariable: $CMD - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.audit.dangerous-system-call-audit.dangerous-system-call-audit - languages: - - python - message: Found dynamic content used in a system call. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. - metadata: - asvs: - control_id: 5.2.4 Dyanmic Code Execution Features - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html - subcategory: - - audit - technology: - - python - patterns: - - pattern-not: os.$W("...", ...) - - pattern-either: - - pattern: os.system(...) - - pattern: getattr(os, "system")(...) - - pattern: __import__("os").system(...) - - pattern: getattr(__import__("os"), "system")(...) - - pattern: | - $X = __import__("os") - ... - $X.system(...) - - pattern: | - $X = __import__("os") - ... - getattr($X, "system")(...) - - pattern: | - $X = getattr(os, "system") - ... - $X(...) - - pattern: | - $X = __import__("os") - ... - $Y = getattr($X, "system") - ... - $Y(...) - - pattern: os.popen(...) - - pattern: os.popen2(...) - - pattern: os.popen3(...) - - pattern: os.popen4(...) - severity: ERROR - - id: python.lang.security.audit.dangerous-system-call-tainted-env-args.dangerous-system-call-tainted-env-args - languages: - - python - message: Found user-controlled data used in a system call. This could allow a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. - metadata: - asvs: - control_id: 5.2.4 Dyanmic Code Execution Features - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-not: os.$W("...", ...) - - pattern-either: - - pattern: os.system(...) - - pattern: | - $X = __import__("os") - ... - $X.system(...) - - pattern: | - $X = __import__("os") - ... - getattr($X, "system")(...) - - pattern: | - $X = getattr(os, "system") - ... - $X(...) - - pattern: | - $X = __import__("os") - ... - $Y = getattr($X, "system") - ... - $Y(...) - - pattern: os.popen(...) - - pattern: os.popen2(...) - - pattern: os.popen3(...) - - pattern: os.popen4(...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.audit.dangerous-testcapi-run-in-subinterp-audit.dangerous-testcapi-run-in-subinterp-audit - languages: - - python - message: Found dynamic content in `run_in_subinterp`. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. Ensure no external data reaches here. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - audit - technology: - - python - patterns: - - pattern-either: - - pattern: | - _testcapi.run_in_subinterp($PAYLOAD, ...) - - pattern: | - test.support.run_in_subinterp($PAYLOAD, ...) - - pattern-not: | - _testcapi.run_in_subinterp("...", ...) - - pattern-not: | - test.support.run_in_subinterp("...", ...) - severity: WARNING - - id: python.lang.security.audit.dangerous-testcapi-run-in-subinterp-tainted-env-args.dangerous-testcapi-run-in-subinterp-tainted-env-args - languages: - - python - message: Found user controlled content in `run_in_subinterp`. This is dangerous because it allows a malicious actor to run arbitrary Python code. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - _testcapi.run_in_subinterp($PAYLOAD, ...) - - pattern-inside: | - test.support.run_in_subinterp($PAYLOAD, ...) - - pattern: $PAYLOAD - - pattern-not: | - _testcapi.run_in_subinterp("...", ...) - - pattern-not: | - test.support.run_in_subinterp("...", ...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: os.environ - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv - - pattern: sys.orig_argv - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: WARNING - - id: python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected - languages: - - python - message: Detected a dynamic value being used with urllib. urllib supports 'file://' schemes, so a dynamic value controlled by a malicious actor may allow them to read arbitrary files. Audit uses of urllib calls to ensure user data cannot control the URLs, or consider using the 'requests' library instead. - metadata: - asvs: - control_id: 5.2.4 Dynamic Code Execution Features - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - bandit-code: B310 - category: security - confidence: LOW - cwe: - - 'CWE-939: Improper Authorization in Handler for Custom URL Scheme' - impact: LOW - likelihood: LOW - owasp: A01:2017 - Injection - references: - - https://cwe.mitre.org/data/definitions/939.html - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/blacklists/calls.py#L163 - subcategory: - - audit - technology: - - python - patterns: - - pattern-not: urllib.$W("...") - - pattern-not: urllib.request.$W("...") - - pattern-not: $OPENER.$W("...") - - pattern-either: - - pattern: urllib.urlopen(...) - - pattern: urllib.request.urlopen(...) - - pattern: urllib.urlretrieve(...) - - pattern: urllib.request.urlretrieve(...) - - patterns: - - pattern-either: - - pattern-inside: | - $OPENER = urllib.URLopener(...) - ... - - pattern-inside: | - $OPENER = urllib.request.URLopener(...) - ... - - pattern-inside: | - $OPENER = urllib.FancyURLopener(...) - ... - - pattern-inside: | - $OPENER = urllib.request.FancyURLopener(...) - ... - - pattern-either: - - pattern: $OPENER.open(...) - - pattern: $OPENER.retrieve(...) - severity: WARNING - - id: python.lang.security.audit.eval-detected.eval-detected - languages: - - python - message: Detected the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources. - metadata: - asvs: - control_id: 5.2.4 Dyanmic Code Execution Features - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html#b307-eval - subcategory: - - audit - technology: - - python - patterns: - - pattern-not: eval(f"") - - pattern-not: eval("...") - - pattern: eval(...) - severity: WARNING - - id: python.lang.security.audit.exec-detected.exec-detected - languages: - - python - message: Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources. - metadata: - asvs: - control_id: 5.2.4 Dyanmic Code Execution Features - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b102_exec_used.html - subcategory: - - audit - technology: - - python - patterns: - - pattern-not: exec("...") - - pattern: exec(...) - severity: WARNING - - id: python.lang.security.audit.formatted-sql-query.formatted-sql-query - languages: - - python - message: Detected possible formatted SQL query. Use parameterized queries instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://stackoverflow.com/questions/775296/mysql-parameterized-queries - subcategory: - - audit - technology: - - python - pattern-either: - - pattern: $DB.execute("..." % ...) - - pattern: $DB.execute("...".format(...)) - - pattern: $DB.execute(f"...") - - patterns: - - pattern-either: - - pattern-inside: | - $SQL = "..." % ... - ... - - pattern-inside: | - $SQL = "...".format(...) - ... - - pattern-inside: | - $SQL = f"...{$X}..." - ... - - pattern: $DB.execute($SQL) - severity: WARNING - - id: python.lang.security.audit.ftplib.ftplib - languages: - - python - message: FTP does not encrypt communications by default. This can lead to sensitive data being exposed. Ensure use of FTP here does not expose sensitive data. - metadata: - bandit-code: B321 - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/telnetlib.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L265 - subcategory: - - audit - technology: - - ftplib - pattern: ftplib.$ANYTHING(...) - severity: WARNING - - id: python.lang.security.audit.hardcoded-password-default-argument.hardcoded-password-default-argument - languages: - - python - message: Hardcoded password is used as a default argument to '$FUNC'. This could be dangerous if a real password is not supplied. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - subcategory: - - audit - technology: - - python - patterns: - - pattern: | - def $FUNC(..., password="...", ...): - ... - - pattern-not: | - def $FUNC(..., password="", ...): - ... - severity: WARNING - - id: python.lang.security.audit.httpsconnection-detected.httpsconnection-detected - languages: - - python - message: The HTTPSConnection API has changed frequently with minor releases of Python. Ensure you are using the API for your version of Python securely. For example, Python 3 versions prior to 3.4.3 will not verify SSL certificates by default. See https://docs.python.org/3/library/http.client.html#http.client.HTTPSConnection for more information. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures - references: - - https://docs.python.org/3/library/http.client.html#http.client.HTTPSConnection - subcategory: - - audit - technology: - - python - pattern-either: - - pattern: httplib.HTTPSConnection(...) - - pattern: http.client.HTTPSConnection(...) - - pattern: six.moves.http_client.HTTPSConnection(...) - severity: WARNING - - id: python.lang.security.audit.insecure-file-permissions.insecure-file-permissions - languages: - - python - message: These permissions `$BITS` are widely permissive and grant access to more people than may be necessary. A good default is `0o644` which gives read and write access to yourself and read access to everyone else. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-276: Incorrect Default Permissions' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - python - patterns: - - pattern-inside: os.$METHOD(...) - - metavariable-pattern: - metavariable: $METHOD - patterns: - - pattern-either: - - pattern: chmod - - pattern: lchmod - - pattern: fchmod - - pattern-either: - - patterns: - - pattern: os.$METHOD($FILE, $BITS, ...) - - metavariable-comparison: - comparison: $BITS >= 0o650 and $BITS < 0o100000 - metavariable: $BITS - - patterns: - - pattern: os.$METHOD($FILE, $BITS) - - metavariable-comparison: - comparison: $BITS >= 0o100650 - metavariable: $BITS - - patterns: - - pattern: os.$METHOD($FILE, $BITS, ...) - - metavariable-pattern: - metavariable: $BITS - patterns: - - pattern-either: - - pattern: <... stat.S_IWGRP ...> - - pattern: <... stat.S_IXGRP ...> - - pattern: <... stat.S_IWOTH ...> - - pattern: <... stat.S_IXOTH ...> - - pattern: <... stat.S_IRWXO ...> - - pattern: <... stat.S_IRWXG ...> - - patterns: - - pattern: os.$METHOD($FILE, $EXPR | $MOD, ...) - - metavariable-comparison: - comparison: $MOD == 0o111 - metavariable: $MOD - severity: WARNING - - fix-regex: - regex: FTP(.*)\) - replacement: FTP_TLS\1, context=ssl.create_default_context()) - id: python.lang.security.audit.insecure-transport.ftplib.use-ftp-tls.use-ftp-tls - languages: - - python - message: The 'FTP' class sends information unencrypted. Consider using the 'FTP_TLS' class instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/ftplib.html#ftplib.FTP_TLS - subcategory: - - audit - technology: - - ftplib - pattern: ftplib.FTP(...) - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.requests.request-session-http-in-with-context.request-session-http-in-with-context - languages: - - python - message: Detected a request using 'http://'. This request will be unencrypted. Use 'https://' instead. - metadata: - asvs: - control_id: 9.2.1 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - requests - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-inside: | - with requests.Session(...) as $SESSION: - ... - - pattern-either: - - pattern: $SESSION.$W($SINK, ...) - - pattern: $SESSION.request($METHOD, $SINK, ...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern: | - "$URL" - - metavariable-pattern: - language: regex - metavariable: $URL - patterns: - - pattern-regex: http:// - - pattern-not-regex: .*://localhost - - pattern-not-regex: .*://127\.0\.0\.1 - severity: INFO - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.requests.request-session-with-http.request-session-with-http - languages: - - python - message: Detected a request using 'http://'. This request will be unencrypted. Use 'https://' instead. - metadata: - asvs: - control_id: 9.1.1 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - requests - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: requests.Session(...).$W($SINK, ...) - - pattern: requests.Session(...).request($METHOD, $SINK, ...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern: | - "$URL" - - metavariable-pattern: - language: regex - metavariable: $URL - patterns: - - pattern-regex: http:// - - pattern-not-regex: .*://localhost - - pattern-not-regex: .*://127\.0\.0\.1 - severity: INFO - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.requests.request-with-http.request-with-http - languages: - - python - message: Detected a request using 'http://'. This request will be unencrypted, and attackers could listen into traffic on the network and be able to obtain sensitive information. Use 'https://' instead. - metadata: - asvs: - control_id: 9.1.1 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - requests - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: requests.$W($SINK, ...) - - pattern: requests.request($METHOD, $SINK, ...) - - pattern: requests.Request($METHOD, $SINK, ...) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern: | - "$URL" - - metavariable-pattern: - language: regex - metavariable: $URL - patterns: - - pattern-regex: http:// - - pattern-not-regex: .*://localhost - - pattern-not-regex: .*://127\.0\.0\.1 - severity: INFO - - id: python.lang.security.audit.insecure-transport.ssl.no-set-ciphers.no-set-ciphers - languages: - - python - message: The 'ssl' module disables insecure cipher suites by default. Therefore, use of 'set_ciphers()' should only be used when you have very specialized requirements. Otherwise, you risk lowering the security of the SSL channel. - metadata: - asvs: - control_id: 9.1.3 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v91-client-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/ssl.html#cipher-selection - - https://docs.python.org/3/library/ssl.html#ssl.SSLContext.set_ciphers - subcategory: - - audit - technology: - - ssl - pattern: $CONTEXT.set_ciphers(...) - severity: WARNING - - id: python.lang.security.audit.insecure-transport.urllib.insecure-openerdirector-open-ftp.insecure-openerdirector-open-ftp - languages: - - python - message: Detected an unsecured transmission channel. 'OpenerDirector.open(...)' is being used with 'ftp://'. Information sent over this connection will be unencrypted. Consider using SFTP instead. urllib does not support SFTP, so consider a library which supports SFTP. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.OpenerDirector.open - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.OpenerDirector(...).open("=~/^[Ff][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.OpenerDirector(...) - ... - - pattern: $OPENERDIRECTOR.open("=~/^[Ff][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.OpenerDirector(...) - ... - - pattern: | - $URL = "=~/^[Ff][Tt][Pp]://.*/" - ... - $OPENERDIRECTOR.open($URL, ...) - - pattern: | - $URL = "=~/^[Ff][Tt][Pp]://.*/" - ... - urllib.request.OpenerDirector(...).open($URL, ...) - - patterns: - - pattern-inside: | - def $FUNC(..., $URL = "=~/^[Ff][Tt][Pp]://.*/", ...): - ... - - pattern-either: - - pattern: urllib.request.OpenerDirector(...).open($URL, ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.OpenerDirector(...) - ... - - pattern: $OPENERDIRECTOR.open($URL, ...) - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.urllib.insecure-openerdirector-open.insecure-openerdirector-open - languages: - - python - message: Detected an unsecured transmission channel. 'OpenerDirector.open(...)' is being used with 'http://'. Use 'https://' instead to secure the channel. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.OpenerDirector.open - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.OpenerDirector(...).open("=~/[Hh][Tt][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.OpenerDirector(...) - ... - - pattern: $OPENERDIRECTOR.open("=~/[Hh][Tt][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.OpenerDirector(...) - ... - - pattern: | - $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" - ... - $OPENERDIRECTOR.open($URL, ...) - - pattern: | - $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" - ... - urllib.request.OpenerDirector(...).open($URL, ...) - - patterns: - - pattern-inside: | - def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): - ... - - pattern-either: - - pattern: urllib.request.OpenerDirector(...).open($URL, ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.OpenerDirector(...) - ... - - pattern: $OPENERDIRECTOR.open($URL, ...) - severity: WARNING - - id: python.lang.security.audit.insecure-transport.urllib.insecure-request-object-ftp.insecure-request-object-ftp - languages: - - python - message: Detected a 'urllib.request.Request()' object using an insecure transport protocol, 'ftp://'. This connection will not be encrypted. Consider using SFTP instead. urllib does not support SFTP natively, so consider using a library which supports SFTP. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.Request - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.Request("=~/^[Ff][Tt][Pp]://.*/", ...) - - pattern: | - $URL = "=~/^[Ff][Tt][Pp]://.*/" - ... - urllib.request.Request($URL, ...) - - pattern: |- - def $FUNC(..., $URL = "=~/^[Ff][Tt][Pp]://.*/", ...): - ... - urllib.request.Request($URL, ...) - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.urllib.insecure-request-object.insecure-request-object - languages: - - python - message: Detected a 'urllib.request.Request()' object using an insecure transport protocol, 'http://'. This connection will not be encrypted. Use 'https://' instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.Request - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.Request("=~/[Hh][Tt][Tt][Pp]://.*/", ...) - - pattern: | - $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" - ... - urllib.request.Request($URL, ...) - - pattern: | - def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): - ... - urllib.request.Request($URL, ...) - severity: WARNING - - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopen-ftp.insecure-urlopen-ftp - languages: - - python - message: Detected 'urllib.urlopen()' using 'ftp://'. This request will not be encrypted. Consider using SFTP instead. urllib does not support SFTP, so consider switching to a library which supports SFTP. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.urlopen - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.urlopen("=~/^[Ff][Tt][Pp]://.*/", ...) - - pattern: | - $URL = "=~/^[Ff][Tt][Pp]://.*/" - ... - urllib.request.urlopen($URL, ...) - - pattern: |- - def $FUNC(..., $URL = "=~/^[Ff][Tt][Pp]://.*/", ...): - ... - urllib.request.urlopen($URL, ...) - severity: WARNING - - fix-regex: - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopen.insecure-urlopen - languages: - - python - message: Detected 'urllib.urlopen()' using 'http://'. This request will not be encrypted. Use 'https://' instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.urlopen - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.urlopen("=~/[Hh][Tt][Tt][Pp]://.*/", ...) - - pattern: | - $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" - ... - urllib.request.urlopen($URL, ...) - - pattern: | - def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): - ... - urllib.request.urlopen($URL, ...) - severity: WARNING - - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopener-open-ftp.insecure-urlopener-open-ftp - languages: - - python - message: Detected an insecure transmission channel. 'URLopener.open(...)' is being used with 'ftp://'. Use SFTP instead. urllib does not support SFTP, so consider using a library which supports SFTP. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.URLopener.open - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.URLopener(...).open("=~/[Ff][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: $OPENERDIRECTOR.open("=~/[Ff][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: | - $URL = "=~/[Ff][Tt][Pp]://.*/" - ... - $OPENERDIRECTOR.open($URL, ...) - - pattern: | - $URL = "=~/[Ff][Tt][Pp]://.*/" - ... - urllib.request.URLopener(...).open($URL, ...) - - patterns: - - pattern-inside: | - def $FUNC(..., $URL = "=~/[Ff][Tt][Pp]://.*/", ...): - ... - - pattern-either: - - pattern: urllib.request.URLopener(...).open($URL, ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: $OPENERDIRECTOR.open($URL, ...) - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopener-open.insecure-urlopener-open - languages: - - python - message: Detected an unsecured transmission channel. 'URLopener.open(...)' is being used with 'http://'. Use 'https://' instead to secure the channel. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.URLopener.open - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.URLopener(...).open("=~/[Hh][Tt][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: $OPENERDIRECTOR.open("=~/[Hh][Tt][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: | - $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" - ... - $OPENERDIRECTOR.open($URL, ...) - - pattern: | - $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" - ... - urllib.request.URLopener(...).open($URL, ...) - - patterns: - - pattern-inside: | - def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): - ... - - pattern-either: - - pattern: urllib.request.URLopener(...).open($URL, ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: $OPENERDIRECTOR.open($URL, ...) - severity: WARNING - - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopener-retrieve-ftp.insecure-urlopener-retrieve-ftp - languages: - - python - message: Detected an insecure transmission channel. 'URLopener.retrieve(...)' is being used with 'ftp://'. Use SFTP instead. urllib does not support SFTP, so consider using a library which supports SFTP. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.URLopener.retrieve - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.URLopener(...).retrieve("=~/[Ff][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: $OPENERDIRECTOR.retrieve("=~/[Ff][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: | - $URL = "=~/[Ff][Tt][Pp]://.*/" - ... - $OPENERDIRECTOR.retrieve($URL, ...) - - pattern: | - $URL = "=~/[Ff][Tt][Pp]://.*/" - ... - urllib.request.URLopener(...).retrieve($URL, ...) - - patterns: - - pattern-inside: | - def $FUNC(..., $URL = "=~/[Ff][Tt][Pp]://.*/", ...): - ... - - pattern-either: - - pattern: urllib.request.URLopener(...).retrieve($URL, ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: $OPENERDIRECTOR.retrieve($URL, ...) - severity: WARNING - - fix-regex: - count: 1 - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlopener-retrieve.insecure-urlopener-retrieve - languages: - - python - message: Detected an unsecured transmission channel. 'URLopener.retrieve(...)' is being used with 'http://'. Use 'https://' instead to secure the channel. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.URLopener.retrieve - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.URLopener(...).retrieve("=~/[Hh][Tt][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: $OPENERDIRECTOR.retrieve("=~/[Hh][Tt][Tt][Pp]://.*/", ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: | - $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" - ... - $OPENERDIRECTOR.retrieve($URL, ...) - - pattern: | - $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" - ... - urllib.request.URLopener(...).retrieve($URL, ...) - - patterns: - - pattern-inside: | - def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): - ... - - pattern-either: - - pattern: urllib.request.URLopener(...).retrieve($URL, ...) - - patterns: - - pattern-inside: | - $OPENERDIRECTOR = urllib.request.URLopener(...) - ... - - pattern: $OPENERDIRECTOR.retrieve($URL, ...) - severity: WARNING - - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlretrieve-ftp.insecure-urlretrieve-ftp - languages: - - python - message: Detected 'urllib.urlretrieve()' using 'ftp://'. This request will not be encrypted. Use SFTP instead. urllib does not support SFTP, so consider switching to a library which supports SFTP. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.urlretrieve - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.urlretrieve("=~/^[Ff][Tt][Pp]://.*/", ...) - - pattern: | - $URL = "=~/^[Ff][Tt][Pp]://.*/" - ... - urllib.request.urlretrieve($URL, ...) - - pattern: |- - def $FUNC(..., $URL = "=~/^[Ff][Tt][Pp]://.*/", ...): - ... - urllib.request.urlretrieve($URL, ...) - severity: WARNING - - fix-regex: - regex: '[Hh][Tt][Tt][Pp]://' - replacement: https:// - id: python.lang.security.audit.insecure-transport.urllib.insecure-urlretrieve.insecure-urlretrieve - languages: - - python - message: Detected 'urllib.urlretrieve()' using 'http://'. This request will not be encrypted. Use 'https://' instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/urllib.request.html#urllib.request.urlretrieve - subcategory: - - audit - technology: - - urllib - pattern-either: - - pattern: urllib.request.urlretrieve("=~/[Hh][Tt][Tt][Pp]://.*/", ...) - - pattern: | - $URL = "=~/[Hh][Tt][Tt][Pp]://.*/" - ... - urllib.request.urlretrieve($URL, ...) - - pattern: | - def $FUNC(..., $URL = "=~/[Hh][Tt][Tt][Pp]://.*/", ...): - ... - urllib.request.urlretrieve($URL, ...) - severity: WARNING - - id: python.lang.security.audit.logging.listeneval.listen-eval - languages: - - python - message: Because portions of the logging configuration are passed through eval(), use of this function may open its users to a security risk. While the function only binds to a socket on localhost, and so does not accept connections from remote machines, there are scenarios where untrusted code could be run under the account of the process which calls listen(). To avoid this happening, use the `verify()` argument to `listen()` to prevent unrecognized configurations. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: LOW - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://docs.python.org/3/library/logging.config.html?highlight=security#logging.config.listen - subcategory: - - audit - technology: - - python - pattern: logging.config.listen(...) - severity: WARNING - - id: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure - languages: - - python - message: Detected a python logger call with a potential hardcoded secret $FORMAT_STRING being logged. This may lead to secret credentials being exposed. Make sure that the logger is not logging sensitive information. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-532: Insertion of Sensitive Information into Log File' - impact: MEDIUM - likelihood: LOW - owasp: - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures - subcategory: - - vuln - technology: - - python - patterns: - - pattern: | - $LOGGER_OBJ.$LOGGER_CALL($FORMAT_STRING,...) - - metavariable-regex: - metavariable: $LOGGER_OBJ - regex: (?i)(_logger|logger|self.logger|log) - - metavariable-regex: - metavariable: $LOGGER_CALL - regex: (debug|info|warn|warning|error|exception|critical) - - metavariable-regex: - metavariable: $FORMAT_STRING - regex: (?i).*(api.key|secret|credential|token|password).*\%s.* - severity: WARNING - - id: python.lang.security.audit.mako-templates-detected.mako-templates-detected - languages: - - python - message: Mako templates do not provide a global HTML escaping mechanism. This means you must escape all sensitive data in your templates using '| u' for URL escaping or '| h' for HTML escaping. If you are using Mako to serve web content, consider using a system such as Jinja2 which enables global escaping. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://docs.makotemplates.org/en/latest/syntax.html#expression-escaping - - https://jinja.palletsprojects.com/en/2.11.x/intro/# - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/mako_templates.py - subcategory: - - audit - technology: - - mako - pattern: mako.template.Template(...) - severity: INFO - - id: python.lang.security.audit.marshal.marshal-usage - languages: - - python - message: 'The marshal module is not intended to be secure against erroneous or maliciously constructed data. Never unmarshal data received from an untrusted or unauthenticated source. See more details: https://docs.python.org/3/library/marshal.html?highlight=security' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.python.org/3/library/marshal.html?highlight=security - subcategory: - - audit - technology: - - python - pattern-either: - - pattern: marshal.dump(...) - - pattern: marshal.dumps(...) - - pattern: marshal.load(...) - - pattern: marshal.loads(...) - severity: WARNING - - id: python.lang.security.audit.md5-used-as-password.md5-used-as-password - languages: - - python - message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as scrypt. You can use `hashlib.scrypt`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://tools.ietf.org/html/rfc6151 - - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords - - https://github.com/returntocorp/semgrep-rules/issues/1609 - - https://docs.python.org/3/library/hashlib.html#hashlib.scrypt - subcategory: - - vuln - technology: - - pycryptodome - - hashlib - - md5 - mode: taint - pattern-sinks: - - patterns: - - pattern: $FUNCTION(...) - - metavariable-regex: - metavariable: $FUNCTION - regex: (?i)(.*password.*) - pattern-sources: - - patterns: - - pattern-either: - - pattern: hashlib.md5 - - pattern: hashlib.new(..., name="MD5", ...) - - pattern: Cryptodome.Hash.MD5 - - pattern: Crypto.Hash.MD5 - - pattern: cryptography.hazmat.primitives.hashes.MD5 - severity: WARNING - - id: python.lang.security.audit.network.bind.avoid-bind-to-all-interfaces - languages: - - python - message: Running `socket.bind` to 0.0.0.0, or empty string could unexpectedly expose the server publicly as it binds to all available interfaces. Consider instead getting correct address from an environment variable or configuration file. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - python - pattern-either: - - pattern: | - $S = socket.socket(...) - ... - $S.bind(("0.0.0.0", ...)) - - pattern: | - $S = socket.socket(...) - ... - $S.bind(("::", ...)) - - pattern: | - $S = socket.socket(...) - ... - $S.bind(("", ...)) - severity: INFO - - id: python.lang.security.audit.network.disabled-cert-validation.disabled-cert-validation - languages: - - python - message: certificate verification explicitly disabled, insecure connections possible - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - subcategory: - - vuln - technology: - - python - patterns: - - pattern-either: - - pattern: urllib3.PoolManager(..., cert_reqs=$REQS, ...) - - pattern: urllib3.ProxyManager(..., cert_reqs=$REQS, ...) - - pattern: urllib3.HTTPSConnectionPool(..., cert_reqs=$REQS, ...) - - pattern: urllib3.connectionpool.HTTPSConnectionPool(..., cert_reqs=$REQS, ...) - - pattern: urllib3.connection_from_url(..., cert_reqs=$REQS, ...) - - pattern: urllib3.proxy_from_url(..., cert_reqs=$REQS, ...) - - pattern: $CONTEXT.wrap_socket(..., cert_reqs=$REQS, ...) - - pattern: ssl.wrap_socket(..., cert_reqs=$REQS, ...) - - metavariable-regex: - metavariable: $REQS - regex: (NONE|CERT_NONE|CERT_OPTIONAL|ssl\.CERT_NONE|ssl\.CERT_OPTIONAL|\'NONE\'|\"NONE\"|\'OPTIONAL\'|\"OPTIONAL\") - severity: ERROR - - id: python.lang.security.audit.network.http-not-https-connection.http-not-https-connection - languages: - - python - message: Detected HTTPConnectionPool. This will transmit data in cleartext. It is recommended to use HTTPSConnectionPool instead for to encrypt communications. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://urllib3.readthedocs.io/en/1.2.1/pools.html#urllib3.connectionpool.HTTPSConnectionPool - subcategory: - - audit - technology: - - python - pattern-either: - - pattern: urllib3.HTTPConnectionPool(...) - - pattern: urllib3.connectionpool.HTTPConnectionPool(...) - severity: ERROR - - id: python.lang.security.audit.non-literal-import.non-literal-import - languages: - - python - message: Untrusted user input in `importlib.import_module()` function allows an attacker to load arbitrary code. Avoid dynamic values in `importlib.import_module()` or use a whitelist to prevent running untrusted code. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-706: Use of Incorrectly-Resolved Name or Reference' - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - python - patterns: - - pattern: | - importlib.import_module($NAME, ...) - - pattern-not: | - importlib.import_module("...", ...) - severity: WARNING - - id: python.lang.security.audit.paramiko-implicit-trust-host-key.paramiko-implicit-trust-host-key - languages: - - python - message: Detected a paramiko host key policy that implicitly trusts a server's host key. Host keys should be verified to ensure the connection is not to a malicious server. Use RejectPolicy or a custom subclass instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-322: Key Exchange without Entity Authentication' - impact: MEDIUM - likelihood: LOW - owasp: - - A02:2021 - Cryptographic Failures - references: - - http://docs.paramiko.org/en/stable/api/client.html#paramiko.client.AutoAddPolicy - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/ssh_no_host_key_verification.py - subcategory: - - audit - technology: - - paramiko - patterns: - - pattern-inside: | - $CLIENT = paramiko.client.SSHClient(...) - ... - $CLIENT.set_missing_host_key_policy(...) - - pattern-either: - - pattern: paramiko.client.AutoAddPolicy - - pattern: paramiko.client.WarningPolicy - severity: WARNING - - id: python.lang.security.audit.paramiko.paramiko-exec-command.paramiko-exec-command - languages: - - python - message: Unverified SSL context detected. This will permit insecure connections without verifying SSL certificates. Use 'ssl.create_default_context()' instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - http://docs.paramiko.org/en/stable/api/client.html#paramiko.client.SSHClient.exec_command - - https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/plugins/injection_paramiko.py - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/plugins/injection_paramiko.py - subcategory: - - audit - technology: - - paramiko - patterns: - - pattern-inside: | - $CLIENT = paramiko.client.SSHClient(...) - ... - - pattern: $CLIENT.exec_command(...) - - pattern-not: $CLIENT.exec_command("...", ...) - severity: ERROR - - id: python.lang.security.audit.python-reverse-shell.python-reverse-shell - languages: - - python - message: Semgrep found a Python reverse shell using $BINPATH to $IP at $PORT - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-553: Command Shell in Externally Accessible Directory' - impact: MEDIUM - likelihood: LOW - references: - - https://cwe.mitre.org/data/definitions/553.html - subcategory: - - audit - technology: - - python - patterns: - - pattern-either: - - pattern: pty.spawn("$BINPATH",...) - - pattern: subprocess.call(["$BINPATH",...],...) - - metavariable-regex: - metavariable: $BINPATH - regex: /bin/.*?sh\b - - pattern-inside: | - import socket - ... - $S = socket.socket(...) - ... - $S.connect(($IP,$PORT),...) - ... - severity: WARNING - - id: python.lang.security.audit.regex-dos.regex_dos - languages: - - python - message: Detected usage of re.compile with an inefficient regular expression. This can lead to regular expression denial of service, which can result in service down time. Instead, check all regexes or use safer alternatives such as pyre2. - metadata: - category: security - confidence: LOW - cwe: 'CWE-1333: Inefficient Regular Expression Complexity' - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: A06:2017 - Security Misconfiguration - references: - - https://docs.python.org/3/library/re.html - subcategory: - - vuln - technology: - - python - patterns: - - pattern: | - $A = re.compile("$B", ...) - ... - $A.$METHOD(...) - - metavariable-analysis: - analyzer: redos - metavariable: $B - - metavariable-regex: - metavariable: $METHOD - regex: (?!(escape)|(purge)) - severity: WARNING - - id: python.lang.security.audit.sqli.aiopg-sqli.aiopg-sqli - languages: - - python - message: 'Detected string concatenation with a non-literal variable in an aiopg Python SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries instead. You can create parameterized queries like so: ''cur.execute("SELECT %s FROM table", (user_value,))''.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/aio-libs/aiopg - subcategory: - - audit - technology: - - aiopg - patterns: - - pattern-either: - - patterns: - - pattern: $CUR.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = '...'.format(...) - ... - - pattern-inside: | - $QUERY = '...' % (...) - ... - - pattern-inside: | - $QUERY = f'...{$USERINPUT}...' - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern-not-inside: | - $QUERY = '...'.format() - ... - - pattern-not-inside: | - $QUERY = '...' % () - ... - - pattern: $CUR.$METHOD(..., $X + $Y, ...) - - pattern: $CUR.$METHOD(..., '...'.format(...), ...) - - pattern: $CUR.$METHOD(..., '...' % (...), ...) - - pattern: $CUR.$METHOD(..., f'...{$USERINPUT}...', ...) - - pattern-either: - - pattern-inside: | - $CONN = await aiopg.connect(...) - ... - $CUR = await $CONN.cursor(...) - ... - - pattern-inside: | - $POOL = await aiopg.create_pool(...) - ... - async with $POOL.acquire(...) as $CONN: - ... - async with $CONN.cursor(...) as $CUR: - ... - - pattern-inside: | - $POOL = await aiopg.create_pool(...) - ... - with (await $POOL.cursor(...)) as $CUR: - ... - - pattern-inside: | - $POOL = await aiopg.create_pool(...) - ... - async with $POOL as $CONN: - ... - $CUR = await $CONN.cursor(...) - ... - - pattern-inside: | - $POOL = await aiopg.create_pool(...) - ... - async with $POOL.cursor(...) as $CUR: - ... - - pattern-not: $CUR.$METHOD(..., "..." + "...", ...) - - pattern-not: $CUR.$METHOD(..., '...'.format(), ...) - - pattern-not: $CUR.$METHOD(..., '...'%(), ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(execute)$ - severity: WARNING - - id: python.lang.security.audit.sqli.asyncpg-sqli.asyncpg-sqli - languages: - - python - message: 'Detected string concatenation with a non-literal variable in a asyncpg Python SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can create parameterized queries like so: ''conn.fetch("SELECT $1 FROM table", value)''. You can also create prepared statements with ''Connection.prepare'': ''stmt = conn.prepare("SELECT $1 FROM table"); await stmt.fetch(user_value)''' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/MagicStack/asyncpg - - https://magicstack.github.io/asyncpg/current/ - subcategory: - - audit - technology: - - asyncpg - patterns: - - pattern-either: - - patterns: - - pattern: $CONN.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = '...'.format(...) - ... - - pattern-inside: | - $QUERY = '...' % (...) - ... - - pattern-inside: | - $QUERY = f'...{$USERINPUT}...' - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern-not-inside: | - $QUERY = '...'.format() - ... - - pattern-not-inside: | - $QUERY = '...' % () - ... - - pattern: $CONN.$METHOD(..., $X + $Y, ...) - - pattern: $CONN.$METHOD(..., $Y.format(...), ...) - - pattern: $CONN.$METHOD(..., '...'.format(...), ...) - - pattern: $CONN.$METHOD(..., '...' % (...), ...) - - pattern: $CONN.$METHOD(..., f'...{$USERINPUT}...', ...) - - pattern-either: - - pattern-inside: | - $CONN = await asyncpg.connect(...) - ... - - pattern-inside: | - async with asyncpg.create_pool(...) as $CONN: - ... - - pattern-inside: | - async with $POOL.acquire(...) as $CONN: - ... - - pattern-inside: | - $CONN = await $POOL.acquire(...) - ... - - pattern-inside: | - def $FUNCNAME(..., $CONN: Connection, ...): - ... - - pattern-inside: | - def $FUNCNAME(..., $CONN: asyncpg.Connection, ...): - ... - - pattern-not: $CONN.$METHOD(..., "..." + "...", ...) - - pattern-not: $CONN.$METHOD(..., '...'.format(), ...) - - pattern-not: $CONN.$METHOD(..., '...'%(), ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(fetch|fetchrow|fetchval|execute|executemany|prepare|cursor|copyfromquery)$ - severity: WARNING - - id: python.lang.security.audit.sqli.pg8000-sqli.pg8000-sqli - languages: - - python - message: 'Detected string concatenation with a non-literal variable in a pg8000 Python SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can create parameterized queries like so: ''conn.run("SELECT :value FROM table", value=myvalue)''. You can also create prepared statements with ''conn.prepare'': ''conn.prepare("SELECT (:v) FROM table")''' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/tlocke/pg8000 - subcategory: - - audit - technology: - - pg8000 - patterns: - - pattern-either: - - patterns: - - pattern: $CONN.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = '...'.format(...) - ... - - pattern-inside: | - $QUERY = '...' % (...) - ... - - pattern-inside: | - $QUERY = f'...{$USERINPUT}...' - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern-not-inside: | - $QUERY = '...'.format() - ... - - pattern-not-inside: | - $QUERY = '...' % () - ... - - pattern: $CONN.$METHOD(..., $X + $Y, ...) - - pattern: $CONN.$METHOD(..., '...'.format(...), ...) - - pattern: $CONN.$METHOD(..., '...' % (...), ...) - - pattern: $CONN.$METHOD(..., f'...{$USERINPUT}...', ...) - - pattern-either: - - pattern-inside: | - $CONN = pg8000.native.Connection(...) - ... - - pattern-inside: | - $CONN = pg8000.dhapi.connect(...) - ... - - pattern-inside: | - $CONN1 = pg8000.connect(...) - ... - $CONN = $CONN1.cursor(...) - ... - - pattern-inside: | - $CONN = pg8000.connect(...) - ... - - pattern-not: $CONN.$METHOD(..., "..." + "...", ...) - - pattern-not: $CONN.$METHOD(..., '...'.format(), ...) - - pattern-not: $CONN.$METHOD(..., '...'%(), ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(run|execute|executemany|prepare)$ - severity: WARNING - - id: python.lang.security.audit.sqli.psycopg-sqli.psycopg-sqli - languages: - - python - message: 'Detected string concatenation with a non-literal variable in a psycopg2 Python SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use prepared statements by creating a ''sql.SQL'' string. You can also use the pyformat binding style to create parameterized queries. For example: ''cur.execute(SELECT * FROM table WHERE name=%s, user_input)''' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://www.psycopg.org/docs/sql.html - subcategory: - - audit - technology: - - psycopg - patterns: - - pattern-either: - - patterns: - - pattern: $CUR.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = '...'.format(...) - ... - - pattern-inside: | - $QUERY = '...' % (...) - ... - - pattern-inside: | - $QUERY = f'...{$USERINPUT}...' - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern-not-inside: | - $QUERY = '...'.format() - ... - - pattern-not-inside: | - $QUERY = '...' % () - ... - - pattern: $CUR.$METHOD(..., $X + $Y, ...) - - pattern: $CUR.$METHOD(..., '...'.format(...), ...) - - pattern: $CUR.$METHOD(..., '...' % (...), ...) - - pattern: $CUR.$METHOD(..., f'...{$USERINPUT}...', ...) - - pattern-either: - - pattern-inside: | - $CONN = psycopg2.connect(...) - ... - $CUR = $CONN.cursor(...) - ... - - pattern-inside: | - $CONN = psycopg2.connect(...) - ... - with $CONN.cursor(...) as $CUR: - ... - - pattern-not: $CUR.$METHOD(..., "..." + "...", ...) - - pattern-not: $CUR.$METHOD(..., '...'.format(), ...) - - pattern-not: $CUR.$METHOD(..., '...'%(), ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(execute|executemany|mogrify)$ - severity: WARNING - - id: python.lang.security.audit.ssl-wrap-socket-is-deprecated.ssl-wrap-socket-is-deprecated - languages: - - python - message: '''ssl.wrap_socket()'' is deprecated. This function creates an insecure socket without server name indication or hostname matching. Instead, create an SSL context using ''ssl.SSLContext()'' and use that to wrap a socket.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/ssl.html#ssl.wrap_socket - - https://docs.python.org/3/library/ssl.html#ssl.SSLContext.wrap_socket - subcategory: - - vuln - technology: - - python - pattern: ssl.wrap_socket(...) - severity: WARNING - - fix-regex: - regex: (shell\s*=\s*)True - replacement: \1False - id: python.lang.security.audit.subprocess-shell-true.subprocess-shell-true - languages: - - python - message: Found 'subprocess' function '$FUNC' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess - - https://docs.python.org/3/library/subprocess.html - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html - subcategory: - - vuln - technology: - - python - patterns: - - pattern: subprocess.$FUNC(..., shell=True, ...) - - pattern-not: subprocess.$FUNC("...", shell=True, ...) - severity: ERROR - - id: python.lang.security.audit.system-wildcard-detected.system-wildcard-detected - languages: - - python - message: Detected use of the wildcard character in a system call that spawns a shell. This subjects the wildcard to normal shell expansion, which can have unintended consequences if there exist any non-standard file names. Consider a file named '-e sh script.sh' -- this will execute a script when 'rsync' is called. See https://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt for more information. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-155: Improper Neutralization of Wildcards or Matching Symbols' - impact: LOW - likelihood: LOW - owasp: A01:2017 - Injection - references: - - https://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt - source-url-open: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/injection_wildcard.py - subcategory: - - audit - technology: - - python - patterns: - - pattern-either: - - pattern-inside: os.system("...") - - pattern-inside: os.popen("...") - - pattern-inside: os.popen2("...") - - pattern-inside: os.popen3("...") - - pattern-inside: os.popen4("...") - - pattern-inside: subprocess.$W(..., shell=True, ...) - - pattern-regex: (tar|chmod|chown|rsync)(.*?)\* - severity: WARNING - - id: python.lang.security.audit.telnetlib.telnetlib - languages: - - python - message: Telnet does not encrypt communications. Use SSH instead. - metadata: - bandit-code: B312 - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.python.org/3/library/telnetlib.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L208 - subcategory: - - audit - technology: - - python - pattern: telnetlib.$ANYTHING(...) - severity: WARNING - - id: python.lang.security.audit.weak-ssl-version.weak-ssl-version - languages: - - python - message: An insecure SSL version was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use 'ssl.PROTOCOL_TLSv1_2' or higher. - metadata: - asvs: - control_id: 9.1.3 Weak TLS - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v91-client-communications-security-requirements - section: V9 Communications Verification Requirements - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://tools.ietf.org/html/rfc7568 - - https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html - - https://docs.python.org/3/library/ssl.html#ssl.PROTOCOL_TLSv1_2 - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/insecure_ssl_tls.py#L30 - subcategory: - - audit - technology: - - python - pattern-either: - - pattern: ssl.PROTOCOL_SSLv2 - - pattern: ssl.PROTOCOL_SSLv3 - - pattern: ssl.PROTOCOL_TLSv1 - - pattern: ssl.PROTOCOL_TLSv1_1 - - pattern: pyOpenSSL.SSL.SSLv2_METHOD - - pattern: pyOpenSSL.SSL.SSLv23_METHOD - - pattern: pyOpenSSL.SSL.SSLv3_METHOD - - pattern: pyOpenSSL.SSL.TLSv1_METHOD - - pattern: pyOpenSSL.SSL.TLSv1_1_METHOD - severity: WARNING - - id: python.lang.security.dangerous-code-run.dangerous-interactive-code-run - languages: - - python - message: Found user controlled data inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $X = code.InteractiveConsole(...) - ... - - pattern-inside: | - $X = code.InteractiveInterpreter(...) - ... - - pattern-either: - - pattern: | - $X.push($PAYLOAD,...) - - pattern: | - $X.runsource($PAYLOAD,...) - - pattern: | - $X.runcode(code.compile_command($PAYLOAD),...) - - pattern: | - $PL = code.compile_command($PAYLOAD,...) - ... - $X.runcode($PL,...) - - focus-metavariable: $PAYLOAD - - pattern-not: | - $X.push("...",...) - - pattern-not: | - $X.runsource("...",...) - - pattern-not: | - $X.runcode(code.compile_command("..."),...) - - pattern-not: | - $PL = code.compile_command("...",...) - ... - $X.runcode($PL,...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - severity: WARNING - - id: python.lang.security.dangerous-globals-use.dangerous-globals-use - languages: - - python - message: Found non static data as an index to 'globals()'. This is extremely dangerous because it allows an attacker to execute arbitrary code on the system. Refactor your code not to use 'globals()'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-96: Improper Neutralization of Directives in Statically Saved Code (''Static Code Injection'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://github.com/mpirnat/lets-be-bad-guys/blob/d92768fb3ade32956abd53bd6bb06e19d634a084/badguys/vulnerable/views.py#L181-L186 - subcategory: - - audit - technology: - - python - patterns: - - pattern-either: - - pattern: globals().get(...) - - pattern: locals().get(...) - - pattern: globals()[...] - - pattern: locals()[...] - - patterns: - - pattern-either: - - pattern-inside: | - $G = globals() - ... - - pattern-inside: | - $G = locals() - ... - - pattern-either: - - pattern: $G.get(...) - - pattern: $G[...] - - pattern: $FUNC.__globals__[...] - - pattern-not: globals().get("...") - - pattern-not: locals().get("...") - - pattern-not: globals()["..."] - - pattern-not: locals()["..."] - - pattern-not: $G.get("...") - - pattern-not: $G.get["..."] - - pattern-not: $G["..."] - - pattern-not: $FUNC.__globals__["..."] - - pattern-not-inside: globals()[...] = ... - - pattern-not-inside: locals()[...] = ... - - pattern-not-inside: $G[...] = ... - - pattern-not-inside: $FUNC.__globals__[...] = ... - severity: WARNING - - id: python.lang.security.dangerous-os-exec.dangerous-os-exec - languages: - - python - message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-not: os.$METHOD("...", ...) - - pattern: os.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (execl|execle|execlp|execlpe|execv|execve|execvp|execvpe) - - patterns: - - pattern-not: os.$METHOD("...", [$PATH,"...","...",...],...) - - pattern-inside: os.$METHOD($BASH,[$PATH,"-c",$CMD,...],...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (execv|execve|execvp|execvpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-not: os.$METHOD("...", $PATH, "...", "...",...) - - pattern-inside: os.$METHOD($BASH, $PATH, "-c", $CMD,...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (execl|execle|execlp|execlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - severity: ERROR - - id: python.lang.security.dangerous-spawn-process.dangerous-spawn-process - languages: - - python - message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-not: os.$METHOD($MODE, "...", ...) - - pattern-inside: os.$METHOD($MODE, $CMD, ...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) - - patterns: - - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...) - - pattern-inside: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - - patterns: - - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...) - - pattern-inside: os.$METHOD($MODE, $BASH, "-c", $CMD,...) - - pattern: $CMD - - metavariable-regex: - metavariable: $METHOD - regex: (spawnl|spawnle|spawnlp|spawnlpe) - - metavariable-regex: - metavariable: $BASH - regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - - patterns: - - pattern-either: - - pattern: os.environ['$ANYTHING'] - - pattern: os.environ.get('$FOO', ...) - - pattern: os.environb['$ANYTHING'] - - pattern: os.environb.get('$FOO', ...) - - pattern: os.getenv('$ANYTHING', ...) - - pattern: os.getenvb('$ANYTHING', ...) - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: sys.argv[...] - - pattern: sys.orig_argv[...] - - patterns: - - pattern-inside: | - $PARSER = argparse.ArgumentParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-inside: | - $PARSER = optparse.OptionParser(...) - ... - - pattern-inside: | - $ARGS = $PARSER.parse_args() - - pattern: <... $ARGS ...> - - patterns: - - pattern-either: - - pattern-inside: | - $OPTS, $ARGS = getopt.getopt(...) - ... - - pattern-inside: | - $OPTS, $ARGS = getopt.gnu_getopt(...) - ... - - pattern-either: - - patterns: - - pattern-inside: | - for $O, $A in $OPTS: - ... - - pattern: $A - - pattern: $ARGS - severity: ERROR - - id: python.lang.security.dangerous-subinterpreters-run-string.dangerous-subinterpreters-run-string - languages: - - python - message: Found user controlled content in `run_string`. This is dangerous because it allows a malicious actor to run arbitrary Python code. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://bugs.python.org/issue43472 - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern: | - _xxsubinterpreters.run_string($ID, $PAYLOAD, ...) - - pattern-not: | - _xxsubinterpreters.run_string($ID, "...", ...) - - focus-metavariable: $PAYLOAD - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - severity: WARNING - - id: python.lang.security.dangerous-subprocess-use.dangerous-subprocess-use - languages: - - python - message: Detected subprocess function '$FUNC' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.escape()'. - metadata: - asvs: - control_id: 5.3.8 OS Command Injection - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess - - https://docs.python.org/3/library/subprocess.html - - https://docs.python.org/3/library/shlex.html - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-not: subprocess.$FUNC("...", ...) - - pattern-not: subprocess.$FUNC(["...",...], ...) - - pattern-not: subprocess.$FUNC(("...",...), ...) - - pattern-not: subprocess.CalledProcessError(...) - - pattern-not: subprocess.SubprocessError(...) - - pattern: subprocess.$FUNC($CMD, ...) - - patterns: - - pattern-not: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...) - - pattern: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD) - - patterns: - - pattern-not: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...],...) - - pattern-not: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...),...) - - pattern-either: - - pattern: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD], ...) - - pattern: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD), ...) - - patterns: - - pattern-not: subprocess.$FUNC("=~/(python)/","...",...) - - pattern: subprocess.$FUNC("=~/(python)/", $CMD) - - patterns: - - pattern-not: subprocess.$FUNC(["=~/(python)/","...",...],...) - - pattern-not: subprocess.$FUNC(("=~/(python)/","...",...),...) - - pattern-either: - - pattern: subprocess.$FUNC(["=~/(python)/", $CMD],...) - - pattern: subprocess.$FUNC(("=~/(python)/", $CMD),...) - - focus-metavariable: $CMD - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - severity: ERROR - - id: python.lang.security.dangerous-system-call.dangerous-system-call - languages: - - python - message: Found user-controlled data used in a system call. This could allow a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. - metadata: - asvs: - control_id: 5.2.4 Dyanmic Code Execution Features - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements - section: 'V5: Validation, Sanitization and Encoding Verification Requirements' - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-not: os.$W("...", ...) - - pattern-either: - - pattern: os.system(...) - - pattern: getattr(os, "system")(...) - - pattern: __import__("os").system(...) - - pattern: getattr(__import__("os"), "system")(...) - - pattern: | - $X = __import__("os") - ... - $X.system(...) - - pattern: | - $X = __import__("os") - ... - getattr($X, "system")(...) - - pattern: | - $X = getattr(os, "system") - ... - $X(...) - - pattern: | - $X = __import__("os") - ... - $Y = getattr($X, "system") - ... - $Y(...) - - pattern: os.popen(...) - - pattern: os.popen2(...) - - pattern: os.popen3(...) - - pattern: os.popen4(...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - severity: ERROR - - id: python.lang.security.dangerous-testcapi-run-in-subinterp.dangerous-testcapi-run-in-subinterp - languages: - - python - message: Found user controlled content in `run_in_subinterp`. This is dangerous because it allows a malicious actor to run arbitrary Python code. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' - impact: HIGH - likelihood: HIGH - owasp: - - A03:2021 - Injection - references: - - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ - subcategory: - - vuln - technology: - - python - mode: taint - options: - symbolic_propagation: true - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - _testcapi.run_in_subinterp($PAYLOAD, ...) - - pattern: | - test.support.run_in_subinterp($PAYLOAD, ...) - - focus-metavariable: $PAYLOAD - - pattern-not: | - _testcapi.run_in_subinterp("...", ...) - - pattern-not: | - test.support.run_in_subinterp("...", ...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: flask.request.form.get(...) - - pattern: flask.request.form[...] - - pattern: flask.request.args.get(...) - - pattern: flask.request.args[...] - - pattern: flask.request.values.get(...) - - pattern: flask.request.values[...] - - pattern: flask.request.cookies.get(...) - - pattern: flask.request.cookies[...] - - pattern: flask.request.stream - - pattern: flask.request.headers.get(...) - - pattern: flask.request.headers[...] - - pattern: flask.request.data - - pattern: flask.request.full_path - - pattern: flask.request.url - - pattern: flask.request.json - - pattern: flask.request.get_json() - - pattern: flask.request.view_args.get(...) - - pattern: flask.request.view_args[...] - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - focus-metavariable: $ROUTEVAR - - patterns: - - pattern-inside: | - def $FUNC(request, ...): - ... - - pattern-either: - - pattern: request.$PROPERTY.get(...) - - pattern: request.$PROPERTY[...] - - patterns: - - pattern-either: - - pattern-inside: | - @rest_framework.decorators.api_view(...) - def $FUNC($REQ, ...): - ... - - patterns: - - pattern-either: - - pattern-inside: | - class $VIEW(..., rest_framework.views.APIView, ...): - ... - - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" - - pattern-inside: | - def $METHOD(self, $REQ, ...): - ... - - metavariable-regex: - metavariable: $METHOD - regex: (get|post|put|patch|delete|head) - - pattern-either: - - pattern: $REQ.POST.get(...) - - pattern: $REQ.POST[...] - - pattern: $REQ.FILES.get(...) - - pattern: $REQ.FILES[...] - - pattern: $REQ.DATA.get(...) - - pattern: $REQ.DATA[...] - - pattern: $REQ.QUERY_PARAMS.get(...) - - pattern: $REQ.QUERY_PARAMS[...] - - pattern: $REQ.data.get(...) - - pattern: $REQ.data[...] - - pattern: $REQ.query_params.get(...) - - pattern: $REQ.query_params[...] - - pattern: $REQ.content_type - - pattern: $REQ.content_type - - pattern: $REQ.stream - - pattern: $REQ.stream - - patterns: - - pattern-either: - - pattern-inside: | - class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.StreamRequestHandler, ...): - ... - - pattern-inside: | - class $SERVER(..., http.server.DatagramRequestHandler, ...): - ... - - pattern-either: - - pattern: self.requestline - - pattern: self.path - - pattern: self.headers[...] - - pattern: self.headers.get(...) - - pattern: self.rfile - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - severity: WARNING - - id: python.lang.security.deserialization.avoid-jsonpickle.avoid-jsonpickle - languages: - - python - message: Avoid using `jsonpickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data using `json` module. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://github.com/jsonpickle/jsonpickle#jsonpickle - - https://www.exploit-db.com/exploits/49585 - subcategory: - - audit - technology: - - jsonpickle - patterns: - - pattern: | - jsonpickle.decode($PAYLOAD,...) - - pattern-not: | - jsonpickle.decode("...",...) - severity: WARNING - - fix-regex: - count: 1 - regex: unsafe_load - replacement: safe_load - id: python.lang.security.deserialization.avoid-pyyaml-load.avoid-pyyaml-load - languages: - - python - message: Detected a possible YAML deserialization vulnerability. `yaml.unsafe_load`, `yaml.Loader`, `yaml.CLoader`, and `yaml.UnsafeLoader` are all known to be unsafe methods of deserializing YAML. An attacker with control over the YAML input could create special YAML input that allows the attacker to run arbitrary Python code. This would allow the attacker to steal files, download and install malware, or otherwise take over the machine. Use `yaml.safe_load` or `yaml.SafeLoader` instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation - - https://nvd.nist.gov/vuln/detail/CVE-2017-18342 - subcategory: - - audit - technology: - - pyyaml - patterns: - - pattern-inside: | - import yaml - ... - - pattern-not-inside: | - $YAML = ruamel.yaml.YAML(...) - ... - - pattern-either: - - pattern: yaml.unsafe_load(...) - - pattern: yaml.load(..., Loader=yaml.Loader, ...) - - pattern: yaml.load(..., Loader=yaml.UnsafeLoader, ...) - - pattern: yaml.load(..., Loader=yaml.CLoader, ...) - - pattern: yaml.load_all(..., Loader=yaml.Loader, ...) - - pattern: yaml.load_all(..., Loader=yaml.UnsafeLoader, ...) - - pattern: yaml.load_all(..., Loader=yaml.CLoader, ...) - severity: ERROR - - id: python.lang.security.deserialization.avoid-unsafe-ruamel.avoid-unsafe-ruamel - languages: - - python - message: Avoid using unsafe `ruamel.yaml.YAML()`. `ruamel.yaml.YAML` can create arbitrary Python objects. A malicious actor could exploit this to run arbitrary code. Use `YAML(typ='rt')` or `YAML(typ='safe')` instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://yaml.readthedocs.io/en/latest/basicuse.html?highlight=typ - subcategory: - - audit - technology: - - ruamel.yaml - pattern-either: - - pattern: ruamel.yaml.YAML(..., typ='unsafe', ...) - - pattern: ruamel.yaml.YAML(..., typ='base', ...) - severity: ERROR - - id: python.lang.security.deserialization.pickle.avoid-pickle - languages: - - python - message: Avoid using `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.python.org/3/library/pickle.html - subcategory: - - audit - technology: - - python - patterns: - - pattern-either: - - pattern: pickle.$FUNC(...) - - pattern: _pickle.$FUNC(...) - - pattern-not: pickle.$FUNC("...") - - pattern-not: _pickle.$FUNC("...") - severity: WARNING - - id: python.lang.security.deserialization.pickle.avoid-cpickle - languages: - - python - message: Avoid using `cPickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.python.org/3/library/pickle.html - subcategory: - - audit - technology: - - python - patterns: - - pattern: cPickle.$FUNC(...) - - pattern-not: cPickle.$FUNC("...") - severity: WARNING - - id: python.lang.security.deserialization.pickle.avoid-dill - languages: - - python - message: Avoid using `dill`, which uses `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.python.org/3/library/pickle.html - subcategory: - - audit - technology: - - python - patterns: - - pattern: dill.$FUNC(...) - - pattern-not: dill.$FUNC("...") - severity: WARNING - - id: python.lang.security.deserialization.pickle.avoid-shelve - languages: - - python - message: Avoid using `shelve`, which uses `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://docs.python.org/3/library/pickle.html - subcategory: - - audit - technology: - - python - pattern: shelve.$FUNC(...) - severity: WARNING - - id: python.lang.security.insecure-hash-algorithms-md5.insecure-hash-algorithm-md5 - languages: - - python - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. - metadata: - asvs: - control_id: 6.2.2 Insecure Custom Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - bandit-code: B303 - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 - subcategory: - - vuln - technology: - - python - patterns: - - pattern: hashlib.md5(...) - - pattern-not: hashlib.md5(..., usedforsecurity=False, ...) - severity: WARNING - - fix-regex: - regex: sha1 - replacement: sha256 - id: python.lang.security.insecure-hash-algorithms.insecure-hash-algorithm-sha1 - languages: - - python - message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. - metadata: - asvs: - control_id: 6.2.2 Insecure Custom Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - bandit-code: B303 - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 - subcategory: - - vuln - technology: - - python - pattern: hashlib.sha1(...) - severity: WARNING - - id: python.lang.security.insecure-hash-function.insecure-hash-function - languages: - - python - message: Detected use of an insecure MD4 or MD5 hash function. These functions have known vulnerabilities and are considered deprecated. Consider using 'SHA256' or a similar function instead. - metadata: - asvs: - control_id: 6.2.2 Insecure Custom Algorithm - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms - section: V6 Stored Cryptography Verification Requirements - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://tools.ietf.org/html/rfc6151 - - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/hashlib_new_insecure_functions.py - subcategory: - - audit - technology: - - python - pattern-either: - - pattern: hashlib.new("=~/[M|m][D|d][4|5]/", ...) - - pattern: hashlib.new(..., name="=~/[M|m][D|d][4|5]/", ...) - severity: WARNING - - fix-regex: - regex: _create_unverified_context - replacement: create_default_context - id: python.lang.security.unverified-ssl-context.unverified-ssl-context - languages: - - python - message: Unverified SSL context detected. This will permit insecure connections without verifying SSL certificates. Use 'ssl.create_default_context' instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures - references: - - https://docs.python.org/3/library/ssl.html#ssl-security - - https://docs.python.org/3/library/http.client.html#http.client.HTTPSConnection - subcategory: - - audit - technology: - - python - patterns: - - pattern-either: - - pattern: ssl._create_unverified_context(...) - - pattern: ssl._create_default_https_context = ssl._create_unverified_context - severity: ERROR - - fix: defusedxml.etree.ElementTree.parse($...ARGS) - id: python.lang.security.use-defused-xml-parse.use-defused-xml-parse - languages: - - python - message: The native Python `xml` library is vulnerable to XML External Entity (XXE) attacks. These attacks can leak confidential data and "XML bombs" can cause denial of service. Do not use this library to parse untrusted input. Instead the Python documentation recommends using `defusedxml`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://docs.python.org/3/library/xml.html - - https://github.com/tiran/defusedxml - - https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing - subcategory: - - vuln - technology: - - python - patterns: - - pattern: xml.etree.ElementTree.parse($...ARGS) - - pattern-not: xml.etree.ElementTree.parse("...") - severity: ERROR - - id: python.lang.security.use-defused-xml.use-defused-xml - languages: - - python - message: The Python documentation recommends using `defusedxml` instead of `xml` because the native Python `xml` library is vulnerable to XML External Entity (XXE) attacks. These attacks can leak confidential data and "XML bombs" can cause denial of service. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://docs.python.org/3/library/xml.html - - https://github.com/tiran/defusedxml - - https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing - subcategory: - - audit - technology: - - python - pattern: import xml - severity: ERROR - - id: python.lang.security.use-defused-xmlrpc.use-defused-xmlrpc - languages: - - python - message: Detected use of xmlrpc. xmlrpc is not inherently safe from vulnerabilities. Use defusedxml.xmlrpc instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-776: Improper Restriction of Recursive Entity References in DTDs (''XML Entity Expansion'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://pypi.org/project/defusedxml/ - - https://docs.python.org/3/library/xml.html#xml-vulnerabilities - source-rule-url: https://github.com/PyCQA/bandit/blob/07f84cb5f5e7c1055e6feaa0fe93afa471de0ac3/bandit/blacklists/imports.py#L160 - subcategory: - - audit - technology: - - python - pattern-either: - - pattern: import xmlrpclib - - pattern: import SimpleXMLRPCServer - - pattern: import xmlrpc - severity: ERROR - - fix-regex: - regex: csv - replacement: defusedcsv - id: python.lang.security.use-defusedcsv.use-defusedcsv - languages: - - python - message: Detected the generation of a CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-1236: Improper Neutralization of Formula Elements in a CSV File' - impact: LOW - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/raphaelm/defusedcsv - - https://owasp.org/www-community/attacks/CSV_Injection - - https://web.archive.org/web/20220516052229/https://www.contextis.com/us/blog/comma-separated-vulnerabilities - subcategory: - - audit - technology: - - python - patterns: - - pattern: csv.writer(...) - - pattern-not: defusedcsv.writer(...) - severity: INFO - - id: python.pycryptodome.security.insecure-cipher-algorithm-blowfish.insecure-cipher-algorithm-blowfish - languages: - - python - message: Detected Blowfish cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. - metadata: - bandit-code: B304 - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://stackoverflow.com/questions/1135186/whats-wrong-with-xor-encryption - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 - subcategory: - - vuln - technology: - - pycryptodome - pattern-either: - - pattern: Cryptodome.Cipher.Blowfish.new(...) - - pattern: Crypto.Cipher.Blowfish.new(...) - severity: WARNING - - id: python.pycryptodome.security.insecure-cipher-algorithm-des.insecure-cipher-algorithm-des - languages: - - python - message: Detected DES cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. - metadata: - bandit-code: B304 - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://cwe.mitre.org/data/definitions/326.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 - subcategory: - - vuln - technology: - - pycryptodome - pattern-either: - - pattern: Cryptodome.Cipher.DES.new(...) - - pattern: Crypto.Cipher.DES.new(...) - severity: WARNING - - id: python.pycryptodome.security.insecure-cipher-algorithm-rc2.insecure-cipher-algorithm-rc2 - languages: - - python - message: Detected RC2 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. - metadata: - bandit-code: B304 - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://cwe.mitre.org/data/definitions/326.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 - subcategory: - - vuln - technology: - - pycryptodome - pattern-either: - - pattern: Cryptodome.Cipher.ARC2.new(...) - - pattern: Crypto.Cipher.ARC2.new(...) - severity: WARNING - - id: python.pycryptodome.security.insecure-cipher-algorithm-rc4.insecure-cipher-algorithm-rc4 - languages: - - python - message: Detected ARC4 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. - metadata: - bandit-code: B304 - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://cwe.mitre.org/data/definitions/326.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 - subcategory: - - vuln - technology: - - pycryptodome - pattern-either: - - pattern: Cryptodome.Cipher.ARC4.new(...) - - pattern: Crypto.Cipher.ARC4.new(...) - severity: WARNING - - id: python.pycryptodome.security.insecure-cipher-algorithm.insecure-cipher-algorithm-xor - languages: - - python - message: Detected XOR cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. - metadata: - bandit-code: B304 - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://stackoverflow.com/questions/1135186/whats-wrong-with-xor-encryption - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 - subcategory: - - vuln - technology: - - pycryptodome - pattern-either: - - pattern: Cryptodome.Cipher.XOR.new(...) - - pattern: Crypto.Cipher.XOR.new(...) - severity: WARNING - - id: python.pycryptodome.security.insecure-hash-algorithm-md2.insecure-hash-algorithm-md2 - languages: - - python - message: Detected MD2 hash algorithm which is considered insecure. MD2 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 - subcategory: - - vuln - technology: - - pycryptodome - pattern-either: - - pattern: Crypto.Hash.MD2.new(...) - - pattern: Cryptodome.Hash.MD2.new (...) - severity: WARNING - - id: python.pycryptodome.security.insecure-hash-algorithm-md4.insecure-hash-algorithm-md4 - languages: - - python - message: Detected MD4 hash algorithm which is considered insecure. MD4 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 - subcategory: - - vuln - technology: - - pycryptodome - pattern-either: - - pattern: Crypto.Hash.MD4.new(...) - - pattern: Cryptodome.Hash.MD4.new (...) - severity: WARNING - - id: python.pycryptodome.security.insecure-hash-algorithm-md5.insecure-hash-algorithm-md5 - languages: - - python - message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 - subcategory: - - vuln - technology: - - pycryptodome - pattern-either: - - pattern: Crypto.Hash.MD5.new(...) - - pattern: Cryptodome.Hash.MD5.new (...) - severity: WARNING - - id: python.pycryptodome.security.insecure-hash-algorithm.insecure-hash-algorithm-sha1 - languages: - - python - message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html - - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability - - http://2012.sharcs.org/slides/stevens.pdf - - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html - source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 - subcategory: - - vuln - technology: - - pycryptodome - pattern-either: - - pattern: Crypto.Hash.SHA.new(...) - - pattern: Cryptodome.Hash.SHA.new (...) - severity: WARNING - - id: python.pycryptodome.security.insufficient-dsa-key-size.insufficient-dsa-key-size - languages: - - python - message: Detected an insufficient key size for DSA. NIST recommends a key size of 2048 or higher. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py - subcategory: - - vuln - technology: - - pycryptodome - patterns: - - pattern-either: - - pattern: Crypto.PublicKey.DSA.generate(..., bits=$SIZE, ...) - - pattern: Crypto.PublicKey.DSA.generate($SIZE, ...) - - pattern: Cryptodome.PublicKey.DSA.generate(..., bits=$SIZE, ...) - - pattern: Cryptodome.PublicKey.DSA.generate($SIZE, ...) - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - severity: WARNING - - id: python.pycryptodome.security.insufficient-rsa-key-size.insufficient-rsa-key-size - languages: - - python - message: Detected an insufficient key size for RSA. NIST recommends a key size of 2048 or higher. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf - source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py - subcategory: - - vuln - technology: - - pycryptodome - patterns: - - pattern-either: - - pattern: Crypto.PublicKey.RSA.generate(..., bits=$SIZE, ...) - - pattern: Crypto.PublicKey.RSA.generate($SIZE, ...) - - pattern: Cryptodome.PublicKey.RSA.generate(..., bits=$SIZE, ...) - - pattern: Cryptodome.PublicKey.RSA.generate($SIZE, ...) - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - severity: WARNING - - id: python.pycryptodome.security.mode-without-authentication.crypto-mode-without-authentication - languages: - - python - message: 'An encryption mode of operation is being used without proper message authentication. This can potentially result in the encrypted content to be decrypted by an attacker. Consider instead use an AEAD mode of operation like GCM. ' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - cryptography - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - AES.new(..., $PYCRYPTODOME_MODE) - - pattern-not-inside: | - AES.new(..., $PYCRYPTODOME_MODE) - ... - HMAC.new - - metavariable-pattern: - metavariable: $PYCRYPTODOME_MODE - patterns: - - pattern-either: - - pattern: AES.MODE_CBC - - pattern: AES.MODE_CTR - - pattern: AES.MODE_CFB - - pattern: AES.MODE_OFB - severity: ERROR - - fix-regex: - regex: MONGODB-CR - replacement: SCRAM-SHA-256 - id: python.pymongo.security.mongodb.mongo-client-bad-auth - languages: - - python - message: Warning MONGODB-CR was deprecated with the release of MongoDB 3.6 and is no longer supported by MongoDB 4.0 (see https://api.mongodb.com/python/current/examples/authentication.html for details). - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-477: Use of Obsolete Function' - impact: LOW - likelihood: LOW - references: - - https://cwe.mitre.org/data/definitions/477.html - subcategory: - - vuln - technology: - - pymongo - pattern: | - pymongo.MongoClient(..., authMechanism='MONGODB-CR') - severity: WARNING - - fix: | - $...PARAMS, httponly=True - id: python.pyramid.audit.authtkt-cookie-httponly-unsafe-default.pyramid-authtkt-cookie-httponly-unsafe-default - languages: - - python - message: Found a Pyramid Authentication Ticket cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern: pyramid.authentication.$FUNC($...PARAMS) - - metavariable-pattern: - metavariable: $FUNC - pattern-either: - - pattern: AuthTktCookieHelper - - pattern: AuthTktAuthenticationPolicy - - pattern-not: pyramid.authentication.$FUNC(..., httponly=$HTTPONLY, ...) - - pattern-not: pyramid.authentication.$FUNC(..., **$PARAMS, ...) - - focus-metavariable: $...PARAMS - severity: WARNING - - fix: | - True - id: python.pyramid.audit.authtkt-cookie-httponly-unsafe-value.pyramid-authtkt-cookie-httponly-unsafe-value - languages: - - python - message: Found a Pyramid Authentication Ticket cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - patterns: - - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktCookieHelper(..., httponly=$HTTPONLY, ...) - - patterns: - - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., httponly=$HTTPONLY, ...) - - pattern: $HTTPONLY - - metavariable-pattern: - metavariable: $HTTPONLY - pattern: | - False - severity: WARNING - - fix: | - 'Lax' - id: python.pyramid.audit.authtkt-cookie-samesite.pyramid-authtkt-cookie-samesite - languages: - - python - message: Found a Pyramid Authentication Ticket without the samesite option correctly set. Pyramid cookies should be handled securely by setting samesite='Lax'. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - pattern: pyramid.authentication.AuthTktCookieHelper(..., samesite=$SAMESITE, ...) - - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., samesite=$SAMESITE, ...) - - pattern: $SAMESITE - - metavariable-regex: - metavariable: $SAMESITE - regex: (?!'Lax') - severity: WARNING - - fix-regex: - regex: (.*)\) - replacement: \1, secure=True) - id: python.pyramid.audit.authtkt-cookie-secure-unsafe-default.pyramid-authtkt-cookie-secure-unsafe-default - languages: - - python - message: Found a Pyramid Authentication Ticket cookie using an unsafe default for the secure option. Pyramid cookies should be handled securely by setting secure=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - patterns: - - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., secure=$SECURE, ...) - - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktCookieHelper(...) - - patterns: - - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., secure=$SECURE, ...) - - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(...) - severity: WARNING - - fix: | - True - id: python.pyramid.audit.authtkt-cookie-secure-unsafe-value.pyramid-authtkt-cookie-secure-unsafe-value - languages: - - python - message: Found a Pyramid Authentication Ticket cookie without the secure option correctly set. Pyramid cookies should be handled securely by setting secure=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - patterns: - - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktCookieHelper(..., secure=$SECURE, ...) - - patterns: - - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) - - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., secure=$SECURE, ...) - - pattern: $SECURE - - metavariable-pattern: - metavariable: $SECURE - pattern: | - False - severity: WARNING - - fix: | - True - id: python.pyramid.audit.csrf-check-disabled.pyramid-csrf-check-disabled - languages: - - python - message: CSRF protection is disabled for this view. This is a security risk. - metadata: - asvs: - control_id: 4.2.2 CSRF - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V4-Access-Control.md#v42-operation-level-access-control - section: V4 Access Control - version: "4" - category: security - confidence: LOW - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - pyramid - patterns: - - pattern-inside: | - from pyramid.view import view_config - ... - @view_config(..., require_csrf=$REQUIRE_CSRF, ...) - def $VIEW(...): - ... - - pattern: $REQUIRE_CSRF - - metavariable-comparison: - comparison: $REQUIRE_CSRF == False - metavariable: $REQUIRE_CSRF - severity: WARNING - - fix: | - True - id: python.pyramid.audit.csrf-origin-check-disabled-globally.pyramid-csrf-origin-check-disabled-globally - languages: - - python - message: Automatic check of the referrer for cross-site request forgery tokens has been explicitly disabled globally, which might leave views unprotected when an unsafe CSRF storage policy is used. Use 'pyramid.config.Configurator.set_default_csrf_options(check_origin=True)' to turn the automatic check for all unsafe methods (per RFC2616). - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-inside: | - $CONFIG.set_default_csrf_options(..., check_origin=$CHECK_ORIGIN, ...) - - pattern: $CHECK_ORIGIN - - metavariable-comparison: - comparison: $CHECK_ORIGIN == False - metavariable: $CHECK_ORIGIN - severity: ERROR - - fix: | - True - id: python.pyramid.audit.csrf-origin-check-disabled.pyramid-csrf-origin-check-disabled - languages: - - python - message: Origin check for the CSRF token is disabled for this view. This might represent a security risk if the CSRF storage policy is not known to be secure. - metadata: - asvs: - control_id: 4.2.2 CSRF - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V4-Access-Control.md#v42-operation-level-access-control - section: V4 Access Control - version: "4" - category: security - confidence: MEDIUM - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-inside: | - from pyramid.view import view_config - ... - @view_config(..., check_origin=$CHECK_ORIGIN, ...) - def $VIEW(...): - ... - - pattern: $CHECK_ORIGIN - - metavariable-comparison: - comparison: $CHECK_ORIGIN == False - metavariable: $CHECK_ORIGIN - severity: WARNING - - fix-regex: - regex: (.*)\) - replacement: \1, httponly=True) - id: python.pyramid.audit.set-cookie-httponly-unsafe-default.pyramid-set-cookie-httponly-unsafe-default - languages: - - python - message: Found a Pyramid cookie using an unsafe default for the httponly option. Pyramid cookies should be handled securely by setting httponly=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., httponly=$HTTPONLY, ...) - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(...) - severity: WARNING - - fix: | - True - id: python.pyramid.audit.set-cookie-httponly-unsafe-value.pyramid-set-cookie-httponly-unsafe-value - languages: - - python - message: Found a Pyramid cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/www-community/controls/SecureCookieAttribute - - https://owasp.org/www-community/HttpOnly - - https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#httponly-attribute - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(..., httponly=$HTTPONLY, ...) - - pattern: $HTTPONLY - - metavariable-pattern: - metavariable: $HTTPONLY - pattern: | - False - severity: WARNING - - fix-regex: - regex: (.*)\) - replacement: \1, samesite='Lax') - id: python.pyramid.audit.set-cookie-samesite-unsafe-default.pyramid-set-cookie-samesite-unsafe-default - languages: - - python - message: Found a Pyramid cookie using an unsafe value for the samesite option. Pyramid cookies should be handled securely by setting samesite='Lax' in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., samesite=$SAMESITE, ...) - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(...) - severity: WARNING - - fix: | - 'Lax' - id: python.pyramid.audit.set-cookie-samesite-unsafe-value.pyramid-set-cookie-samesite-unsafe-value - languages: - - python - message: Found a Pyramid cookie without the samesite option correctly set. Pyramid cookies should be handled securely by setting samesite='Lax' in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(..., samesite=$SAMESITE, ...) - - pattern: $SAMESITE - - metavariable-regex: - metavariable: $SAMESITE - regex: (?!'Lax') - severity: WARNING - - fix-regex: - regex: (.*)\) - replacement: \1, secure=True) - id: python.pyramid.audit.set-cookie-secure-unsafe-default.pyramid-set-cookie-secure-unsafe-default - languages: - - python - message: Found a Pyramid cookie using an unsafe default for the secure option. Pyramid cookies should be handled securely by setting secure=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., secure=$SECURE, ...) - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(...) - severity: WARNING - - fix: | - True - id: python.pyramid.audit.set-cookie-secure-unsafe-value.pyramid-set-cookie-secure-unsafe-value - languages: - - python - message: Found a Pyramid cookie without the secure option correctly set. Pyramid cookies should be handled securely by setting secure=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-either: - - pattern-inside: | - @pyramid.view.view_config(...) - def $VIEW($REQUEST): - ... - $RESPONSE = $REQUEST.response - ... - - pattern-inside: | - def $VIEW(...): - ... - $RESPONSE = pyramid.httpexceptions.HTTPFound(...) - ... - - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) - - pattern: $RESPONSE.set_cookie(..., secure=$SECURE, ...) - - pattern: $SECURE - - metavariable-pattern: - metavariable: $SECURE - pattern: | - False - severity: WARNING - - fix: | - True - id: python.pyramid.security.csrf-check-disabled-globally.pyramid-csrf-check-disabled-globally - languages: - - python - message: Automatic check of cross-site request forgery tokens has been explicitly disabled globally, which might leave views unprotected. Use 'pyramid.config.Configurator.set_default_csrf_options(require_csrf=True)' to turn the automatic check for all unsafe methods (per RFC2616). - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - pyramid - patterns: - - pattern-inside: | - $CONFIG.set_default_csrf_options(..., require_csrf=$REQUIRE_CSRF, ...) - - pattern: $REQUIRE_CSRF - - metavariable-comparison: - comparison: $REQUIRE_CSRF == False - metavariable: $REQUIRE_CSRF - severity: ERROR - - id: python.pyramid.security.direct-use-of-response.pyramid-direct-use-of-response - languages: - - python - message: Detected data rendered directly to the end user via 'Response'. This bypasses Pyramid's built-in cross-site scripting (XSS) defenses and could result in an XSS vulnerability. Use Pyramid's template engines to safely render HTML. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - pyramid - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - pyramid.request.Response.text($SINK) - - pattern: | - pyramid.request.Response($SINK) - - pattern: | - $REQ.response.body = $SINK - - pattern: | - $REQ.response.text = $SINK - - pattern: | - $REQ.response.ubody = $SINK - - pattern: | - $REQ.response.unicode_body = $SINK - - pattern: $SINK - pattern-sources: - - patterns: - - pattern-inside: | - @pyramid.view.view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - severity: ERROR - - fix-regex: - regex: format - replacement: bindparams - id: python.pyramid.security.sqlalchemy-sql-injection.pyramid-sqlalchemy-sql-injection - languages: - - python - message: Distinct, Having, Group_by, Order_by, and Filter in SQLAlchemy can cause sql injections if the developer inputs raw SQL into the before-mentioned clauses. This pattern captures relevant cases in which the developer inputs raw SQL into the distinct, having, group_by, order_by or filter clauses and injects user-input into the raw SQL with any function besides "bindparams". Use bindParams to securely bind user-input to SQL statements. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.sqlalchemy.org/en/14/tutorial/data_select.html#tutorial-selecting-data - subcategory: - - vuln - technology: - - pyramid - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - $QUERY = $REQ.dbsession.query(...) - ... - - pattern-either: - - pattern: | - $QUERY.$SQLFUNC("...".$FORMATFUNC(..., $SINK, ...)) - - pattern: | - $QUERY.join(...).$SQLFUNC("...".$FORMATFUNC(..., $SINK, ...)) - - pattern: $SINK - - metavariable-regex: - metavariable: $SQLFUNC - regex: (group_by|order_by|distinct|having|filter) - - metavariable-regex: - metavariable: $FORMATFUNC - regex: (?!bindparams) - pattern-sources: - - patterns: - - pattern-inside: | - from pyramid.view import view_config - ... - @view_config( ... ) - def $VIEW($REQ): - ... - - pattern: $REQ.$ANYTHING - - pattern-not: $REQ.dbsession - severity: ERROR - - id: python.requests.best-practice.use-raise-for-status.use-raise-for-status - languages: - - python - message: There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a 500 error while you're only checking for a 401. - metadata: - category: best-practice - references: - - https://requests.readthedocs.io/en/master/api/#requests.Response.raise_for_status - technology: - - requests - patterns: - - pattern-either: - - pattern: requests.request(...) - - pattern: requests.get(...) - - pattern: requests.post(...) - - pattern: requests.put(...) - - pattern: requests.delete(...) - - pattern: requests.head(...) - - pattern: requests.patch(...) - - pattern-not-inside: | - $RESP = requests.$METHOD(...) - $RESP.raise_for_status(...) - - pattern-not-inside: | - requests.$METHOD(...).raise_for_status(...) - - pattern-not-inside: | - $RESP = requests.$METHOD(...) - if $RESP.status_code == ...: - ... - - pattern-not-inside: | - $RESP = requests.$METHOD(...) - if $RESP.status_code != ...: - ... - - pattern-not-inside: | - $RESP = requests.$METHOD(...) - ... - if $RESP.ok: - ... - - pattern-not-inside: | - $RESP = requests.$METHOD(...) - ... - if not $RESP.ok: - ... - - pattern-not-inside: | - with ...: - ... - $RESP = requests.$METHOD(...) - ... - $RESP.raise_for_status(...) - - pattern-not-inside: | - with ... as ...: - ... - $RESP = requests.$METHOD(...) - ... - $RESP.raise_for_status(...) - severity: WARNING - - id: python.requests.best-practice.use-request-json-shortcut.python.requests.best-practice.use-request-json-shortcut - languages: - - python - message: The requests library has a convenient shortcut for sending JSON requests, which lets you stop worrying about serializing the body yourself. To use it, replace `body=json.dumps(...)` with `json=...`. - metadata: - category: best-practice - references: - - https://requests.readthedocs.io/en/stable/user/quickstart/#more-complicated-post-requests - technology: - - requests - patterns: - - pattern-inside: import json; ... - - pattern-inside: import requests; ... - - pattern: requests.$METHOD(..., body=json.dumps($BODY), ...) - severity: WARNING - - fix: $RESP.json() - id: python.requests.best-practice.use-response-json-shortcut.python.requests.best-practice.use-response-json-shortcut - languages: - - python - message: The requests library has a convenient shortcut for reading JSON responses, which lets you stop worrying about deserializing the response yourself. - metadata: - category: best-practice - references: - - https://requests.readthedocs.io/en/stable/user/quickstart/#json-response-content - technology: - - requests - patterns: - - pattern-inside: import json; ... - - pattern-inside: import requests; ... - - pattern-inside: $RESP = requests.$METHOD(...); ... - - pattern: json.loads($RESP.text) - severity: WARNING - - fix-regex: - regex: (.*)\)$ - replacement: \1, timeout=30) - id: python.requests.best-practice.use-timeout.use-timeout - languages: - - python - message: Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a timeout for all 'requests'. - metadata: - category: best-practice - references: - - https://docs.python-requests.org/en/latest/user/advanced/?highlight=timeout#timeouts - - https://requests.readthedocs.io/en/latest/user/quickstart/#timeouts - technology: - - requests - pattern-either: - - patterns: - - pattern-not: requests.$W(..., timeout=$N, ...) - - pattern-not: requests.$W(..., **$KWARGS) - - pattern-either: - - pattern: requests.request(...) - - pattern: requests.get(...) - - pattern: requests.post(...) - - pattern: requests.put(...) - - pattern: requests.delete(...) - - pattern: requests.head(...) - - pattern: requests.patch(...) - - patterns: - - pattern-inside: | - $SESSION = requests.Session(...) - ... - - pattern-not: | - $SESSION.$W(..., timeout=$N, ...) - - pattern-not: | - $SESSION.$W(..., **$KWARGS) - - pattern-either: - - pattern: $SESSION.get(...) - - pattern: $SESSION.post(...) - - pattern: $SESSION.put(...) - - pattern: $SESSION.delete(...) - - pattern: $SESSION.head(...) - - pattern: $SESSION.patch(...) - severity: WARNING - - fix-regex: - regex: verify(\s)*=(\s)*False - replacement: verify=True - id: python.requests.security.disabled-cert-validation.disabled-cert-validation - languages: - - python - message: Certificate verification has been explicitly disabled. This permits insecure connections to insecure servers. Re-enable certification validation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures - references: - - https://stackoverflow.com/questions/41740361/is-it-safe-to-disable-ssl-certificate-verification-in-pythonss-requests-lib - subcategory: - - audit - technology: - - requests - pattern-either: - - pattern: requests.put(..., verify=False, ...) - - pattern: requests.patch(..., verify=False, ...) - - pattern: requests.delete(..., verify=False, ...) - - pattern: requests.head(..., verify=False, ...) - - pattern: requests.options(..., verify=False, ...) - - pattern: requests.request(..., verify=False, ...) - - pattern: requests.get(..., verify=False, ...) - - pattern: requests.post(..., verify=False, ...) - severity: ERROR - - fix-regex: - count: 1 - regex: http:\/\/ - replacement: https:// - id: python.requests.security.no-auth-over-http.no-auth-over-http - languages: - - python - message: Authentication detected over HTTP. HTTP does not provide any encryption or protection for these authentication credentials. This may expose these credentials to unauthorized parties. Use 'https://' instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-523: Unprotected Transport of Credentials' - impact: LOW - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A02:2021 - Cryptographic Failures - references: - - https://semgrep.dev/blog/2020/bento-check-no-auth-over-http/ - - https://bento.dev/checks/requests/no-auth-over-http/ - source-rule-url: https://pypi.org/project/flake8-flask/ - subcategory: - - audit - technology: - - requests - pattern-either: - - pattern: requests.$W("=~/http:\/\/.*/", ..., auth=$X, ...) - - pattern: | - $URL = "=~/http:\/\/.../" - ... - requests.$W($URL, ..., auth=$X, ...) - severity: ERROR - - id: python.sh.security.string-concat.string-concat - languages: - - python - message: Detected string concatenation or formatting in a call to a command via 'sh'. This could be a command injection vulnerability if the data is user-controlled. Instead, use a list and append the argument. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - sh - pattern-either: - - pattern: sh.$BIN($X + $Y) - - pattern: sh.$BIN($X.format(...)) - - pattern: sh.$BIN(f"...{...}...") - severity: ERROR - - id: python.sqlalchemy.correctness.bad-operator-in-filter.bad-operator-in-filter - languages: - - python - message: Only comparison operators should be used inside SQLAlchemy filter expressions. Use `==` instead of `is`, `!=` instead of `is not`, `sqlalchemy.and_` instead of `and`, `sqlalchemy.or_` instead of `or`, `sqlalchemy.not_` instead of `not`, and `sqlalchemy.in_` instead of `in_`. - metadata: - category: correctness - references: - - https://docs.sqlalchemy.org/en/13/orm/tutorial.html#common-filter-operators - technology: - - sqlalchemy - patterns: - - pattern-inside: | - def $ANY(...): - ... - $MODEL.query - - pattern-inside: | - $TARGET.filter(...) - - pattern-either: - - pattern: not $A - - pattern: $A is $B - - pattern: $A is not $B - - pattern: $A and $B - - pattern: $A or $B - - pattern: $A in $B - - pattern: $A not in $B - severity: WARNING - - id: python.sqlalchemy.correctness.delete-where.delete-where-no-execute - languages: - - python - message: .delete().where(...) results in a no-op in SQLAlchemy unless the command is executed, use .filter(...).delete() instead. - metadata: - category: correctness - technology: - - sqlalchemy - patterns: - - pattern: $X.delete().where(...) - - pattern-not-inside: $X.delete().where(...).execute() - - pattern-not-inside: $C.execute(...) - severity: ERROR - - id: python.sqlalchemy.performance.performance-improvements.len-all-count - languages: - - python - message: Using QUERY.count() instead of len(QUERY.all()) sends less data to the client since the SQLAlchemy method is performed server-side. - metadata: - category: performance - technology: - - sqlalchemy - pattern: len($X.all()) - severity: WARNING - - id: python.sqlalchemy.performance.performance-improvements.batch-import - languages: - - python - message: Rather than adding one element at a time, consider batch loading to improve performance. - metadata: - category: performance - technology: - - sqlalchemy - pattern: | - for $X in $Y: - db.session.add($Z) - severity: WARNING - - id: python.sqlalchemy.security.audit.avoid-sqlalchemy-text.avoid-sqlalchemy-text - languages: - - python - message: sqlalchemy.text passes the constructed SQL statement to the database mostly unchanged. This means that the usual SQL injection protections are not applied and this function is vulnerable to SQL injection if user input can reach here. Use normal SQLAlchemy operators (such as or_, and_, etc.) to construct SQL. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql - subcategory: - - audit - technology: - - sqlalchemy - mode: taint - pattern-sinks: - - pattern: | - sqlalchemy.text(...) - pattern-sources: - - patterns: - - pattern: | - $X + $Y - - metavariable-type: - metavariable: $X - type: string - - patterns: - - pattern: | - $X + $Y - - metavariable-type: - metavariable: $Y - type: string - - patterns: - - pattern: | - f"..." - - patterns: - - pattern: | - $X.format(...) - - metavariable-type: - metavariable: $X - type: string - - patterns: - - pattern: | - $X % $Y - - metavariable-type: - metavariable: $X - type: string - severity: ERROR - - id: python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query - languages: - - python - message: 'Avoiding SQL string concatenation: untrusted input concatenated with raw SQL query can result in SQL Injection. In order to execute raw query safely, prepared statement should be used. SQLAlchemy provides TextualSQL to easily used prepared statement with named parameters. For complex SQL composition, use SQL Expression Language or Schema Definition Language. In most cases, SQLAlchemy ORM will be a better option.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql - - https://www.tutorialspoint.com/sqlalchemy/sqlalchemy_quick_guide.htm - - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-more-specific-text-with-table-expression-literal-column-and-expression-column - subcategory: - - audit - technology: - - sqlalchemy - pattern-either: - - pattern: | - $CONNECTION.execute( $SQL + ..., ... ) - - pattern: | - $CONNECTION.execute( $SQL % (...), ...) - - pattern: | - $CONNECTION.execute( $SQL.format(...), ... ) - - pattern: | - $CONNECTION.execute(f"...{...}...", ...) - - patterns: - - pattern-inside: | - $QUERY = $SQL + ... - ... - - pattern: | - $CONNECTION.execute($QUERY, ...) - - patterns: - - pattern-inside: | - $QUERY = $SQL % (...) - ... - - pattern: | - $CONNECTION.execute($QUERY, ...) - - patterns: - - pattern-inside: | - $QUERY = $SQL.format(...) - ... - - pattern: | - $CONNECTION.execute($QUERY, ...) - - patterns: - - pattern-inside: | - $QUERY = f"...{...}..." - ... - - pattern: | - $CONNECTION.execute($QUERY, ...) - severity: ERROR - - fix-regex: - regex: format - replacement: bindparams - id: python.sqlalchemy.security.sqlalchemy-sql-injection.sqlalchemy-sql-injection - languages: - - python - message: Distinct, Having, Group_by, Order_by, and Filter in SQLAlchemy can cause sql injections if the developer inputs raw SQL into the before-mentioned clauses. This pattern captures relevant cases in which the developer inputs raw SQL into the distinct, having, group_by, order_by or filter clauses and injects user-input into the raw SQL with any function besides "bindparams". Use bindParams to securely bind user-input to SQL statements. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - sqlalchemy - patterns: - - pattern-either: - - pattern: | - def $FUNC(...,$VAR,...): - ... - $SESSION.query(...).$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) - - pattern: | - def $FUNC(...,$VAR,...): - ... - $SESSION.query.join(...).$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) - - pattern: | - def $FUNC(...,$VAR,...): - ... - $SESSION.query.$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) - - pattern: | - def $FUNC(...,$VAR,...): - ... - query.$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) - - metavariable-regex: - metavariable: $SQLFUNC - regex: (group_by|order_by|distinct|having|filter) - - metavariable-regex: - metavariable: $FORMATFUNC - regex: (?!bindparams) - severity: WARNING - - id: python.twilio.security.twiml-injection.twiml-injection - languages: - - python - message: Using non-constant TwiML (Twilio Markup Language) argument when creating a Twilio conversation could allow the injection of additional TwiML commands - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-91: XML Injection' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2021 - Injection - references: - - https://codeberg.org/fennix/funjection - subcategory: vuln - technology: - - python - - twilio - - twiml - mode: taint - pattern-sanitizers: - - pattern: xml.sax.saxutils.escape(...) - - pattern: html.escape(...) - pattern-sinks: - - patterns: - - pattern: | - $CLIENT.calls.create(..., twiml=$SINK, ...) - - focus-metavariable: $SINK - pattern-sources: - - pattern: | - f"..." - - pattern: | - "..." % ... - - pattern: | - "...".format(...) - - patterns: - - pattern: $ARG - - pattern-inside: | - def $F(..., $ARG, ...): - ... - severity: WARNING - - id: ruby.aws-lambda.security.activerecord-sqli.activerecord-sqli - languages: - - ruby - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `Example.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]`' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://guides.rubyonrails.org/active_record_querying.html#finding-by-sql - subcategory: - - vuln - technology: - - aws-lambda - - active-record - mode: taint - pattern-sinks: - - patterns: - - pattern: $QUERY - - pattern-either: - - pattern: ActiveRecord::Base.connection.execute($QUERY,...) - - pattern: $MODEL.find_by_sql($QUERY,...) - - pattern: $MODEL.select_all($QUERY,...) - - pattern-inside: | - require 'active_record' - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context) - ... - end - severity: WARNING - - id: ruby.aws-lambda.security.mysql2-sqli.mysql2-sqli - languages: - - ruby - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use sanitize statements like so: `escaped = client.escape(user_input)`' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/brianmario/mysql2 - subcategory: - - vuln - technology: - - aws-lambda - - mysql2 - mode: taint - pattern-sanitizers: - - pattern: $CLIENT.escape(...) - pattern-sinks: - - patterns: - - pattern: $QUERY - - pattern-either: - - pattern: $CLIENT.query($QUERY,...) - - pattern: $CLIENT.prepare($QUERY,...) - - pattern-inside: | - require 'mysql2' - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context) - ... - end - severity: WARNING - - id: ruby.aws-lambda.security.pg-sqli.pg-sqli - languages: - - ruby - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `conn.exec_params(''SELECT $1 AS a, $2 AS b, $3 AS c'', [1, 2, nil])`' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://www.rubydoc.info/gems/pg/PG/Connection - subcategory: - - vuln - technology: - - aws-lambda - - postgres - - pg - mode: taint - pattern-sinks: - - patterns: - - pattern: $QUERY - - pattern-either: - - pattern: $CONN.exec($QUERY,...) - - pattern: $CONN.exec_params($QUERY,...) - - pattern: $CONN.exec_prepared($QUERY,...) - - pattern: $CONN.async_exec($QUERY,...) - - pattern: $CONN.async_exec_params($QUERY,...) - - pattern: $CONN.async_exec_prepared($QUERY,...) - - pattern-inside: | - require 'pg' - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context) - ... - end - severity: WARNING - - id: ruby.aws-lambda.security.sequel-sqli.sequel-sqli - languages: - - ruby - message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `DB[''select * from items where name = ?'', name]`' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/jeremyevans/sequel#label-Arbitrary+SQL+queries - subcategory: - - vuln - technology: - - aws-lambda - - sequel - mode: taint - pattern-sinks: - - patterns: - - pattern: $QUERY - - pattern-either: - - pattern: DB[$QUERY,...] - - pattern: DB.run($QUERY,...) - - pattern-inside: | - require 'sequel' - ... - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context) - ... - end - severity: WARNING - - id: ruby.aws-lambda.security.tainted-deserialization.tainted-deserialization - languages: - - ruby - message: Deserialization of a string tainted by `event` object found. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of `load` can cause remote code execution. Loading user input with MARSHAL, YAML or CSV can potentially be dangerous. If you need to deserialize untrusted data, you should use JSON as it is only capable of returning 'primitive' types such as strings, arrays, hashes, numbers and nil. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://ruby-doc.org/core-3.1.2/doc/security_rdoc.html - - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb - subcategory: - - vuln - technology: - - ruby - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - pattern: $SINK - - pattern-either: - - pattern-inside: | - YAML.load($SINK,...) - - pattern-inside: | - CSV.load($SINK,...) - - pattern-inside: | - Marshal.load($SINK,...) - - pattern-inside: | - Marshal.restore($SINK,...) - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context) - ... - end - severity: WARNING - - id: ruby.aws-lambda.security.tainted-sql-string.tainted-sql-string - languages: - - ruby - message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://rorsecurity.info/portfolio/ruby-on-rails-sql-injection-cheat-sheet - subcategory: - - vuln - technology: - - aws-lambda - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: | - "...#{...}..." - - pattern-regex: (?i)(select|delete|insert|create|update|alter|drop)\b|\w+\s*!?[<>=].* - - patterns: - - pattern-either: - - pattern: Kernel::sprintf("$SQLSTR", ...) - - pattern: | - "$SQLSTR" + $EXPR - - pattern: | - "$SQLSTR" % $EXPR - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b|\w+\s*!?[<>=].* - - pattern-not-inside: | - puts(...) - pattern-sources: - - patterns: - - pattern: event - - pattern-inside: | - def $HANDLER(event, context) - ... - end - severity: ERROR - - id: ruby.jwt.security.audit.jwt-decode-without-verify.ruby-jwt-decode-without-verify - languages: - - ruby - message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-345: Insufficient Verification of Data Authenticity' - impact: LOW - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - patterns: - - pattern-inside: | - require 'jwt' - ... - - pattern: JWT.decode($PAYLOAD,$SECRET,false,...) - severity: WARNING - - id: ruby.jwt.security.audit.jwt-exposed-data.ruby-jwt-exposed-data - languages: - - ruby - message: The object is passed strictly to jsonwebtoken.sign(...) Make sure that sensitive information is not exposed through JWT token payload. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - patterns: - - pattern-inside: | - require 'jwt' - ... - - pattern-inside: | - def $FUNC(...,$INPUT,...) - ... - end - - pattern: | - JWT.encode($INPUT,...) - severity: WARNING - - id: ruby.jwt.security.jwt-exposed-credentials.ruby-jwt-exposed-credentials - languages: - - ruby - message: Password is exposed through JWT token payload. This is not encrypted and the password could be compromised. Do not store passwords in JWT tokens. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://cwe.mitre.org/data/definitions/522.html - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - patterns: - - pattern-inside: | - require 'jwt' - ... - - pattern: | - $PAYLOAD = {...,password:...,...} - ... - JWT.encode($PAYLOAD,...) - severity: ERROR - - id: ruby.jwt.security.jwt-hardcode.ruby-jwt-hardcoded-secret - languages: - - ruby - message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: LOW - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - patterns: - - pattern-inside: | - require 'jwt' - ... - - pattern-either: - - pattern: | - JWT.encode($PAYLOAD,"...",...) - - pattern: | - JWT.decode($PAYLOAD,"...",...) - - pattern: | - JWT.encode($PAYLOAD,nil,...) - - pattern: | - JWT.decode($PAYLOAD,nil,...) - - pattern: | - $SECRET = "..." - ... - JWT.encode($PAYLOAD,$SECRET,...) - - pattern: | - $SECRET = "..." - ... - JWT.decode($PAYLOAD,$SECRET,...) - - pattern-not: | - JWT.encode($PAYLOAD, nil, ... , jwks: ..., ...) - - pattern-not: | - JWT.decode($PAYLOAD, nil, ..., jwks: ..., ...) - severity: ERROR - - id: ruby.jwt.security.jwt-none-alg.ruby-jwt-none-alg - languages: - - ruby - message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - patterns: - - pattern-inside: | - require 'jwt' - ... - - pattern: | - JWT.encode($PAYLOAD, $SECRET, 'none', ...) - severity: ERROR - - id: ruby.lang.security.bad-deserialization-env.bad-deserialization-env - languages: - - ruby - message: Checks for unsafe deserialization. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of load and object_load can cause remote code execution. Loading user input with MARSHAL or CSV can potentially be dangerous. Use JSON in a secure fashion instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb - subcategory: - - vuln - technology: - - ruby - mode: taint - pattern-sinks: - - pattern-either: - - pattern: | - CSV.load(...) - - pattern: | - Marshal.load(...) - - pattern: | - Marshal.restore(...) - - pattern: | - Oj.object_load(...) - - pattern: | - Oj.load($X) - pattern-sources: - - pattern-either: - - pattern: request.env - severity: ERROR - - fix: Psych.safe_load($...ARGS) - id: ruby.lang.security.bad-deserialization-yaml.bad-deserialization-yaml - languages: - - ruby - message: Unsafe deserialization from YAML. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of load and object_load can cause remote code execution. Loading user input with YAML can potentially be dangerous. Use JSON in a secure fashion instead. However, loading YAML from a static file is not dangerous and should not be flagged. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb - subcategory: - - audit - technology: - - ruby - - yaml - patterns: - - pattern: | - YAML.load($...ARGS) - - pattern-not: | - YAML.load(..., safe: true, ...) - - pattern-not: | - YAML.load("...", ...) - - pattern-not-inside: | - YAML.load(..., File.read(...), ...) - - pattern-not-inside: | - $FILE = File.read(...) - ... - YAML.load(..., $FILE, ...) - - pattern-not-inside: | - $FILENAME = ... - ... - $FILE = File.read($FILENAME, ...) - ... - YAML.load(..., $FILE, ...) - - pattern-not-inside: | - YAML.load(..., $X.$Y(File.read(...)), ...) - - pattern-not-inside: | - YAML.load(..., $X.$Y(File.read(...)).$Z, ...) - - pattern-not-inside: | - $T = $MOD.$MET(File.read(...)) - ... - YAML.load(..., $T, ...) - - pattern-not-inside: | - $T = $MOD.$MET(File.read(...)) - ... - YAML.load(..., $T.$R, ...) - severity: ERROR - - id: ruby.lang.security.bad-deserialization.bad-deserialization - languages: - - ruby - message: Checks for unsafe deserialization. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of load and object_load can cause remote code execution. Loading user input with MARSHAL or CSV can potentially be dangerous. Use JSON in a secure fashion instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-502: Deserialization of Untrusted Data' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A08:2017 - Insecure Deserialization - - A08:2021 - Software and Data Integrity Failures - references: - - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb - subcategory: - - vuln - technology: - - ruby - mode: taint - pattern-sinks: - - pattern-either: - - pattern: | - CSV.load(...) - - pattern: | - Marshal.load(...) - - pattern: | - Marshal.restore(...) - - pattern: | - Oj.object_load(...) - - pattern: | - Oj.load($X) - pattern-sources: - - pattern-either: - - pattern: params - - pattern: cookies - severity: ERROR - - id: ruby.lang.security.cookie-serialization.cookie-serialization - languages: - - ruby - message: Checks if code allows cookies to be deserialized using Marshal. If the attacker can craft a valid cookie, this could lead to remote code execution. The hybrid check is just to warn users to migrate to :json for best practice. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_cookie_serialization.rb - - https://robertheaton.com/2013/07/22/how-to-hack-a-rails-app-using-its-secret-token/ - subcategory: - - audit - technology: - - ruby - pattern-either: - - pattern: | - Rails.application.config.action_dispatch.cookies_serializer = :marshal - - pattern: | - Rails.application.config.action_dispatch.cookies_serializer = :hybrid - severity: ERROR - - id: ruby.lang.security.create-with.create-with - languages: - - ruby - message: Checks for strong parameter bypass through usage of create_with. Create_with bypasses strong parameter protection, which could allow attackers to set arbitrary attributes on models. To fix this vulnerability, either remove all create_with calls or use the permit function to specify tags that are allowed to be set. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_create_with.rb - - https://groups.google.com/g/rubyonrails-security/c/M4chq5Sb540/m/CC1Fh0Y_NWwJ - subcategory: - - audit - technology: - - ruby - patterns: - - pattern-not: | - $FUNC.create_with($PARAMSB.permit(...)) - - pattern: | - $FUNC.create_with($PARAMSA) - severity: ERROR - - id: ruby.lang.security.dangerous-exec.dangerous-exec - languages: - - ruby - message: Detected non-static command inside $EXEC. Audit the input to '$EXEC'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://guides.rubyonrails.org/security.html#command-line-injection - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_execute.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern: | - $EXEC(...) - - pattern-not: | - $EXEC("...","...","...",...) - - pattern-not: | - $EXEC(["...","...","...",...],...) - - pattern-not: | - $EXEC({...},"...","...","...",...) - - pattern-not: | - $EXEC({...},["...","...","...",...],...) - - metavariable-regex: - metavariable: $EXEC - regex: ^(system|exec|spawn|Process.exec|Process.spawn|Open3.capture2|Open3.capture2e|Open3.capture3|Open3.popen2|Open3.popen2e|Open3.popen3|IO.popen|Gem::Util.popen|PTY.spawn)$ - pattern-sources: - - patterns: - - pattern: | - def $F(...,$ARG,...) - ... - end - - focus-metavariable: $ARG - - pattern: params - - pattern: cookies - severity: WARNING - - id: ruby.lang.security.dangerous-open.dangerous-open - languages: - - ruby - message: Detected non-static command inside 'open'. Audit the input to 'open'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - ruby - patterns: - - pattern: | - open($CMD,...) - - pattern-not: | - open("...",...) - - metavariable-regex: - metavariable: $CMD - regex: '|' - severity: WARNING - - id: ruby.lang.security.dangerous-open3-pipeline.dangerous-open3-pipeline - languages: - - ruby - message: Detected non-static command inside $PIPE. Audit the input to '$PIPE'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - ruby - patterns: - - pattern: | - Open3.$PIPE(...) - - pattern-not: | - Open3.$PIPE(...,"...",...) - - metavariable-regex: - metavariable: $PIPE - regex: ^(pipeline|pipeline_r|pipeline_rw|pipeline_start|pipeline_w)$ - severity: WARNING - - id: ruby.lang.security.dangerous-subshell.dangerous-subshell - languages: - - ruby - message: Detected non-static command inside `...`. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - ruby - patterns: - - pattern: | - `...#{$VAL}...` - - pattern-not: | - `...#{"..."}...` - - pattern-not-inside: | - $VAL = "..." - ... - severity: WARNING - - id: ruby.lang.security.dangerous-syscall.dangerous-syscall - languages: - - ruby - message: '''syscall'' is essentially unsafe and unportable. The DL (https://apidock.com/ruby/Fiddle) library is preferred for safer and a bit more portable programming.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - ruby - pattern: | - syscall - severity: WARNING - - id: ruby.lang.security.divide-by-zero.divide-by-zero - languages: - - ruby - message: Detected a possible ZeroDivisionError. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-369: Divide By Zero' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_divide_by_zero.rb - subcategory: - - vuln - technology: - - ruby - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: $NUMER / 0 - - pattern: $NUMER - pattern-sources: - - patterns: - - pattern: $VAR - - metavariable-regex: - metavariable: $VAR - regex: ^\d*(?!\.)$ - severity: WARNING - - fix-regex: - regex: =(\s)*true - replacement: = false - id: ruby.lang.security.file-disclosure.file-disclosure - languages: - - ruby - message: Special requests can determine whether a file exists on a filesystem that's outside the Rails app's root directory. To fix this, set config.serve_static_assets = false. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_file_disclosure.rb - - https://groups.google.com/g/rubyonrails-security/c/23fiuwb1NBA/m/MQVM1-5GkPMJ - subcategory: - - audit - technology: - - ruby - pattern: config.serve_static_assets = true - severity: ERROR - - id: ruby.lang.security.filter-skipping.filter-skipping - languages: - - ruby - message: Checks for use of action in Ruby routes. This can cause Rails to render an arbitrary view if an attacker creates an URL accurately. Affects 3.0 applications. Can avoid the vulnerability by providing additional constraints. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-1021: Improper Restriction of Rendered UI Layers or Frames' - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_filter_skipping.rb - - https://groups.google.com/g/rubyonrails-security/c/NCCsca7TEtY - subcategory: - - audit - technology: - - ruby - patterns: - - pattern-not: | - $CALL "=~/.*(/:action.*).*/", $ACTION - - pattern: | - $CALL "=~/.*(/:action.*).*/" - severity: ERROR - - fix-regex: - regex: =\s*false - replacement: = true - id: ruby.lang.security.force-ssl-false.force-ssl-false - languages: - - ruby - message: Checks for configuration setting of force_ssl to false. Force_ssl forces usage of HTTPS, which could lead to network interception of unencrypted application traffic. To fix, set config.force_ssl = true. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_force_ssl.rb - subcategory: - - vuln - technology: - - ruby - pattern: config.force_ssl = false - severity: WARNING - - id: ruby.lang.security.hardcoded-http-auth-in-controller.hardcoded-http-auth-in-controller - languages: - - ruby - message: Detected hardcoded password used in basic authentication in a controller class. Including this password in version control could expose this credential. Consider refactoring to use environment variables or configuration files. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/basic_auth/index.markdown - subcategory: - - audit - technology: - - ruby - - secrets - patterns: - - pattern-inside: | - class $CONTROLLER < ApplicationController - ... - http_basic_authenticate_with ..., :password => "$SECRET", ... - end - - focus-metavariable: $SECRET - severity: WARNING - - id: ruby.lang.security.hardcoded-secret-rsa-passphrase.hardcoded-secret-rsa-passphrase - languages: - - ruby - message: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://cwe.mitre.org/data/definitions/522.html - subcategory: - - vuln - technology: - - ruby - - secrets - patterns: - - pattern-either: - - pattern: OpenSSL::PKey::RSA.new(..., '...') - - pattern: OpenSSL::PKey::RSA.new(...).to_pem(..., '...') - - pattern: OpenSSL::PKey::RSA.new(...).export(..., '...') - - patterns: - - pattern-inside: | - $OPENSSL = OpenSSL::PKey::RSA.new(...) - ... - - pattern-either: - - pattern: | - $OPENSSL.export(...,'...') - - pattern: | - $OPENSSL.to_pem(...,'...') - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $ASSIGN = '...' - ... - - pattern: OpenSSL::PKey::RSA.new(..., $ASSIGN) - - patterns: - - pattern-inside: | - def $METHOD1(...) - ... - $ASSIGN = '...' - ... - end - ... - def $METHOD2(...) - ... - end - - pattern: OpenSSL::PKey::RSA.new(..., $ASSIGN) - - patterns: - - pattern-inside: | - $ASSIGN = '...' - ... - def $METHOD(...) - $OPENSSL = OpenSSL::PKey::RSA.new(...) - ... - end - ... - - pattern-either: - - pattern: $OPENSSL.export(...,$ASSIGN) - - pattern: $OPENSSL.to_pem(...,$ASSIGN) - - patterns: - - pattern-inside: | - def $METHOD1(...) - ... - $OPENSSL = OpenSSL::PKey::RSA.new(...) - ... - $ASSIGN = '...' - ... - end - ... - - pattern-either: - - pattern: $OPENSSL.export(...,$ASSIGN) - - pattern: $OPENSSL.to_pem(...,$ASSIGN) - - patterns: - - pattern-inside: | - def $METHOD1(...) - ... - $ASSIGN = '...' - ... - end - ... - def $METHOD2(...) - ... - $OPENSSL = OpenSSL::PKey::RSA.new(...) - ... - end - ... - - pattern-either: - - pattern: $OPENSSL.export(...,$ASSIGN) - - pattern: $OPENSSL.to_pem(...,$ASSIGN) - severity: WARNING - - id: ruby.lang.security.insufficient-rsa-key-size.insufficient-rsa-key-size - languages: - - ruby - message: The RSA key size $SIZE is insufficent by NIST standards. It is recommended to use a key length of 2048 or higher. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf - subcategory: - - vuln - technology: - - ruby - patterns: - - pattern-either: - - pattern: OpenSSL::PKey::RSA.generate($SIZE,...) - - pattern: OpenSSL::PKey::RSA.new($SIZE, ...) - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $ASSIGN = $SIZE - ... - - pattern-either: - - pattern: OpenSSL::PKey::RSA.new($ASSIGN, ...) - - pattern: OpenSSL::PKey::RSA.generate($ASSIGN, ...) - - patterns: - - pattern-inside: | - def $METHOD1(...) - ... - $ASSIGN = $SIZE - ... - end - ... - - pattern-either: - - pattern: OpenSSL::PKey::RSA.new($ASSIGN, ...) - - pattern: OpenSSL::PKey::RSA.generate($ASSIGN, ...) - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - severity: WARNING - - id: ruby.lang.security.json-entity-escape.json-entity-escape - languages: - - ruby - message: Checks if HTML escaping is globally disabled for JSON output. This could lead to XSS. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_json_entity_escape.rb - subcategory: - - audit - technology: - - ruby - pattern-either: - - pattern: | - ActiveSupport.escape_html_entities_in_json = false - - pattern: | - config.active_support.escape_html_entities_in_json = false - severity: WARNING - - id: ruby.lang.security.mass-assignment-protection-disabled.mass-assignment-protection-disabled - languages: - - ruby - message: Mass assignment protection disabled for '$MODEL'. This could permit assignment to sensitive model fields without intention. Instead, use 'attr_accessible' for the model or disable mass assigment using 'config.active_record.whitelist_attributes = true'. ':without_protection => true' must be removed for this to take effect. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: HIGH - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/mass_assignment/index.markdown - subcategory: - - audit - technology: - - ruby - pattern: $MODEL.new(params[...], ..., :without_protection => true, ...) - severity: WARNING - - id: ruby.lang.security.md5-used-as-password.md5-used-as-password - languages: - - ruby - message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Instead, use a suitable password hashing function such as bcrypt. You can use the `bcrypt` gem. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html - - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords - - https://github.com/returntocorp/semgrep-rules/issues/1609 - subcategory: - - vuln - technology: - - md5 - mode: taint - pattern-sinks: - - patterns: - - pattern: $FUNCTION(...); - - metavariable-regex: - metavariable: $FUNCTION - regex: (?i)(.*password.*) - pattern-sources: - - pattern: Digest::MD5 - severity: WARNING - - id: ruby.lang.security.missing-csrf-protection.missing-csrf-protection - languages: - - ruby - message: Detected controller which does not enable cross-site request forgery protections using 'protect_from_forgery'. Add 'protect_from_forgery :with => :exception' to your controller class. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/cross-site_request_forgery/index.markdown - subcategory: - - audit - technology: - - ruby - patterns: - - pattern: | - class $CONTROLLER < ActionController::Base - ... - end - - pattern-not: | - class $CONTROLLER < ActionController::Base - ... - protect_from_forgery :with => :exception - end - - pattern-not: | - class $CONTROLLER < ActionController::Base - ... - protect_from_forgery prepend: true, with: :exception - end - severity: ERROR - - id: ruby.lang.security.model-attr-accessible.model-attr-accessible - languages: - - ruby - message: 'Checks for dangerous permitted attributes that can lead to mass assignment vulnerabilities. Query parameters allowed using permit and attr_accessible are checked for allowance of dangerous attributes admin, banned, role, and account_id. Also checks for usages of params.permit!, which allows everything. Fix: don''t allow admin, banned, role, and account_id using permit or attr_accessible.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_model_attr_accessible.rb - subcategory: - - audit - technology: - - ruby - pattern-either: - - pattern: | - ....permit(..., :admin, ...) - - pattern: | - ....permit(..., :role, ...) - - pattern: | - ....permit(..., :banned, ...) - - pattern: | - ....permit(..., :account_id, ...) - - pattern: | - attr_accessible ..., :admin, ... - - pattern: | - attr_accessible ..., :role, ... - - pattern: | - attr_accessible ..., :banned, ... - - pattern: | - attr_accessible ..., :account_id, ... - - pattern: | - params.permit! - severity: ERROR - - id: ruby.lang.security.model-attributes-attr-accessible.model-attributes-attr-accessible - languages: - - ruby - message: Checks for models that do not use attr_accessible. This means there is no limiting of which variables can be manipulated through mass assignment. For newer Rails applications, parameters should be allowlisted using strong parameters. For older Rails versions, they should be allowlisted using strong_attributes. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_model_attributes.rb - subcategory: - - audit - technology: - - rails - patterns: - - pattern-not: | - class $CLASS < $TYPE - ... - attr_accessible :$XXX - ... - end - ... - $CLASS.$FUNC(...) - - pattern: | - class $CLASS < $TYPE - ... - end - ... - $CLASS.$FUNC(...) - - metavariable-pattern: - metavariable: $TYPE - patterns: - - pattern-not-regex: (?i)(Error|Exception) - - focus-metavariable: $CLASS - severity: ERROR - - id: ruby.lang.security.no-eval.ruby-eval - languages: - - ruby - message: Use of eval with user-controllable input detected. This can lead to attackers running arbitrary code. Ensure external data does not reach here, otherwise this is a security vulnerability. Consider other ways to do this without eval. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_evaluation.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $X.eval - - pattern: $X.class_eval - - pattern: $X.instance_eval - - pattern: $X.module_eval - - pattern: $X.eval(...) - - pattern: $X.class_eval(...) - - pattern: $X.instance_eval(...) - - pattern: $X.module_eval(...) - - pattern: eval(...) - - pattern: class_eval(...) - - pattern: module_eval(...) - - pattern: instance_eval(...) - - pattern-not: $M("...",...) - pattern-sources: - - pattern-either: - - pattern: params - - pattern: cookies - - patterns: - - pattern: | - RubyVM::InstructionSequence.compile(...) - - pattern-not: | - RubyVM::InstructionSequence.compile("...") - severity: WARNING - - id: ruby.lang.security.no-send.bad-send - languages: - - ruby - message: Checks for unsafe use of Object#send, try, __send__, and public_send. These only account for unsafe use of a method, not target. This can lead to arbitrary calling of exit, along with arbitrary code execution. Please be sure to sanitize input in order to avoid this. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_send.rb - - https://the.igreque.info/posts/2016/01-object-send-considered-harmful-en.html - subcategory: - - audit - technology: - - ruby - pattern-either: - - pattern: | - $PARAM = params[...] - ... - $RES = $MOD.send($PARAM.$FUNC) - - pattern: | - $PARAM = params[...] - ... - $RES = $MOD.try($PARAM.$FUNC) - - pattern: | - $PARAM = params[...] - ... - $RES = $MOD.__send__($PARAM.$FUNC) - - pattern: | - $PARAM = params[...] - ... - $RES = $MOD.public_send($PARAM.$FUNC) - severity: ERROR - - fix-regex: - regex: VERIFY_NONE - replacement: VERIFY_PEER - id: ruby.lang.security.ssl-mode-no-verify.ssl-mode-no-verify - languages: - - ruby - message: Detected SSL that will accept an unverified connection. This makes the connections susceptible to man-in-the-middle attacks. Use 'OpenSSL::SSL::VERIFY_PEER' instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - subcategory: - - vuln - technology: - - ruby - pattern: OpenSSL::SSL::VERIFY_NONE - severity: WARNING - - id: ruby.lang.security.unprotected-mass-assign.mass-assignment-vuln - languages: - - ruby - message: 'Checks for calls to without_protection during mass assignment (which allows record creation from hash values). This can lead to users bypassing permissions protections. For Rails 4 and higher, mass protection is on by default. Fix: Don''t use :without_protection => true. Instead, configure attr_accessible to control attribute access.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_without_protection.rb - - https://www.acunetix.com/vulnerabilities/web/rails-mass-assignment/ - subcategory: - - audit - technology: - - ruby - patterns: - - pattern-either: - - pattern: | - $MOD.new(params[$CODE]) - - pattern: | - $MOD.new(..., params[$CODE], :without_protection => true, ...) - - pattern-not-inside: | - attr_accessible $VAR - ... - $MOD.new(params[$CODE]) - severity: WARNING - - id: ruby.lang.security.weak-hashes-md5.weak-hashes-md5 - languages: - - ruby - message: Should not use md5 to generate hashes. md5 is proven to be vulnerable through the use of brute-force attacks. Could also result in collisions, leading to potential collision attacks. Use SHA256 or other hashing functions instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-328: Use of Weak Hash' - impact: HIGH - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.ibm.com/support/pages/security-bulletin-vulnerability-md5-signature-and-hash-algorithm-affects-sterling-integrator-and-sterling-file-gateway-cve-2015-7575 - subcategory: - - vuln - technology: - - ruby - pattern-either: - - pattern: Digest::MD5.base64digest $X - - pattern: Digest::MD5.hexdigest $X - - pattern: Digest::MD5.digest $X - - pattern: Digest::MD5.new - - pattern: OpenSSL::Digest::MD5.base64digest $X - - pattern: OpenSSL::Digest::MD5.hexdigest $X - - pattern: OpenSSL::Digest::MD5.digest $X - - pattern: OpenSSL::Digest::MD5.new - severity: WARNING - - id: ruby.lang.security.weak-hashes-sha1.weak-hashes-sha1 - languages: - - ruby - message: Should not use SHA1 to generate hashes. There is a proven SHA1 hash collision by Google, which could lead to vulnerabilities. Use SHA256, SHA3 or other hashing functions instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-328: Use of Weak Hash' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html - - https://shattered.io/ - subcategory: - - vuln - technology: - - ruby - pattern-either: - - pattern: Digest::SHA1.$FUNC - - pattern: OpenSSL::Digest::SHA1.$FUNC - - pattern: OpenSSL::HMAC.$FUNC("sha1",...) - severity: WARNING - - fix: redirect_to $T - id: ruby.rails.correctness.rails-no-render-after-save.rails-no-render-after-save - languages: - - ruby - message: Found a call to `render $T` after calling `$T.save`. Do not call `render` after calling `save` on an ActiveRecord object. Reloading the page will cause the state-changing operation to be repeated which may cause undesirable side effects. Use `redirect_to` instead. - metadata: - category: correctness - references: - - https://guides.rubyonrails.org/getting_started.html#creating-a-new-article - technology: - - rails - - ruby - - activerecord - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: | - render $T - pattern-sources: - - patterns: - - pattern: $T - - pattern-inside: | - $T.save - ... - severity: WARNING - - id: ruby.rails.performance.ruby-rails-performance-indexes-are-really-beneficial.ruby-rails-performance-indexes-are-beneficial - languages: - - ruby - message: The $COLUMN column appears to be a foreign key. Would it benefit from an index? Having an index can improve performance. - metadata: - category: performance - references: - - https://archive.is/i7SLO - technology: - - rails - patterns: - - pattern-not-inside: | - add_column $TABLE, $COLUMN, $TYPE, ... - ... - add_index $TABLE, $COLUMN, ... - - pattern: | - add_column $TABLE, $COLUMN, $TYPE, ... - - metavariable-regex: - metavariable: $COLUMN - regex: (.*_id$) - - metavariable-regex: - metavariable: $TYPE - regex: :integer|:bigint - severity: INFO - - id: ruby.rails.security.audit.avoid-session-manipulation.avoid-session-manipulation - languages: - - ruby - message: This gets data from session using user inputs. A malicious user may be able to retrieve information from your session that you didn't intend them to. Do not use user input as a session key. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-276: Incorrect Default Permissions' - cwe2021-top25: true - cwe2022-top25: true - help: | - ## Remediation - Session manipulation can occur when an application allows user-input in session keys. Since sessions are typically considered a source of truth (e.g. to check the logged-in user or to match CSRF tokens), allowing an attacker to manipulate the session may lead to unintended behavior. - - ## References - [Session Manipulation](https://brakemanscanner.org/docs/warning_types/session_manipulation/) - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/session_manipulation/ - shortDescription: Allowing an attacker to manipulate the session may lead to unintended behavior. - subcategory: - - vuln - tags: - - security - technology: - - rails - mode: taint - pattern-sinks: - - pattern: session[...] - pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - severity: WARNING - - id: ruby.rails.security.audit.avoid-tainted-file-access.avoid-tainted-file-access - languages: - - ruby - message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: Dir.$X(...) - - pattern: File.$X(...) - - pattern: IO.$X(...) - - pattern: Kernel.$X(...) - - pattern: PStore.$X(...) - - pattern: Pathname.$X(...) - - metavariable-pattern: - metavariable: $X - patterns: - - pattern-either: - - pattern: chdir - - pattern: chroot - - pattern: delete - - pattern: entries - - pattern: foreach - - pattern: glob - - pattern: install - - pattern: lchmod - - pattern: lchown - - pattern: link - - pattern: load - - pattern: load_file - - pattern: makedirs - - pattern: move - - pattern: new - - pattern: open - - pattern: read - - pattern: readlines - - pattern: rename - - pattern: rmdir - - pattern: safe_unlink - - pattern: symlink - - pattern: syscopy - - pattern: sysopen - - pattern: truncate - - pattern: unlink - pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - severity: WARNING - - id: ruby.rails.security.audit.avoid-tainted-ftp-call.avoid-tainted-ftp-call - languages: - - ruby - message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sinks: - - pattern-either: - - pattern: Net::FTP.$X(...) - - patterns: - - pattern-inside: | - $FTP = Net::FTP.$OPEN(...) - ... - $FTP.$METHOD(...) - - pattern: $FTP.$METHOD(...) - pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - severity: WARNING - - id: ruby.rails.security.audit.avoid-tainted-http-request.avoid-tainted-http-request - languages: - - ruby - message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sinks: - - pattern-either: - - patterns: - - pattern: Net::HTTP::$METHOD.new(...) - - metavariable-pattern: - metavariable: $METHOD - patterns: - - pattern-either: - - pattern: Copy - - pattern: Delete - - pattern: Get - - pattern: Head - - pattern: Lock - - pattern: Mkcol - - pattern: Move - - pattern: Options - - pattern: Patch - - pattern: Post - - pattern: Propfind - - pattern: Proppatch - - pattern: Put - - pattern: Trace - - pattern: Unlock - - patterns: - - pattern: Net::HTTP.$X(...) - - metavariable-pattern: - metavariable: $X - patterns: - - pattern-either: - - pattern: get - - pattern: get2 - - pattern: head - - pattern: head2 - - pattern: options - - pattern: patch - - pattern: post - - pattern: post2 - - pattern: post_form - - pattern: put - - pattern: request - - pattern: request_get - - pattern: request_head - - pattern: request_post - - pattern: send_request - - pattern: trace - - pattern: get_print - - pattern: get_response - - pattern: start - pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - severity: WARNING - - id: ruby.rails.security.audit.avoid-tainted-shell-call.avoid-tainted-shell-call - languages: - - ruby - message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: Kernel.$X(...) - - patterns: - - pattern-either: - - pattern: Shell.$X(...) - - patterns: - - pattern-inside: | - $SHELL = Shell.$ANY(...) - ... - $SHELL.$X(...) - - pattern: $SHELL.$X(...) - - metavariable-pattern: - metavariable: $X - patterns: - - pattern-either: - - pattern: cat - - pattern: chdir - - pattern: chroot - - pattern: delete - - pattern: entries - - pattern: exec - - pattern: foreach - - pattern: glob - - pattern: install - - pattern: lchmod - - pattern: lchown - - pattern: link - - pattern: load - - pattern: load_file - - pattern: makedirs - - pattern: move - - pattern: new - - pattern: open - - pattern: read - - pattern: readlines - - pattern: rename - - pattern: rmdir - - pattern: safe_unlink - - pattern: symlink - - pattern: syscopy - - pattern: sysopen - - pattern: system - - pattern: truncate - - pattern: unlink - pattern-sources: - - pattern-either: - - pattern: params[...] - - pattern: cookies - - pattern: request.env - severity: ERROR - - id: ruby.rails.security.audit.detailed-exceptions.detailed-exceptions - languages: - - ruby - message: Found that the setting for providing detailed exception reports in Rails is set to true. This can lead to information exposure, where sensitive system or internal information is displayed to the end user. Instead, turn this setting off. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_detailed_exceptions.rb - subcategory: - - audit - technology: - - rails - patterns: - - pattern-either: - - patterns: - - pattern: | - config.consider_all_requests_local = true - - patterns: - - pattern-inside: | - class $CONTROLLER < ApplicationController - ... - end - - pattern: | - def show_detailed_exceptions? (...) - ... - return $RETURN - end - - metavariable-pattern: - metavariable: $RETURN - patterns: - - pattern-not: | - false - severity: WARNING - - id: ruby.rails.security.audit.rails-skip-forgery-protection.rails-skip-forgery-protection - languages: - - ruby - message: This call turns off CSRF protection allowing CSRF attacks against the application - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html#method-i-skip_forgery_protection - subcategory: - - audit - technology: - - rails - pattern: skip_forgery_protection - severity: WARNING - - id: ruby.rails.security.audit.sqli.ruby-pg-sqli.ruby-pg-sqli - languages: - - ruby - message: 'Detected string concatenation with a non-literal variable in a pg Ruby SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized queries like so: `conn.exec_params(''SELECT $1 AS a, $2 AS b, $3 AS c'', [1, 2, nil])` And you can use prepared statements with `exec_prepared`.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://www.rubydoc.info/gems/pg/PG/Connection - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-propagators: - - from: $Y - pattern: $X << $Y - to: $X - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $CON = PG.connect(...) - ... - - pattern-inside: | - $CON = PG::Connection.open(...) - ... - - pattern-inside: | - $CON = PG::Connection.new(...) - ... - - pattern-either: - - pattern: | - $CON.$METHOD($X,...) - - pattern: | - $CON.$METHOD $X, ... - - focus-metavariable: $X - - metavariable-regex: - metavariable: $METHOD - regex: ^(exec|exec_params)$ - pattern-sources: - - pattern-either: - - pattern: | - params - - pattern: | - cookies - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-content-tag.avoid-content-tag - languages: - - ruby - message: '''content_tag()'' bypasses HTML escaping for some portion of the content. If external data can reach here, this exposes your application to cross-site scripting (XSS) attacks. Ensure no external data reaches here. If you must do this, create your HTML manually and use ''html_safe''. Ensure no external data enters the HTML-safe string!' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/template_injection/index.markdown - - https://www.netsparker.com/blog/web-security/preventing-xss-ruby-on-rails-web-applications/ - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_content_tag.rb - subcategory: - - audit - technology: - - rails - pattern: content_tag(...) - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-default-routes.avoid-default-routes - languages: - - ruby - message: Default routes are enabled in this routes file. This means any public method on a controller can be called as an action. It is very easy to accidentally expose a method you didn't mean to. Instead, remove this line and explicitly include all routes you intend external users to follow. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-276: Incorrect Default Permissions' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/default_routes/index.markdown - subcategory: - - audit - technology: - - rails - paths: - include: - - '*routes.rb' - patterns: - - pattern-either: - - pattern: map.connect ":controller/:action/:id" - - pattern: match ':controller(/:action(/:id(.:format)))' - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-html-safe.avoid-html-safe - languages: - - ruby - message: '''html_safe()'' does not make the supplied string safe. ''html_safe()'' bypasses HTML escaping. If external data can reach here, this exposes your application to cross-site scripting (XSS) attacks. Ensure no external data reaches here.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/cross_site_scripting/index.markdown - - https://www.netsparker.com/blog/web-security/preventing-xss-ruby-on-rails-web-applications/ - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_cross_site_scripting.rb - subcategory: - - audit - technology: - - rails - pattern-either: - - pattern: $STR.html_safe - - pattern: $STR.html_safe.$MORE - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-link-to.avoid-link-to - languages: - - ruby - message: This code includes user input in `link_to`. In Rails 2.x, the body of `link_to` is not escaped. This means that user input which reaches the body will be executed when the HTML is rendered. Even in other versions, values starting with `javascript:` or `data:` are not escaped. It is better to create and use a safer function which checks the body argument. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://brakemanscanner.org/docs/warning_types/link_to/ - - https://brakemanscanner.org/docs/warning_types/link_to_href/ - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_link_to.rb - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sanitizers: - - patterns: - - pattern: | - "...#{...}..." - - pattern-not: | - "#{...}..." - pattern-sinks: - - pattern: link_to(...) - pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - - pattern-either: - - pattern: $MODEL.url(...) - - pattern: $MODEL.uri(...) - - pattern: $MODEL.link(...) - - pattern: $MODEL.page(...) - - pattern: $MODEL.site(...) - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-raw.avoid-raw - languages: - - ruby - message: '''raw()'' bypasses HTML escaping. If external data can reach here, this exposes your application to cross-site scripting (XSS) attacks. If you must do this, construct individual strings and mark them as safe for HTML rendering with `html_safe()`.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://api.rubyonrails.org/classes/ActionView/Helpers/OutputSafetyHelper.html#method-i-raw - - https://www.netsparker.com/blog/web-security/preventing-xss-ruby-on-rails-web-applications/ - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_cross_site_scripting.rb - subcategory: - - audit - technology: - - rails - pattern: raw(...) - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-redirect.avoid-redirect - languages: - - ruby - message: When a redirect uses user input, a malicious user can spoof a website under a trusted URL or access restricted parts of a site. When using user-supplied values, sanitize the value before using it for the redirect. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/redirect/ - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sanitizers: - - pattern: params.merge(:only_path => true) - - pattern: params.merge(:host => ...) - pattern-sinks: - - pattern: redirect_to(...) - pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - - patterns: - - pattern: $MODEL.$X(...) - - pattern-not: $MODEL.$X("...") - - metavariable-pattern: - metavariable: $X - pattern-either: - - pattern: all - - pattern: create - - pattern: create! - - pattern: find - - pattern: find_by_sql - - pattern: first - - pattern: last - - pattern: new - - pattern: from - - pattern: group - - pattern: having - - pattern: joins - - pattern: lock - - pattern: order - - pattern: reorder - - pattern: select - - pattern: where - - pattern: find_by - - pattern: find_by! - - pattern: take - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-render-dynamic-path.avoid-render-dynamic-path - languages: - - ruby - message: Avoid rendering user input. It may be possible for a malicious user to input a path that lets them access a template they shouldn't. To prevent this, check dynamic template paths against a predefined allowlist to make sure it's an allowed template. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/dynamic_render_paths/ - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: render($X => $INPUT, ...) - - pattern: $INPUT - - metavariable-pattern: - metavariable: $X - pattern-either: - - pattern: action - - pattern: template - - pattern: partial - - pattern: file - pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - severity: WARNING - - id: ruby.rails.security.audit.xss.avoid-render-inline.avoid-render-inline - languages: - - ruby - message: '''render inline: ...'' renders an entire ERB template inline and is dangerous. If external data can reach here, this exposes your application to server-side template injection (SSTI) or cross-site scripting (XSS) attacks. Instead, consider using a partial or another safe rendering method.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#inline-renders---even-worse-than-xss - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render_inline.rb - subcategory: - - audit - technology: - - rails - pattern: 'render inline: ...' - severity: WARNING - - fix-regex: - regex: 'text:' - replacement: 'plain:' - id: ruby.rails.security.audit.xss.avoid-render-text.avoid-render-text - languages: - - ruby - message: '''render text: ...'' actually sets the content-type to ''text/html''. If external data can reach here, this exposes your application to cross-site scripting (XSS) attacks. Instead, use ''render plain: ...'' to render non-HTML text.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#inline-renders---even-worse-than-xss - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render_inline.rb - subcategory: - - audit - technology: - - rails - pattern: 'render text: ...' - severity: WARNING - - id: ruby.rails.security.audit.xss.manual-template-creation.manual-template-creation - languages: - - ruby - message: Detected manual creation of an ERB template. Manual creation of templates may expose your application to server-side template injection (SSTI) or cross-site scripting (XSS) attacks if user input is used to create the template. Instead, create a '.erb' template file and use 'render'. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/template_injection/index.markdown - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_template_injection.rb - subcategory: - - audit - technology: - - rails - pattern: ERB.new(...) - severity: WARNING - - id: ruby.rails.security.audit.xss.templates.alias-for-html-safe.alias-for-html-safe - languages: - - generic - message: The syntax `<%== ... %>` is an alias for `html_safe`. This means the content inside these tags will be rendered as raw HTML. This may expose your application to cross-site scripting. If you need raw HTML, prefer using the more explicit `html_safe` and be sure to correctly sanitize variables using a library such as DOMPurify. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://medium.com/sumone-technical-blog/a-pretty-way-to-unescape-html-in-a-ruby-on-rails-application-efc22b850027 - - https://stackoverflow.com/questions/4251284/raw-vs-html-safe-vs-h-to-unescape-html#:~:text=== - subcategory: - - audit - technology: - - rails - paths: - include: - - '*.erb' - patterns: - - pattern: <%== ... %> - - pattern-not: <%== $...A.to_json %> - severity: WARNING - - id: ruby.rails.security.audit.xss.templates.avoid-content-tag.avoid-content-tag - languages: - - generic - message: '''content_tag'' exhibits unintuitive escaping behavior and may accidentally expose your application to cross-site scripting. If using Rails 2, only attribute values are escaped. If using Rails 3, content and attribute values are escaped. Tag and attribute names are never escaped. Because of this, it is recommended to use ''html_safe'' if you must render raw HTML data.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://brakemanscanner.org/docs/warning_types/content_tag/ - source-rule-url: https://brakemanscanner.org/docs/warning_types/content_tag/ - subcategory: - - audit - technology: - - rails - paths: - include: - - '*.erb' - patterns: - - pattern-inside: <%= ... %> - - pattern: content_tag - severity: WARNING - - id: ruby.rails.security.audit.xss.templates.avoid-html-safe.avoid-html-safe - languages: - - generic - message: '''html_safe'' renders raw HTML. This means that normal HTML escaping is bypassed. If user data can be controlled here, this exposes your application to cross-site scripting (XSS). If you need to do this, be sure to correctly sanitize the data using a library such as DOMPurify.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://stackoverflow.com/questions/4251284/raw-vs-html-safe-vs-h-to-unescape-html#:~:text=== - - https://medium.com/sumone-technical-blog/a-pretty-way-to-unescape-html-in-a-ruby-on-rails-application-efc22b850027 - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_cross_site_scripting.rb - subcategory: - - audit - technology: - - rails - paths: - include: - - '*.erb' - patterns: - - pattern-inside: <%= ... %> - - pattern: $SOMETHING.html_safe - severity: WARNING - - id: ruby.rails.security.audit.xss.templates.avoid-raw.avoid-raw - languages: - - generic - message: '''raw'' renders raw HTML, as the name implies. This means that normal HTML escaping is bypassed. If user data can be controlled here, this exposes your application to cross-site scripting (XSS). If you need to do this, be sure to correctly sanitize the data using a library such as DOMPurify.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://stackoverflow.com/questions/4251284/raw-vs-html-safe-vs-h-to-unescape-html#:~:text=== - - https://medium.com/sumone-technical-blog/a-pretty-way-to-unescape-html-in-a-ruby-on-rails-application-efc22b850027 - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_cross_site_scripting.rb - subcategory: - - audit - technology: - - rails - paths: - include: - - '*.erb' - patterns: - - pattern-inside: <%= ... %> - - pattern: raw - severity: WARNING - - id: ruby.rails.security.audit.xss.templates.dangerous-link-to.dangerous-link-to - languages: - - generic - message: 'Detected a template variable used in ''link_to''. This will generate dynamic data in the ''href'' attribute. This allows a malicious actor to input the ''javascript:'' URI and is subject to cross- site scripting (XSS) attacks. If using a relative URL, start with a literal forward slash and concatenate the URL, like this: ''link_to "Here", "/"+@link''. You may also consider setting the Content Security Policy (CSP) header.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Ruby_on_Rails_Cheat_Sheet.html#cross-site-scripting-xss - - https://brakemanscanner.org/docs/warning_types/link_to_href/ - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_link_to.rb - subcategory: - - audit - technology: - - rails - paths: - include: - - '*.erb' - patterns: - - pattern-inside: <%= ... %> - - pattern-not-inside: link_to ... "/" + ... @$VAR - - pattern-not-inside: link_to ... '/' + ... @$VAR - - pattern: link_to ... @$VAR - severity: WARNING - - fix-regex: - regex: <%=(.*?)%> - replacement: '"<%=\1%>"' - id: ruby.rails.security.audit.xss.templates.unquoted-attribute.unquoted-attribute - languages: - - generic - message: 'Detected a unquoted template variable as an attribute. If unquoted, a malicious actor could inject custom JavaScript handlers. To fix this, add quotes around the template expression, like this: "<%= expr %>".' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#unquoted-attributes - - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss - subcategory: - - audit - technology: - - rails - paths: - include: - - '*.erb' - patterns: - - pattern-inside: <$TAG ...> - - pattern-not-inside: ="..." - - pattern-not-inside: ="<%= ... %>" - - pattern-not-inside: ='...' - - pattern-not-inside: ='<%= ... %>' - - pattern: <%= ... %> - severity: WARNING - - id: ruby.rails.security.audit.xss.templates.var-in-href.var-in-href - languages: - - generic - message: 'Detected a template variable used in an anchor tag with the ''href'' attribute. This allows a malicious actor to input the ''javascript:'' URI and is subject to cross- site scripting (XSS) attacks. If using a relative URL, start with a literal forward slash and concatenate the URL, like this: href=''/<%= link =>''. You may also consider setting the Content Security Policy (CSP) header.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss#:~:text=javascript:%20URI - - https://github.com/pugjs/pug/issues/2952 - subcategory: - - audit - technology: - - rails - paths: - include: - - '*.erb' - pattern-either: - - pattern: - - pattern: - severity: WARNING - - id: ruby.rails.security.audit.xss.templates.var-in-script-tag.var-in-script-tag - languages: - - generic - message: Detected a template variable used in a script tag. Although template variables are HTML escaped, HTML escaping does not always prevent cross-site scripting (XSS) attacks when used directly in JavaScript. If you need to do this, use `escape_javascript` or its alias, `j`. However, this will not protect from XSS in all circumstances; see the references for more information. Consider placing this value in the HTML portion (outside of a script tag). - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://www.netsparker.com/blog/web-security/preventing-xss-ruby-on-rails-web-applications/ - - https://www.youtube.com/watch?v=yYTkLUEdIyE - - https://www.veracode.com/blog/secure-development/nodejs-template-engines-why-default-encoders-are-not-enough - subcategory: - - audit - technology: - - rails - paths: - include: - - '*.erb' - patterns: - - pattern-inside: - - pattern-not: <%= j ... > - - pattern-not: <%= escape_javascript ... > - - pattern: <%= ... > - severity: WARNING - - id: ruby.rails.security.audit.xxe.libxml-backend.libxml-backend - languages: - - ruby - message: This application is using LibXML as the XML backend. LibXML can be vulnerable to XML External Entities (XXE) vulnerabilities. Use the built-in Rails XML parser, REXML, instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://www.stackhawk.com/blog/rails-xml-external-entities-xxe-guide-examples-and-prevention/ - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - rails - - libxml - pattern: ActiveSupport::XmlMini.backend = "LibXML" - severity: WARNING - - id: ruby.rails.security.audit.xxe.xml-external-entities-enabled.xml-external-entities-enabled - languages: - - ruby - message: This application is explicitly enabling external entities enabling an attacker to inject malicious XML to exploit an XML External Entities (XXE) vulnerability. This could let the attacker cause a denial-of-service by forcing the parser to parse large files, or at worst, let the attacker download sensitive files or user data. Use the built-in Rails XML parser, REXML, instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://www.stackhawk.com/blog/rails-xml-external-entities-xxe-guide-examples-and-prevention/ - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - rails - - libxml - patterns: - - pattern-either: - - pattern-inside: | - LibXML::XML.class_eval do - ... - end - - pattern-inside: | - XML.class_eval do - ... - end - - pattern: XML.default_substitute_entities = true - severity: ERROR - - id: ruby.rails.security.brakeman.check-before-filter.check-before-filter - languages: - - ruby - message: 'Disabled-by-default Rails controller checks make it much easier to introduce access control mistakes. Prefer an allowlist approach with `:only => [...]` rather than `except: => [...]`' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-284: Improper Access Control' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_skip_before_filter.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: search - patterns: - - pattern-either: - - pattern: | - skip_filter ..., :except => $ARGS - - pattern: | - skip_before_filter ..., :except => $ARGS - - pattern: | - skip_before_action ..., :except => $ARGS - severity: ERROR - - id: ruby.rails.security.brakeman.check-cookie-store-session-security-attributes.check-cookie-store-session-security-attributes - languages: - - ruby - message: Found a Rails `cookie_store` session configuration setting the `$KEY` attribute to `false`. If using a cookie-based session store, the HttpOnly and Secure flags should be set. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_session_settings.rb - subcategory: - - audit - technology: - - ruby - - rails - patterns: - - pattern-either: - - patterns: - - pattern: | - :$KEY => false - - pattern-inside: | - ActionController::Base.session = {...} - - pattern: | - $MODULE::Application.config.session_store :cookie_store, ..., :$KEY => false, ... - - pattern: | - $CLASS.application.config.session_store :cookie_store, ..., $KEY: false, ... - - metavariable-regex: - metavariable: $KEY - regex: ^(session_)?(http_?only|secure)$ - severity: WARNING - - id: ruby.rails.security.brakeman.check-dynamic-render-local-file-include.check-dynamic-render-local-file-include - languages: - - generic - message: Found request parameters in a call to `render` in a dynamic context. This can allow end users to request arbitrary local files which may result in leaking sensitive information persisted on disk. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion - - https://github.com/presidentbeef/brakeman/blob/f74cb53ead47f0af821d98b5b41e16d63100c240/test/apps/rails2/app/views/home/test_render.html.erb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: search - paths: - include: - - '*.erb' - patterns: - - pattern: | - params[...] - - pattern-inside: | - render :file => ... - severity: WARNING - - id: ruby.rails.security.brakeman.check-http-verb-confusion.check-http-verb-confusion - languages: - - ruby - message: Found an improperly constructed control flow block with `request.get?`. Rails will route HEAD requests as GET requests but they will fail the `request.get?` check, potentially causing unexpected behavior unless an `elif` condition is used. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-650: Trusting HTTP Permission Methods on the Server Side' - impact: MEDIUM - likelihood: HIGH - owasp: - - A04:2021 - Insecure Design - references: - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails6/app/controllers/accounts_controller.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_verb_confusion.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: search - patterns: - - pattern: | - if request.get? - ... - else - ... - end - - pattern-not-inside: | - if ... - elsif ... - ... - end - severity: ERROR - - id: ruby.rails.security.brakeman.check-permit-attributes-high.check-permit-attributes-high - languages: - - ruby - message: Calling `permit` on security-critical properties like `$ATTRIBUTE` may leave your application vulnerable to mass assignment. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_permit_attributes.rb - subcategory: - - audit - technology: - - ruby - - rails - patterns: - - pattern: $P.permit($ATTRIBUTE) - - metavariable-regex: - metavariable: $ATTRIBUTE - regex: .*(admin|account_id).* - severity: ERROR - - id: ruby.rails.security.brakeman.check-permit-attributes-medium.check-permit-attributes-medium - languages: - - ruby - message: Calling `permit` on security-critical properties like `$ATTRIBUTE` may leave your application vulnerable to mass assignment. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes' - impact: MEDIUM - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_permit_attributes.rb - subcategory: - - audit - technology: - - ruby - - rails - patterns: - - pattern: $P.permit($ATTRIBUTE) - - metavariable-regex: - metavariable: $ATTRIBUTE - regex: .*(role|banned).* - severity: WARNING - - id: ruby.rails.security.brakeman.check-rails-secret-yaml.check-rails-secret-yaml - languages: - - yaml - message: $VALUE Found a string literal assignment to a production Rails session secret in `secrets.yaml`. Do not commit secret values to source control! Any user in possession of this value may falsify arbitrary session data in your application. Read this value from an environment variable, KMS, or file on disk outside of source control. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-540: Inclusion of Sensitive Information in Source Code' - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails4/config/secrets.yml - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_session_settings.rb - subcategory: - - audit - technology: - - ruby - - rails - paths: - include: - - '*secrets.*.yml' - - '*secrets.*.yaml' - patterns: - - pattern: | - secret_key_base: $VALUE - - metavariable-pattern: - language: generic - metavariable: $VALUE - patterns: - - pattern-not: | - <%= ... %> - - pattern-inside: | - production: - ... - severity: WARNING - - id: ruby.rails.security.brakeman.check-rails-session-secret-handling.check-rails-session-secret-handling - languages: - - ruby - message: Found a string literal assignment to a Rails session secret `$KEY`. Do not commit secret values to source control! Any user in possession of this value may falsify arbitrary session data in your application. Read this value from an environment variable, KMS, or file on disk outside of source control. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-540: Inclusion of Sensitive Information in Source Code' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails4_with_engines/config/initializers/secret_token.rb - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3/config/initializers/secret_token.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_session_settings.rb - subcategory: - - vuln - technology: - - ruby - - rails - patterns: - - pattern-either: - - patterns: - - pattern: | - :$KEY => "$LITERAL" - - pattern-inside: | - ActionController::Base.session = {...} - - pattern: | - $RAILS::Application.config.$KEY = "$LITERAL" - - pattern: | - Rails.application.config.$KEY = "$LITERAL" - - metavariable-regex: - metavariable: $KEY - regex: ^secret(_(token|key_base))?$ - severity: WARNING - - id: ruby.rails.security.brakeman.check-redirect-to.check-redirect-to - languages: - - ruby - message: Found potentially unsafe handling of redirect behavior $X. Do not pass `params` to `redirect_to` without the `:only_path => true` hash value. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_redirect.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - patterns: - - pattern: | - $F(...) - - metavariable-pattern: - metavariable: $F - patterns: - - pattern-not-regex: (params|url_for|cookies|request.env|permit|redirect_to) - - pattern: | - params.merge! :only_path => true - ... - - pattern: | - params.slice(...) - ... - - pattern: | - redirect_to [...] - - patterns: - - pattern: | - $MODEL. ... .$M(...) - ... - - metavariable-regex: - metavariable: $MODEL - regex: '[A-Z]\w+' - - metavariable-regex: - metavariable: $M - regex: (all|create|find|find_by|find_by_sql|first|last|new|from|group|having|joins|lock|order|reorder|select|where|take) - - patterns: - - pattern: | - params.$UNSAFE_HASH.merge(...,:only_path => true,...) - ... - - metavariable-regex: - metavariable: $UNSAFE_HASH - regex: to_unsafe_h(ash)? - - patterns: - - pattern: params.permit(...,$X,...) - - metavariable-pattern: - metavariable: $X - patterns: - - pattern-not-regex: (host|port|(sub)?domain) - pattern-sinks: - - patterns: - - pattern: $X - - pattern-inside: | - redirect_to $X, ... - - pattern-not-regex: params\.\w+(? false,...) - severity: WARNING - - id: ruby.rails.security.brakeman.check-regex-dos.check-regex-dos - languages: - - ruby - message: Found a potentially user-controllable argument in the construction of a regular expressions. This may result in excessive resource consumption when applied to certain inputs, or when the user is allowed to control the match target. Avoid allowing users to specify regular expressions processed by the server. If you must support user-controllable input in a regular expression, use an allow-list to restrict the expressions users may supply to limit catastrophic backtracking. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1333: Inefficient Regular Expression Complexity' - impact: MEDIUM - likelihood: HIGH - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_regex_dos.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: $Y - - pattern-inside: | - /...#{...}.../ - - patterns: - - pattern: $Y - - pattern-inside: | - Regexp.new(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - - patterns: - - pattern: $Y - - pattern-either: - - pattern-inside: | - $RECORD.read_attribute($Y) - - pattern-inside: | - $RECORD[$Y] - - metavariable-regex: - metavariable: $RECORD - regex: '[A-Z][a-z]+' - severity: ERROR - - id: ruby.rails.security.brakeman.check-render-local-file-include.check-render-local-file-include - languages: - - ruby - message: Found request parameters in a call to `render`. This can allow end users to request arbitrary local files which may result in leaking sensitive information persisted on disk. Where possible, avoid letting users specify template paths for `render`. If you must allow user input, use an allow-list of known templates or normalize the user-supplied value with `File.basename(...)`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion - - https://github.com/presidentbeef/brakeman/blob/f74cb53/test/apps/rails2/app/controllers/home_controller.rb#L48-L60 - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render.rb - subcategory: - - vuln - technology: - - ruby - - rails - vulnerability_class: - - Path Traversal - mode: taint - pattern-sanitizers: - - patterns: - - pattern: $MAP[...] - - metavariable-pattern: - metavariable: $MAP - patterns: - - pattern-not-regex: params - - pattern: File.basename(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - render ..., file: $X - - pattern: | - render ..., inline: $X - - pattern: | - render ..., template: $X - - pattern: | - render ..., action: $X - - pattern: | - render $X, ... - - focus-metavariable: $X - pattern-sources: - - patterns: - - pattern: params[...] - severity: WARNING - - id: ruby.rails.security.brakeman.check-reverse-tabnabbing.check-reverse-tabnabbing - languages: - - generic - message: Setting an anchor target of `_blank` without the `noopener` or `noreferrer` attribute allows reverse tabnabbing on Internet Explorer, Opera, and Android Webview. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1022: Use of Web Link to Untrusted Target with window.opener Access' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#browser_compatibility - - https://github.com/presidentbeef/brakeman/blob/3f5d5d5/test/apps/rails5/app/views/users/show.html.erb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_reverse_tabnabbing.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: search - paths: - include: - - '*.erb' - patterns: - - pattern: | - _blank - - pattern-inside: | - target: ... - - pattern-not-inside: | - <%= ... rel: 'noopener noreferrer' ...%> - - pattern-either: - - patterns: - - pattern-inside: | - <%= $...INLINERUBYDO do -%> - ... - <% end %> - - metavariable-pattern: - language: ruby - metavariable: $...INLINERUBYDO - patterns: - - pattern: | - link_to ... - - pattern-not: | - link_to "...", "...", ... - - patterns: - - pattern-not-inside: | - <%= ... do - %> - - pattern-inside: | - <%= $...INLINERUBY %> - - metavariable-pattern: - language: ruby - metavariable: $...INLINERUBY - patterns: - - pattern: | - link_to ... - - pattern-not: | - link_to '...', '...', ... - - pattern-not: | - link_to '...', target: ... - severity: WARNING - - id: ruby.rails.security.brakeman.check-secrets.check-secrets - languages: - - ruby - message: Found a Brakeman-style secret - a variable with the name password/secret/api_key/rest_auth_site_key and a non-empty string literal value. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - - https://github.com/presidentbeef/brakeman/blob/3f5d5d5f00864cdf7769c50f5bd26f1769a4ba75/test/apps/rails3.1/app/controllers/users_controller.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_secrets.rb - subcategory: - - vuln - technology: - - ruby - - rails - patterns: - - pattern: $VAR = "$VALUE" - - metavariable-regex: - metavariable: $VAR - regex: (?i)password|secret|(rest_auth_site|api)_key$ - - metavariable-regex: - metavariable: $VALUE - regex: .+ - severity: WARNING - - id: ruby.rails.security.brakeman.check-send-file.check-send-file - languages: - - ruby - message: Allowing user input to `send_file` allows a malicious user to potentially read arbitrary files from the server. Avoid accepting user input in `send_file` or normalize with `File.basename(...)` - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-73: External Control of File Name or Path' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A04:2021 - Insecure Design - references: - - https://owasp.org/www-community/attacks/Path_Traversal - - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_send_file.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern: | - send_file ... - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - severity: ERROR - - id: ruby.rails.security.brakeman.check-sql.check-sql - languages: - - ruby - message: Found potential SQL injection due to unsafe SQL query construction via $X. Where possible, prefer parameterized queries. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/www-community/attacks/SQL_Injection - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/models/product.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_sql.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - patterns: - - pattern: $X - - pattern-either: - - pattern-inside: | - :$KEY => $X - - pattern-inside: | - ["...",$X,...] - - pattern: | - params[...].to_i - - pattern: | - params[...].to_f - - patterns: - - pattern: | - params[...] ? $A : $B - - metavariable-pattern: - metavariable: $A - patterns: - - pattern-not: | - params[...] - - metavariable-pattern: - metavariable: $B - patterns: - - pattern-not: | - params[...] - pattern-sinks: - - patterns: - - pattern: $X - - pattern-not-inside: | - $P.where("...",...) - - pattern-not-inside: | - $P.where(:$KEY => $VAL,...) - - pattern-either: - - pattern-inside: | - $P.$M(...) - - pattern-inside: | - $P.$M("...",...) - - pattern-inside: | - class $P < ActiveRecord::Base - ... - end - - metavariable-regex: - metavariable: $M - regex: (where|find|first|last|select|minimum|maximum|calculate|sum|average) - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - severity: ERROR - - id: ruby.rails.security.brakeman.check-unsafe-reflection-methods.check-unsafe-reflection-methods - languages: - - ruby - message: Found user-controllable input to a reflection method. This may allow a user to alter program behavior and potentially execute arbitrary instructions in the context of the process. Do not provide arbitrary user input to `tap`, `method`, or `to_proc` - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails6/app/controllers/groups_controller.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unsafe_reflection_methods.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern: $X - - pattern-either: - - pattern-inside: | - $X. ... .to_proc - - patterns: - - pattern-inside: | - $Y.method($Z) - - focus-metavariable: $Z - - patterns: - - pattern-inside: | - $Y.tap($Z) - - focus-metavariable: $Z - - patterns: - - pattern-inside: | - $Y.tap{ |$ANY| $Z } - - focus-metavariable: $Z - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - severity: ERROR - - id: ruby.rails.security.brakeman.check-unsafe-reflection.check-unsafe-reflection - languages: - - ruby - message: Found user-controllable input to Ruby reflection functionality. This allows a remote user to influence runtime behavior, up to and including arbitrary remote code execution. Do not provide user-controllable input to reflection functionality. Do not call symbol conversion on user-controllable input. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2021 - Injection - references: - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails2/app/controllers/application_controller.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unsafe_reflection.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern: $X - - pattern-either: - - pattern-inside: | - $X.constantize - - pattern-inside: | - $X. ... .safe_constantize - - pattern-inside: | - const_get(...) - - pattern-inside: | - qualified_const_get(...) - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - severity: ERROR - - id: ruby.rails.security.brakeman.check-unscoped-find.check-unscoped-find - languages: - - ruby - message: Found an unscoped `find(...)` with user-controllable input. If the ActiveRecord model being searched against is sensitive, this may lead to Insecure Direct Object Reference (IDOR) behavior and allow users to read arbitrary records. Scope the find to the current user, e.g. `current_user.accounts.find(params[:id])`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-639: Authorization Bypass Through User-Controlled Key' - impact: HIGH - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/unscoped_find/ - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/controllers/users_controller.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unscoped_find.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $MODEL.find(...) - - pattern: $MODEL.find_by_id(...) - - pattern: $MODEL.find_by_id!(...) - - metavariable-regex: - metavariable: $MODEL - regex: '[A-Z]\S+' - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - severity: WARNING - - id: ruby.rails.security.brakeman.check-validation-regex.check-validation-regex - languages: - - ruby - message: $V Found an incorrectly-bounded regex passed to `validates_format_of` or `validate ... format => ...`. Ruby regex behavior is multiline by default and lines should be terminated by `\A` for beginning of line and `\Z` for end of line, respectively. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-185: Incorrect Regular Expression' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/format_validation/ - - https://github.com/presidentbeef/brakeman/blob/aef6253a8b7bcb97116f2af1ed2a561a6ae35bd5/test/apps/rails3/app/models/account.rb - - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/models/account.rb - source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_validation_regex.rb - subcategory: - - vuln - technology: - - ruby - - rails - mode: search - patterns: - - pattern-either: - - pattern: | - validates ..., :format => <... $V ...>,... - - pattern: | - validates_format_of ..., :with => <... $V ...>,... - - metavariable-regex: - metavariable: $V - regex: /(.{2}(? $X,...) - - focus-metavariable: $X - - patterns: - - pattern: | - "$SQLVERB#{$EXPR}..." - - pattern-not-inside: | - $FUNC("...", "...#{$EXPR}...",...) - - focus-metavariable: $SQLVERB - - pattern-regex: (?i)(select|delete|insert|create|update|alter|drop)\b - - patterns: - - pattern-either: - - pattern: Kernel::sprintf("$SQLSTR", $EXPR) - - pattern: | - "$SQLSTR" + $EXPR - - pattern: | - "$SQLSTR" % $EXPR - - pattern-not-inside: | - $FUNC("...", "...#{$EXPR}...",...) - - focus-metavariable: $EXPR - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b - pattern-sources: - - patterns: - - pattern-either: - - pattern: params - - pattern: request - severity: ERROR - - id: ruby.rails.security.injection.tainted-url-host.tainted-url-host - languages: - - ruby - message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Use the `ssrf_filter` gem and guard the url construction with `SsrfFilter(...)`, or create an allowlist for approved hosts. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: MEDIUM - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - - https://github.com/arkadiyt/ssrf_filter - subcategory: - - vuln - technology: - - rails - mode: taint - pattern-sanitizers: - - pattern: SsrfFilter - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: | - $URLSTR - - pattern-regex: \w+:\/\/#{.*} - - patterns: - - pattern-either: - - pattern: Kernel::sprintf("$URLSTR", ...) - - pattern: | - "$URLSTR" + $EXPR - - pattern: | - "$URLSTR" % $EXPR - - metavariable-pattern: - language: generic - metavariable: $URLSTR - pattern: $SCHEME:// ... - pattern-sources: - - patterns: - - pattern-either: - - pattern: params - - pattern: request - severity: WARNING - - id: rust.lang.security.args-os.args-os - languages: - - rust - message: 'args_os should not be used for security operations. From the docs: "The first element is traditionally the path of the executable, but it can be set to arbitrary text, and might not even exist. This means this property should not be relied upon for security purposes."' - metadata: - category: security - confidence: HIGH - cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' - impact: LOW - likelihood: LOW - references: - - https://doc.rust-lang.org/stable/std/env/fn.args_os.html - subcategory: audit - technology: - - rust - pattern: std::env::args_os() - severity: INFO - - id: rust.lang.security.args.args - languages: - - rust - message: 'args should not be used for security operations. From the docs: "The first element is traditionally the path of the executable, but it can be set to arbitrary text, and might not even exist. This means this property should not be relied upon for security purposes."' - metadata: - category: security - confidence: HIGH - cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' - impact: LOW - likelihood: LOW - references: - - https://doc.rust-lang.org/stable/std/env/fn.args.html - subcategory: audit - technology: - - rust - pattern: std::env::args() - severity: INFO - - id: rust.lang.security.current-exe.current-exe - languages: - - rust - message: 'current_exe should not be used for security operations. From the docs: "The output of this function should not be trusted for anything that might have security implications. Basically, if users can run the executable, they can change the output arbitrarily."' - metadata: - category: security - confidence: HIGH - cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' - impact: LOW - likelihood: LOW - references: - - https://doc.rust-lang.org/stable/std/env/fn.current_exe.html#security - subcategory: audit - technology: - - rust - pattern: std::env::current_exe() - severity: INFO - - id: rust.lang.security.insecure-hashes.insecure-hashes - languages: - - rust - message: Detected cryptographically insecure hashing function - metadata: - category: security - confidence: HIGH - cwe: 'CWE-328: Use of Weak Hash' - impact: MEDIUM - likelihood: LOW - references: - - https://github.com/RustCrypto/hashes - - https://docs.rs/md2/latest/md2/ - - https://docs.rs/md4/latest/md4/ - - https://docs.rs/md5/latest/md5/ - - https://docs.rs/sha-1/latest/sha1/ - subcategory: audit - technology: - - rust - pattern-either: - - pattern: md2::Md2::new(...) - - pattern: md4::Md4::new(...) - - pattern: md5::Md5::new(...) - - pattern: sha1::Sha1::new(...) - severity: WARNING - - id: rust.lang.security.reqwest-accept-invalid.reqwest-accept-invalid - languages: - - rust - message: Dangerously accepting invalid TLS information - metadata: - category: security - confidence: HIGH - cwe: 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: LOW - references: - - https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.danger_accept_invalid_hostnames - - https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.danger_accept_invalid_certs - subcategory: vuln - technology: - - reqwest - pattern-either: - - pattern: reqwest::Client::builder(). ... .danger_accept_invalid_hostnames(true) - - pattern: reqwest::Client::builder(). ... .danger_accept_invalid_certs(true) - severity: WARNING - - id: rust.lang.security.reqwest-set-sensitive.reqwest-set-sensitive - languages: - - rust - message: Set sensitive flag on security headers with 'set_sensitive' to treat data with special care - metadata: - category: security - confidence: MEDIUM - cwe: 'CWE-921: Storage of Sensitive Data in a Mechanism without Access Control' - impact: LOW - likelihood: LOW - references: - - https://docs.rs/reqwest/latest/reqwest/header/struct.HeaderValue.html#method.set_sensitive - subcategory: audit - technology: - - reqwest - patterns: - - pattern: | - let mut $HEADERS = header::HeaderMap::new(); - ... - let $HEADER_VALUE = <... header::HeaderValue::$FROM_FUNC(...) ...>; - ... - $HEADERS.insert($HEADER, $HEADER_VALUE); - - pattern-not: | - let mut $HEADERS = header::HeaderMap::new(); - ... - let $HEADER_VALUE = <... header::HeaderValue::$FROM_FUNC(...) ...>; - ... - $HEADER_VALUE.set_sensitive(true); - ... - $HEADERS.insert($HEADER, $HEADER_VALUE); - - metavariable-pattern: - metavariable: $FROM_FUNC - pattern-either: - - pattern: from_static - - pattern: from_str - - pattern: from_name - - pattern: from_bytes - - pattern: from_maybe_shared - - metavariable-pattern: - metavariable: $HEADER - pattern-either: - - pattern: header::AUTHORIZATION - - pattern: '"Authorization"' - severity: INFO - - id: rust.lang.security.rustls-dangerous.rustls-dangerous - languages: - - rust - message: Dangerous client config used, ensure SSL verification - metadata: - category: security - confidence: HIGH - cwe: 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: LOW - references: - - https://docs.rs/rustls/latest/rustls/client/struct.DangerousClientConfig.html - - https://docs.rs/rustls/latest/rustls/client/struct.ClientConfig.html#method.dangerous - subcategory: vuln - technology: - - rustls - pattern-either: - - pattern: rustls::client::DangerousClientConfig - - pattern: $CLIENT.dangerous().set_certificate_verifier(...) - - pattern: | - let $CLIENT = rustls::client::ClientConfig::dangerous(...); - ... - $CLIENT.set_certificate_verifier(...); - severity: WARNING - - id: rust.lang.security.ssl-verify-none.ssl-verify-none - languages: - - rust - message: SSL verification disabled, this allows for MitM attacks - metadata: - category: security - confidence: HIGH - cwe: 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: LOW - references: - - https://docs.rs/openssl/latest/openssl/ssl/struct.SslContextBuilder.html#method.set_verify - subcategory: vuln - technology: - - openssl - pattern: $BUILDER.set_verify(openssl::ssl::SSL_VERIFY_NONE) - severity: WARNING - - id: rust.lang.security.temp-dir.temp-dir - languages: - - rust - message: 'temp_dir should not be used for security operations. From the docs: ''The temporary directory may be shared among users, or between processes with different privileges; thus, the creation of any files or directories in the temporary directory must use a secure method to create a uniquely named file. Creating a file or directory with a fixed or predictable name may result in “insecure temporary file” security vulnerabilities.''' - metadata: - category: security - confidence: HIGH - cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' - impact: LOW - likelihood: LOW - references: - - https://doc.rust-lang.org/stable/std/env/fn.temp_dir.html - subcategory: audit - technology: - - rust - pattern: std::env::temp_dir() - severity: INFO - - id: rust.lang.security.unsafe-usage.unsafe-usage - languages: - - rust - message: Detected 'unsafe' usage, please audit for secure usage - metadata: - category: security - confidence: HIGH - cwe: 'CWE-242: Use of Inherently Dangerous Function' - impact: LOW - likelihood: LOW - references: - - https://doc.rust-lang.org/std/keyword.unsafe.html - subcategory: audit - technology: - - rust - pattern: unsafe { ... } - severity: INFO - - id: scala.jwt-scala.security.jwt-scala-hardcode.jwt-scala-hardcode - languages: - - scala - message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://jwt-scala.github.io/jwt-scala/ - subcategory: - - vuln - technology: - - scala - patterns: - - pattern-inside: | - import pdi.jwt.$DEPS - ... - - pattern-either: - - pattern: $JWT.encode($X, "...", ...) - - pattern: $JWT.decode($X, "...", ...) - - pattern: $JWT.decodeRawAll($X, "...", ...) - - pattern: $JWT.decodeRaw($X, "...", ...) - - pattern: $JWT.decodeAll($X, "...", ...) - - pattern: $JWT.validate($X, "...", ...) - - pattern: $JWT.isValid($X, "...", ...) - - pattern: $JWT.decodeJson($X, "...", ...) - - pattern: $JWT.decodeJsonAll($X, "...", ...) - - patterns: - - pattern-either: - - pattern: $JWT.encode($X, $KEY, ...) - - pattern: $JWT.decode($X, $KEY, ...) - - pattern: $JWT.decodeRawAll($X, $KEY, ...) - - pattern: $JWT.decodeRaw($X, $KEY, ...) - - pattern: $JWT.decodeAll($X, $KEY, ...) - - pattern: $JWT.validate($X, $KEY, ...) - - pattern: $JWT.isValid($X, $KEY, ...) - - pattern: $JWT.decodeJson($X, $KEY, ...) - - pattern: $JWT.decodeJsonAll($X, $KEY, ...) - - pattern: $JWT.encode($X, this.$KEY, ...) - - pattern: $JWT.decode($X, this.$KEY, ...) - - pattern: $JWT.decodeRawAll($X, this.$KEY, ...) - - pattern: $JWT.decodeRaw($X, this.$KEY, ...) - - pattern: $JWT.decodeAll($X, this.$KEY, ...) - - pattern: $JWT.validate($X, this.$KEY, ...) - - pattern: $JWT.isValid($X, this.$KEY, ...) - - pattern: $JWT.decodeJson($X, this.$KEY, ...) - - pattern: $JWT.decodeJsonAll($X, this.$KEY, ...) - - pattern-either: - - pattern-inside: | - class $CL { - ... - $KEY = "..." - ... - } - - pattern-inside: | - object $CL { - ... - $KEY = "..." - ... - } - - metavariable-pattern: - metavariable: $JWT - patterns: - - pattern-either: - - pattern: Jwt - - pattern: JwtArgonaut - - pattern: JwtCirce - - pattern: JwtJson4s - - pattern: JwtJson - - pattern: JwtUpickle - severity: WARNING - - id: scala.lang.correctness.positive-number-index-of.positive-number-index-of - languages: - - scala - message: Flags scala code that look for values that are greater than 0. This ignores the first element, which is most likely a bug. Instead, use indexOf with -1. If the intent is to check the inclusion of a value, use the contains method instead. - metadata: - category: correctness - confidence: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://blog.codacy.com/9-scala-security-issues/ - technology: - - scala - patterns: - - pattern-either: - - patterns: - - pattern: | - $OBJ.indexOf(...) > $VALUE - - metavariable-comparison: - comparison: $VALUE >= 0 - metavariable: $VALUE - - patterns: - - pattern: | - $OBJ.indexOf(...) >= $SMALLERVAL - - metavariable-comparison: - comparison: $SMALLERVAL > 0 - metavariable: $SMALLERVAL - severity: WARNING - - id: scala.lang.security.audit.dangerous-seq-run.dangerous-seq-run - languages: - - scala - message: Found dynamic content used for the external process. This is dangerous if arbitrary data can reach this function call because it allows a malicious actor to execute commands. Ensure your variables are not controlled by users or sufficiently sanitized. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - scala - patterns: - - pattern: Seq($CMD, ...) - - pattern-not: Seq("...", ...) - - pattern-inside: | - import sys.process - ... - - pattern-not-inside: | - $CMD = "..." - ... - - pattern-either: - - pattern-inside: Seq(...).! - - pattern-inside: Seq(...).!! - - pattern-inside: Seq(...).lazyLines - severity: ERROR - - id: scala.lang.security.audit.dangerous-shell-run.dangerous-shell-run - languages: - - scala - message: Found dynamic content used for the external process. This is dangerous if arbitrary data can reach this function call because it allows a malicious actor to execute commands. Ensure your variables are not controlled by users or sufficiently sanitized. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - scala - patterns: - - pattern: Seq($SH, "-c", $CMD, ...) - - pattern-not: Seq($SH, "-c", "...", ...) - - pattern-inside: | - import sys.process - ... - - pattern-not-inside: | - $CMD = "..." - ... - - pattern-either: - - pattern-inside: Seq(...).! - - pattern-inside: Seq(...).!! - - pattern-inside: Seq(...).lazyLines - - metavariable-regex: - metavariable: $SH - regex: '"(sh|bash|ksh|csh|tcsh|zsh)"' - severity: ERROR - - id: scala.lang.security.audit.dispatch-ssrf.dispatch-ssrf - languages: - - scala - message: A parameter being passed directly into `url` most likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server running this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - - https://dispatchhttp.org/Dispatch.html - subcategory: - - audit - technology: - - scala - - dispatch - patterns: - - pattern: url($URL) - - pattern-inside: | - import dispatch._ - ... - - pattern-either: - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = $A { - ... - } - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = { - ... - } - severity: WARNING - - id: scala.lang.security.audit.documentbuilder-dtd-enabled.documentbuilder-dtd-enabled - languages: - - scala - message: Document Builder being instantiated without calling the `setFeature` functions that are generally used for disabling entity processing. User controlled data in XML Document builder can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - scala - patterns: - - pattern-either: - - pattern: | - $DF = DocumentBuilderFactory.newInstance(...) - ... - $DB = $DF.newDocumentBuilder(...) - - patterns: - - pattern: $DB = DocumentBuilderFactory.newInstance(...) - - pattern-not-inside: | - ... - $X = $DB.newDocumentBuilder(...) - - pattern: $DB = DocumentBuilderFactory.newInstance(...).newDocumentBuilder(...) - - pattern-not-inside: | - ... - $DB.setXIncludeAware(true) - ... - $DB.setNamespaceAware(true) - ... - $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - - pattern-not-inside: | - ... - $DB.setXIncludeAware(true) - ... - $DB.setNamespaceAware(true) - ... - $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - ... - $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) - - pattern-not-inside: | - ... - $DB.setXIncludeAware(true) - ... - $DB.setNamespaceAware(true) - ... - $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - - pattern-not-inside: | - ... - $DB.setXIncludeAware(true) - ... - $DB.setNamespaceAware(true) - ... - $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - ... - $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - severity: WARNING - - id: scala.lang.security.audit.insecure-random.insecure-random - languages: - - scala - message: Flags the use of a predictable random value from `scala.util.Random`. This can lead to vulnerabilities when used in security contexts, such as in a CSRF token, password reset token, or any other secret value. To fix this, use java.security.SecureRandom instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-330: Use of Insufficiently Random Values' - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - resources: - - https://find-sec-bugs.github.io/bugs.htm - subcategory: - - audit - technology: - - scala - - cryptography - patterns: - - pattern: | - import scala.util.Random - severity: WARNING - - id: scala.lang.security.audit.io-source-ssrf.io-source-ssrf - languages: - - scala - message: A parameter being passed directly into `fromURL` most likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server running this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - - https://www.scala-lang.org/api/current/scala/io/Source$.html#fromURL(url:java.net.URL)(implicitcodec:scala.io.Codec):scala.io.BufferedSource - subcategory: - - audit - technology: - - scala - patterns: - - pattern-either: - - pattern: Source.fromURL($URL,...) - - pattern: Source.fromURI($URL,...) - - pattern-inside: | - import scala.io.$SOURCE - ... - - pattern-either: - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = $A { - ... - } - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = { - ... - } - severity: WARNING - - id: scala.lang.security.audit.path-traversal-fromfile.path-traversal-fromfile - languages: - - scala - message: Flags cases of possible path traversal. If an unfiltered parameter is passed into 'fromFile', file from an arbitrary filesystem location could be read. This could lead to sensitive data exposure and other provles. Instead, sanitize the user input instead of performing direct string concatenation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - resources: - - https://find-sec-bugs.github.io/bugs.htm - subcategory: - - audit - technology: - - scala - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - $FILENAME = "..." + $VAR - ... - - pattern-inside: | - $FILENAME = $VAR + "..." - ... - - pattern-inside: | - $FILENAME = $STR.concat($VAR) - ... - - pattern-inside: | - $FILENAME = "...".format(..., $VAR, ...) - ... - - pattern: Source.fromFile($FILENAME, ...) - - patterns: - - pattern-either: - - pattern: Source.fromFile("..." + $VAR, ...) - - pattern: Source.fromFile($VAR + "...", ...) - - pattern: Source.fromFile($STR.concat($VAR), ...) - - pattern: Source.fromFile("...".format(..., $VAR, ...), ...) - - pattern-inside: | - def $FUNC(..., $VAR: $TYPE, ...) = Action { - ... - } - severity: WARNING - - id: scala.lang.security.audit.rsa-padding-set.rsa-padding-set - languages: - - scala - message: Usage of RSA without OAEP (Optimal Asymmetric Encryption Padding) may weaken encryption. This could lead to sensitive data exposure. Instead, use RSA with `OAEPWithMD5AndMGF1Padding` instead. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-780: Use of RSA Algorithm without OAEP' - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - resources: - - https://blog.codacy.com/9-scala-security-issues/ - subcategory: - - audit - technology: - - scala - - cryptography - patterns: - - pattern: | - $VAR = $CIPHER.getInstance($MODE) - - metavariable-regex: - metavariable: $MODE - regex: .*RSA/.*/NoPadding.* - severity: WARNING - - id: scala.lang.security.audit.sax-dtd-enabled.sax-dtd-enabled - languages: - - scala - message: XML processor being instantiated without calling the `setFeature` functions that are generally used for disabling entity processing. User controlled data in XML Parsers can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - scala - patterns: - - pattern-either: - - pattern: $SR = new SAXReader(...) - - pattern: | - $SF = SAXParserFactory.newInstance(...) - ... - $SR = $SF.newSAXParser(...) - - patterns: - - pattern: $SR = SAXParserFactory.newInstance(...) - - pattern-not-inside: | - ... - $X = $SR.newSAXParser(...) - - pattern: $SR = SAXParserFactory.newInstance(...).newSAXParser(...) - - pattern: $SR = new SAXBuilder(...) - - pattern-not-inside: | - ... - $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - - pattern-not-inside: | - ... - $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - ... - $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) - - pattern-not-inside: | - ... - $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - - pattern-not-inside: | - ... - $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) - ... - $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) - ... - $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - severity: WARNING - - id: scala.lang.security.audit.scala-dangerous-process-run.scala-dangerous-process-run - languages: - - scala - message: Found dynamic content used for the external process. This is dangerous if arbitrary data can reach this function call because it allows a malicious actor to execute commands. Use `Seq(...)` for dynamically generated commands. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - scala - patterns: - - pattern-either: - - pattern: $X.! - - pattern: $X.!! - - pattern: $X.lazyLines - - pattern-inside: | - import sys.process - ... - - pattern-not: | - "...".! - - pattern-not: | - "...".!! - - pattern-not: | - "...".lazyLines - - pattern-not: | - Seq(...).! - - pattern-not: | - Seq(...).!! - - pattern-not: | - Seq(...).lazyLines - - pattern-not-inside: | - val $X = "..." - ... - - pattern-not-inside: | - val $X = Seq(...) - ... - severity: ERROR - - id: scala.lang.security.audit.scalac-debug.scalac-debug - languages: - - generic - message: Scala applications built with `debug` set to true in production may leak debug information to attackers. Debug mode also affects performance and reliability. Remove it from configuration. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-489: Active Debug Code' - impact: LOW - likelihood: LOW - owasp: A05:2021 - Security Misconfiguration - references: - - https://docs.scala-lang.org/overviews/compiler-options/index.html - subcategory: - - audit - technology: - - scala - - sbt - paths: - include: - - '*.sbt*' - patterns: - - pattern-either: - - pattern: scalacOptions ... "-Vdebug" - - pattern: scalacOptions ... "-Ydebug" - severity: WARNING - - id: scala.lang.security.audit.scalaj-http-ssrf.scalaj-http-ssrf - languages: - - scala - message: A parameter being passed directly into `Http` can likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server running this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - - https://github.com/scalaj/scalaj-http#simplified-http - subcategory: - - audit - technology: - - scala - - scalaj-http - patterns: - - pattern: Http($URL) - - pattern-inside: | - import scalaj.http.$HTTP - ... - - pattern-either: - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = $A { - ... - } - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = { - ... - } - severity: WARNING - - id: scala.lang.security.audit.scalajs-eval.scalajs-eval - languages: - - scala - message: '`eval()` function evaluates JavaScript code represented as a string. Executing JavaScript from a string is an enormous security risk. It is far too easy for a bad actor to run arbitrary code when you use `eval()`. Do not use eval(). Alternatively: Ensure evaluated content is not definable by external sources. If it’s not possible, strip everything except alphanumeric characters from an input provided for the command string and arguments.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A03:2021 - Injection - references: - - https://www.scala-js.org/doc/ - subcategory: - - vuln - technology: - - scala - - scala-js - mode: taint - pattern-sinks: - - patterns: - - pattern: $JS.eval(...) - - pattern-inside: | - import scala.scalajs.$X - ... - pattern-sources: - - patterns: - - pattern: $PARAM - - pattern-either: - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = $A { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = $A(...) { - ... - } - severity: WARNING - - id: scala.lang.security.audit.tainted-sql-string.tainted-sql-string - languages: - - scala - message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html - subcategory: - - vuln - technology: - - scala - mode: taint - pattern-sanitizers: - - pattern-either: - - patterns: - - pattern-either: - - pattern: $LOGGER.$METHOD(...) - - pattern: $LOGGER(...) - - metavariable-regex: - metavariable: $LOGGER - regex: (i?)log.* - - patterns: - - pattern: $LOGGER.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (i?)(trace|info|warn|warning|warnToError|error|debug) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR".format(...) - - patterns: - - pattern-inside: | - $SB = new StringBuilder("$SQLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$SQLSTR" - ... - - pattern: $VAR += ... - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b - - patterns: - - pattern-either: - - pattern: s"..." - - pattern: f"..." - - pattern-regex: | - .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - - pattern-not-inside: println(...) - pattern-sources: - - patterns: - - pattern: $PARAM - - pattern-either: - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = $A { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = $A(...) { - ... - } - severity: ERROR - - id: scala.lang.security.audit.xmlinputfactory-dtd-enabled.xmlinputfactory-dtd-enabled - languages: - - scala - message: XMLInputFactory being instantiated without calling the setProperty functions that are generally used for disabling entity processing. User controlled data in XML Document builder can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-611: Improper Restriction of XML External Entity Reference' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2017 - XML External Entities (XXE) - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - subcategory: - - audit - technology: - - scala - patterns: - - pattern-not-inside: | - ... - $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", false) - - pattern-either: - - pattern: $XMLFACTORY = XMLInputFactory.newFactory(...) - - pattern: $XMLFACTORY = XMLInputFactory.newInstance(...) - - pattern: $XMLFACTORY = new XMLInputFactory(...) - severity: WARNING - - id: scala.play.security.conf-csrf-headers-bypass.conf-csrf-headers-bypass - languages: - - generic - message: Possibly bypassable CSRF configuration found. CSRF is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. Make sure that Content-Type black list is configured and CORS filter is turned on. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-352: Cross-Site Request Forgery (CSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://www.playframework.com/documentation/2.8.x/Migration25#CSRF-changes - - https://owasp.org/www-community/attacks/csrf - subcategory: - - vuln - technology: - - scala - - play - paths: - include: - - '*.conf' - patterns: - - pattern-either: - - pattern: X-Requested-With = "*" - - pattern: Csrf-Token = "..." - - pattern-inside: | - bypassHeaders {... - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."application/x-www-form-urlencoded"..."multipart/form-data"..."text/plain"...] - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."application/x-www-form-urlencoded"..."text/plain"..."multipart/form-data"...] - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."multipart/form-data"..."application/x-www-form-urlencoded"..."text/plain"...] - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."multipart/form-data"..."text/plain"..."application/x-www-form-urlencoded"...] - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."text/plain"..."application/x-www-form-urlencoded"..."multipart/form-data"...] - ... - ...} - - pattern-not-inside: | - {... - ... - ...blackList = [..."text/plain"..."multipart/form-data"..."application/x-www-form-urlencoded"...] - ... - ...} - severity: ERROR - - id: scala.play.security.conf-insecure-cookie-settings.conf-insecure-cookie-settings - languages: - - generic - message: Session cookie `Secure` flag is explicitly disabled. The `secure` flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the `Secure` flag by setting `secure` to `true` in configuration file. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#security - - https://www.playframework.com/documentation/2.8.x/SettingsSession#Session-Configuration - subcategory: - - vuln - technology: - - play - - scala - paths: - include: - - '*.conf' - patterns: - - pattern: secure = false - - pattern-inside: | - session = { - ... - } - severity: WARNING - - id: scala.play.security.tainted-html-response.tainted-html-response - languages: - - scala - message: Detected a request with potential user-input going into an `Ok()` response. This bypasses any view or template environments, including HTML escaping, which may expose this application to cross-site scripting (XSS) vulnerabilities. Consider using a view technology such as Twirl which automatically escapes HTML views. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - vuln - technology: - - scala - - play - mode: taint - pattern-sanitizers: - - pattern-either: - - pattern: org.apache.commons.lang3.StringEscapeUtils.escapeHtml4(...) - - pattern: org.owasp.encoder.Encode.forHtml(...) - pattern-sinks: - - pattern-either: - - pattern: Html.apply(...) - - pattern: Ok(...).as(HTML) - - pattern: Ok(...).as(ContentTypes.HTML) - - patterns: - - pattern: Ok(...).as($CTYPE) - - metavariable-regex: - metavariable: $CTYPE - regex: '"[tT][eE][xX][tT]/[hH][tT][mM][lL]"' - - patterns: - - pattern: Ok(...).as($CTYPE) - - pattern-not: Ok(...).as("...") - - pattern-either: - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = $A { - ... - } - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = { - ... - } - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern: $REQ - - pattern-either: - - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - patterns: - - pattern: $PARAM - - pattern-either: - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { - ... - } - severity: WARNING - - id: scala.play.security.tainted-slick-sqli.tainted-slick-sqli - languages: - - scala - message: Detected a tainted SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Avoid using using user input for generating SQL strings. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://scala-slick.org/doc/3.3.3/sql.html#splicing-literal-values - - https://scala-slick.org/doc/3.2.0/sql-to-slick.html#non-optimal-sql-code - subcategory: - - vuln - technology: - - scala - - slick - - play - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $MODEL.overrideSql(...) - - pattern: sql"..." - - pattern-inside: | - import slick.$DEPS - ... - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern: $REQ - - pattern-either: - - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - patterns: - - pattern: $PARAM - - pattern-either: - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { - ... - } - severity: ERROR - - id: scala.play.security.tainted-sql-from-http-request.tainted-sql-from-http-request - languages: - - scala - message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html - subcategory: - - vuln - technology: - - scala - - play - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - "$SQLSTR" + ... - - pattern: | - "$SQLSTR".format(...) - - patterns: - - pattern-inside: | - $SB = new StringBuilder("$SQLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$SQLSTR" - ... - - pattern: $VAR += ... - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop)\b - - patterns: - - pattern: s"..." - - pattern-regex: | - .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* - - pattern-not-inside: println(...) - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern: $REQ - - pattern-either: - - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" - - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" - - patterns: - - pattern: $PARAM - - pattern-either: - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { - ... - } - - pattern-inside: | - def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { - ... - } - severity: ERROR - - id: scala.play.security.twirl-html-var.twirl-html-var - languages: - - generic - message: Raw html content controlled by a variable detected. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. Try to avoid using `Html()` or consider properly sanitizing input data. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://www.playframework.com/documentation/2.8.x/ScalaTemplates#Escaping - subcategory: - - audit - technology: - - scala - - play - - twirl - paths: - include: - - '*.html' - patterns: - - pattern-either: - - pattern: | - @Html($VAL) - - pattern: | - @Html(...$VAL + ...) - - pattern: | - @Html(... + $VAL...) - - metavariable-regex: - metavariable: $VAL - regex: \w* - severity: WARNING - - id: scala.play.security.webservice-ssrf.webservice-ssrf - languages: - - scala - message: A parameter being passed directly into `WSClient` most likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server running this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts hardcode the correct host. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - - https://www.playframework.com/documentation/2.8.x/ScalaWS - subcategory: - - audit - technology: - - scala - - play - patterns: - - pattern: $WS.url($URL) - - pattern-either: - - pattern-inside: | - class $CLASS (..., $WS: WSClient, ...) { - ... - } - - pattern-inside: | - def $FUNC(..., $WS: WSClient, ...) = { - ... - } - - pattern-inside: | - $WS = AhcWSClient(...) - ... - - pattern-either: - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = $A { - ... - } - - pattern-inside: | - def $FUNC(..., $URL: $T, ...) = { - ... - } - severity: WARNING - - id: scala.scala-jwt.security.jwt-hardcode.scala-jwt-hardcoded-secret - languages: - - scala - message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: - - audit - technology: - - jwt - pattern-either: - - pattern: | - com.auth0.jwt.algorithms.Algorithm.HMAC256("..."); - - pattern: | - $SECRET = "..."; - ... - com.auth0.jwt.algorithms.Algorithm.HMAC256($SECRET); - - pattern: | - class $CLASS { - ... - $DECL $SECRET = "..."; - ... - def $FUNC (...): $RETURNTYPE = { - ... - com.auth0.jwt.algorithms.Algorithm.HMAC256($SECRET); - ... - } - ... - } - - pattern: | - com.auth0.jwt.algorithms.Algorithm.HMAC384("..."); - - pattern: | - $SECRET = "..."; - ... - com.auth0.jwt.algorithms.Algorithm.HMAC384($SECRET); - - pattern: | - class $CLASS { - ... - $DECL $SECRET = "..."; - ... - def $FUNC (...): $RETURNTYPE = { - ... - com.auth0.jwt.algorithms.Algorithm.HMAC384($SECRET); - ... - } - ... - } - - pattern: | - com.auth0.jwt.algorithms.Algorithm.HMAC512("..."); - - pattern: | - $SECRET = "..."; - ... - com.auth0.jwt.algorithms.Algorithm.HMAC512($SECRET); - - pattern: | - class $CLASS { - ... - $DECL $SECRET = "..."; - ... - def $FUNC (...): $RETURNTYPE = { - ... - com.auth0.jwt.algorithms.Algorithm.HMAC512($SECRET); - ... - } - ... - } - severity: ERROR - - id: scala.slick.security.scala-slick-overridesql-literal.scala-slick-overridesql-literal - languages: - - scala - message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Avoid using non literal values in `overrideSql(...)`. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - subcategory: - - audit - technology: - - scala - - slick - patterns: - - pattern: $MODEL.overrideSql($QUERY,...) - - pattern-not: $MODEL.overrideSql("...",...) - - pattern-not-inside: | - $QUERY = "..." - ... - severity: ERROR - - id: scala.slick.security.scala-slick-sql-non-literal.scala-slick-sql-non-literal - languages: - - scala - message: Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Avoid using `#$variable` and use `$variable` in `sql"..."` strings instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://scala-slick.org/doc/3.3.3/sql.html#splicing-literal-values - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SCALA_SQL_INJECTION_SLICK - subcategory: - - audit - technology: - - scala - - slick - patterns: - - pattern: sql"..." - - pattern-regex: \#\$ - - pattern-inside: | - import slick.$DEPS - ... - severity: ERROR - - id: swift.lang.crypto.insecure-random.insecure-random - languages: - - swift - message: A random number generator was detected which is **not** *guaranteed* to be Cryptographically secure. If the source of entropy is used for security purposes (e.g. with other Cryptographic operations), make sure to use the `SecCopyRandomBytes` API explicitly. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)' - impact: LOW - likelihood: LOW - masvs: - - 'MSTG-CRYPTO-6: All random values are generated using a sufficiently secure random number generator.' - owasp: - - A02:2021 - Cryptographic Failures - references: - - https://mobile-security.gitbook.io/masvs/security-requirements/0x08-v3-cryptography_verification_requirements - - https://developer.apple.com/documentation/security/1399291-secrandomcopybytes - - https://developer.apple.com/documentation/security/randomization_services?language=swift - - https://github.com/apple/swift-evolution/blob/main/proposals/0202-random-unification.md - subcategory: - - audit - technology: - - ios - - macos - pattern-either: - - pattern: random() - - pattern: Int.random(...) - - pattern: Bool.random(...) - - pattern: Float.random(...) - - pattern: Double.random(...) - - pattern: arc4random() - - pattern: arc4random_buf(...) - - pattern: arc4random_uniform(...) - - pattern: SystemRandomNumberGenerator(...) - - pattern: rand() - severity: WARNING - - id: swift.lang.storage.sensitive-storage-userdefaults.swift-user-defaults - languages: - - swift - message: Potentially sensitive data was observed to be stored in UserDefaults, which is not adequate protection of sensitive information. For data of a sensitive nature, applications should leverage the Keychain. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW - masvs: - - 'MASVS-STORAGE-1: The app securely stores sensitive data' - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html - - https://mas.owasp.org/MASVS/controls/MASVS-STORAGE-1/ - subcategory: - - vuln - technology: - - ios - - macos - options: - symbolic_propagation: true - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $VALUE - regex: (?i).*(passcode|password|pass_word|passphrase|pass_code|pass_word|pass_phrase)$ - - focus-metavariable: $VALUE - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $KEY - regex: (?i).*(passcode|password|pass_word|passphrase|pass_code|pass_word|pass_phrase)$ - - focus-metavariable: $KEY - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $VALUE - regex: (?i).*(api_key|apikey)$ - - focus-metavariable: $VALUE - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $KEY - regex: (?i).*(api_key|apikey)$ - - focus-metavariable: $KEY - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $VALUE - regex: (?i).*(secretkey|secret_key|secrettoken|secret_token|clientsecret|client_secret)$ - - focus-metavariable: $VALUE - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $KEY - regex: (?i).*(secretkey|secret_key|secrettoken|secret_token|clientsecret|client_secret)$ - - focus-metavariable: $KEY - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $VALUE - regex: (?i).*(cryptkey|cryptokey|crypto_key|cryptionkey|symmetrickey|privatekey|symmetric_key|private_key)$ - - focus-metavariable: $VALUE - - patterns: - - pattern-either: - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: "$KEY") - - pattern: | - UserDefaults.standard.set("$VALUE", forKey: $KEY) - - pattern: | - UserDefaults.standard.set($VALUE, forKey: "$KEY") - - pattern: | - UserDefaults.standard.set($VALUE, forKey: $KEY) - - metavariable-regex: - metavariable: $KEY - regex: (?i).*(cryptkey|cryptokey|crypto_key|cryptionkey|symmetrickey|privatekey|symmetric_key|private_key)$ - - focus-metavariable: $KEY - severity: WARNING - - id: swift.sqllite.sqllite-injection-audit.swift-potential-sqlite-injection - languages: - - swift - message: Potential Client-side SQL injection which has different impacts depending on the SQL use-case. The impact may include the circumvention of local authentication mechanisms, obtaining of sensitive data from the app, or manipulation of client-side behavior. It wasn't possible to make certain that the source is untrusted, but the application should avoid concatenating dynamic data into SQL queries and should instead leverage parameterized queries. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' - impact: MEDIUM - likelihood: MEDIUM - masvs: - - 'MASVS-CODE-4: The app validates and sanitizes all untrusted inputs.' - references: - - https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html - subcategory: - - vuln - technology: - - ios - - macos - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: sqlite3_exec($DB, $SQL, ...) - - pattern: sqlite3_prepare_v2($DB, $SQL, ...) - - focus-metavariable: - - $SQL - pattern-sources: - - pattern-either: - - pattern: | - "...\($X)..." - - pattern: | - $SQL = "..." + $X - - pattern: | - $SQL = $X + "..." - severity: WARNING - - id: swift.webview.webview-js-window.swift-webview-config-allows-js-open-windows - languages: - - swift - message: Webviews were observed that explictly allow JavaScript in an WKWebview to open windows automatically. Consider disabling this functionality if not required, following the principle of least privelege. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-272: Least Privilege Violation' - impact: LOW - likelihood: LOW - masvs: - - 'MASVS-PLATFORM-2: The app uses WebViews securely' - references: - - https://mas.owasp.org/MASVS/controls/MASVS-PLATFORM-2/ - - https://developer.apple.com/documentation/webkit/wkpreferences/1536573-javascriptcanopenwindowsautomati - subcategory: - - audit - technology: - - ios - - macos - patterns: - - pattern: | - $P = WKPreferences() - ... - - pattern-either: - - patterns: - - pattern-inside: | - $P.JavaScriptCanOpenWindowsAutomatically = $FALSE - ... - $P.JavaScriptCanOpenWindowsAutomatically = $TRUE - - pattern-not-inside: | - ... - $P.JavaScriptCanOpenWindowsAutomatically = $TRUE - ... - $P.JavaScriptCanOpenWindowsAutomatically = $FALSE - - pattern: | - $P.JavaScriptCanOpenWindowsAutomatically = true - - metavariable-regex: - metavariable: $TRUE - regex: ^(true)$ - - metavariable-regex: - metavariable: $TRUE - regex: (.*(?!true)) - - patterns: - - pattern: | - $P.JavaScriptCanOpenWindowsAutomatically = true - - pattern-not-inside: | - ... - $P.JavaScriptCanOpenWindowsAutomatically = ... - ... - $P.JavaScriptCanOpenWindowsAutomatically = ... - severity: WARNING - - id: terraform.aws.best-practice.aws-elasticache-automatic-backup-not-enabled.aws-elasticache-automatic-backup-not-enabled - languages: - - hcl - message: Ensure that Amazon ElastiCache clusters have automatic backup turned on. To fix this, set a `snapshot_retention_limit`. - metadata: - category: best-practice - technology: - - terraform - - aws - patterns: - - pattern-either: - - patterns: - - pattern: | - resource "aws_elasticache_cluster" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_elasticache_cluster" $ANYTHING { - ... - engine = "memcached" - ... - } - - pattern-not-inside: | - resource "aws_elasticache_cluster" $ANYTHING { - ... - snapshot_retention_limit = ... - ... - } - - patterns: - - pattern: | - resource "aws_elasticache_cluster" $ANYTHING { - ... - snapshot_retention_limit = $LIMIT - ... - } - - metavariable-comparison: - comparison: $LIMIT == 0 - metavariable: $LIMIT - severity: WARNING - - id: terraform.aws.best-practice.aws-qldb-inadequate-ledger-permissions-mode.aws-qldb-inadequate-ledger-permissions-mode - languages: - - hcl - message: The AWS QLDB ledger permissions are too permissive. Consider using "'STANDARD'" permissions mode if possible. - metadata: - category: best-practice - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_qldb_ledger" $ANYTHING { - ... - permissions_mode = "ALLOW_ALL" - ... - } - severity: WARNING - - id: terraform.aws.best-practice.aws-rds-cluster-iam-authentication-not-enabled.aws-rds-cluster-iam-authentication-not-enabled - languages: - - hcl - message: The AWS RDS Cluster is not configured to use IAM authentication. Consider using IAM for authentication. - metadata: - category: best-practice - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_rds_cluster" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_rds_cluster" $ANYTHING { - ... - iam_database_authentication_enabled = true - ... - } - severity: WARNING - - id: terraform.aws.best-practice.aws-rds-iam-authentication-not-enabled.aws-rds-iam-authentication-not-enabled - languages: - - hcl - message: The AWS RDS is not configured to use IAM authentication. Consider using IAM for authentication. - metadata: - category: best-practice - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_db_instance" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_db_instance" $ANYTHING { - ... - iam_database_authentication_enabled = true - ... - } - severity: WARNING - - id: terraform.aws.best-practice.aws-rds-multiaz-not-enabled.aws-rds-multiaz-not-enabled - languages: - - hcl - message: The AWS RDS is not configured to use multi-az. Consider using it if possible. - metadata: - category: best-practice - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_db_instance" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_db_instance" $ANYTHING { - ... - multi_az = true - ... - } - severity: WARNING - - id: terraform.aws.best-practice.aws-s3-bucket-versioning-not-enabled.aws-s3-bucket-versioning-not-enabled - languages: - - hcl - message: Ensure that Amazon S3 bucket versioning is not enabled. Consider using versioning if you don't have alternative backup mechanism. - metadata: - category: best-practice - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_s3_bucket" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_s3_bucket" $ANYTHING { - ... - versioning { - ... - enabled = true - ... - } - ... - } - - pattern-not-inside: | - resource "aws_s3_bucket" $ANYTHING { - ... - versioning { - ... - enabled = var.$X - ... - } - ... - } - severity: WARNING - - id: terraform.aws.best-practice.aws-s3-object-lock-not-enabled.aws-s3-object-lock-not-enabled - languages: - - hcl - message: The AWS S3 object lock is not enabled. Consider using it if possible. - metadata: - category: best-practice - technology: - - terraform - - aws - patterns: - - pattern-either: - - pattern: | - resource "aws_s3_bucket" $ANYTHING { - ... - object_lock_configuration = { - object_lock_enabled = "Disabled" - } - ... - } - - pattern: | - resource "aws_s3_bucket" $ANYTHING { - ... - object_lock_configuration { - object_lock_enabled = "Disabled" - } - ... - } - severity: WARNING - - id: terraform.aws.best-practice.missing-alb-drop-http-headers.missing-alb-drop-http-headers - languages: - - hcl - message: Detected a AWS load balancer that is not configured to drop invalid HTTP headers. Add `drop_invalid_header_fields = true` in your resource block. - metadata: - category: best-practice - technology: - - aws - - terraform - patterns: - - pattern-either: - - pattern: | - resource "aws_lb" $ENABLED { - ... - } - - pattern: | - resource "aws_alb" $ENABLED { - ... - } - - pattern-not-inside: | - resource $ANYTHING $ENABLED { - ... - drop_invalid_header_fields = true - ... - } - severity: WARNING - - id: terraform.aws.best-practice.missing-api-gateway-cache-cluster.missing-api-gateway-cache-cluster - languages: - - hcl - message: Found a AWS API Gateway Stage without cache cluster enabled. Enabling the cache cluster feature enhances responsiveness of your API. Add `cache_cluster_enabled = true` to your resource block. - metadata: - category: best-practice - technology: - - aws - - terraform - patterns: - - pattern: | - resource "aws_api_gateway_stage" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_api_gateway_stage" $ANYTHING { - ... - cache_cluster_enabled = true - ... - } - severity: WARNING - - id: terraform.aws.best-practice.missing-autoscaling-group-tags.missing-autoscaling-group-tags - languages: - - hcl - message: |- - There are missing tags for an AWS Auto Scaling group. Tags help track costs, allow for filtering for Auto Scaling groups, help with access control, and aid in organizing AWS resources. Add: `tag { - key = "key" - value = "value" - propagate_at_launch = boolean - }` See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group for more details. - metadata: - category: best-practice - technology: - - aws - - terraform - patterns: - - patterns: - - patterns: - - pattern: resource "aws_autoscaling_group" $ANYTHING {...} - - pattern-not-inside: | - resource "aws_autoscaling_group" $ANYTHING { - ... - tag {...} - ... - } - - patterns: - - pattern: resource "aws_autoscaling_group" $ANYTHING {...} - - pattern-not-inside: | - resource "aws_autoscaling_group" $ANYTHING { - ... - tags = concat(...) - ... - } - severity: WARNING - - id: terraform.aws.best-practice.missing-aws-autoscaling-tags.missing-aws-autoscaling-tags - languages: - - hcl - message: The AWS Autoscaling Group is not tagged. - metadata: - category: best-practice - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_autoscaling_group" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_autoscaling_group" $ANYTHING { - ... - tag { - ... - } - ... - } - - pattern-not-inside: | - resource "aws_autoscaling_group" $ANYTHING { - ... - tags = concat( - ... - ) - ... - } - severity: WARNING - - id: terraform.aws.best-practice.missing-aws-cross-zone-lb.missing-aws-cross-zone-lb - languages: - - hcl - message: The AWS cross zone load balancing is not enabled. - metadata: - category: best-practice - technology: - - terraform - - aws - patterns: - - pattern-either: - - pattern: | - resource "aws_lb" $ANYTHING { - ... - load_balancer_type = ... - ... - } - - pattern: | - resource "aws_alb" $ANYTHING { - ... - load_balancer_type = ... - ... - } - - pattern-not-inside: | - resource $ANYLB $ANYTHING { - ... - enable_cross_zone_load_balancing = true - ... - } - - pattern-not-inside: | - resource $ANYLB $ANYTHING { - ... - load_balancer_type = "application" - ... - } - severity: WARNING - - id: terraform.aws.best-practice.missing-aws-lb-deletion-protection.missing-aws-lb-deletion-protection - languages: - - hcl - message: The AWS LoadBalancer deletion protection is not enabled. - metadata: - category: best-practice - references: - - https://aws.amazon.com/what-is/load-balancing/#seo-faq-pairs#benefits-lb - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb - technology: - - terraform - - aws - patterns: - - pattern-either: - - pattern-inside: | - resource "aws_alb" "..." { - ... - } - - pattern-inside: | - resource "aws_lb" "..." { - ... - } - - pattern-not-inside: | - resource $ANYLB $ANYTHING { - ... - enable_deletion_protection = true - ... - } - severity: WARNING - - id: terraform.aws.best-practice.missing-aws-qldb-deletion-protection.missing-aws-qldb-deletion-protection - languages: - - hcl - message: The AWS QLDB deletion protection is not enabled. - metadata: - category: best-practice - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_qldb_ledger" $ANYTHING { - ... - deletion_protection = false - ... - } - severity: WARNING - - id: terraform.aws.best-practice.missing-cloudwatch-log-group-kms-key.missing-cloudwatch-log-group-kms-key - languages: - - hcl - message: The AWS CloudWatch Log group is missing a KMS key. While Log group data is always encrypted, you can optionally use a KMS key instead. Add `kms_key_id = "yourKey"` to your resource block. - metadata: - category: best-practice - technology: - - aws - - terraform - patterns: - - patterns: - - pattern: resource "aws_cloudwatch_log_group" $ANYTHING {...} - - pattern-not-inside: | - resource "aws_cloudwatch_log_group" $ANYTHING { - ... - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.best-practice.missing-cloudwatch-log-group-retention.missing-cloudwatch-log-group-retention - languages: - - hcl - message: The AWS CloudWatch Log group is missing log retention time. By default, logs are retained indefinitely. Add `retention_in_days = ` to your resource block. - metadata: - category: best-practice - technology: - - aws - - terraform - patterns: - - patterns: - - pattern: resource "aws_cloudwatch_log_group" $ANYTHING {...} - - pattern-not-inside: | - resource "aws_cloudwatch_log_group" $ANYTHING { - ... - retention_in_days = ... - ... - } - severity: WARNING - - id: terraform.aws.correctness.lambda-permission-logs-missing-arn-asterisk.lambda-permission-logs-missing-arn-asterisk - languages: - - hcl - message: 'The `source_arn` field needs to end with an asterisk, like this: `:*` Without this, the `aws_lambda_permission` resource ''$NAME'' will not be created. Add the asterisk to the end of the arn. x $ARN' - metadata: - category: correctness - references: - - https://github.com/hashicorp/terraform-provider-aws/issues/14630 - technology: - - aws - - terraform - - aws-lambda - patterns: - - pattern-inside: | - resource "aws_lambda_permission" "$NAME" { ... } - - pattern: | - source_arn = $ARN - - metavariable-pattern: - metavariable: $ARN - patterns: - - pattern-regex: arn:aws:logs.* - - pattern-not-regex: arn:aws:logs:.*:\* - severity: WARNING - - id: terraform.aws.correctness.lambda-redundant-field-with-image.lambda-redundant-field-with-image - languages: - - hcl - message: When using the AWS Lambda "Image" package_type, `runtime` and `handler` are not necessary for Lambda to understand how to run the code. These are built into the container image. Including `runtime` or `handler` with an "Image" `package_type` will result in an error on `terraform apply`. Remove these redundant fields. - metadata: - category: correctness - references: - - https://stackoverflow.com/questions/72771366/why-do-i-get-error-handler-and-runtime-must-be-set-when-packagetype-is-zip-whe - technology: - - aws - - terraform - - aws-lambda - patterns: - - pattern-inside: "resource \"aws_lambda_function\" $NAME { \n ...\n package_type = \"Image\"\n}\n" - - pattern-either: - - pattern: handler = ... - - pattern: runtime = ... - severity: WARNING - - id: terraform.aws.correctness.reserved-aws-lambda-environment-variable.reserved-aws-lambda-environment-variable - languages: - - hcl - message: '`terraform apply` will fail because the environment variable "$VARIABLE" is a reserved by AWS. Use another name for "$VARIABLE".' - metadata: - category: correctness - references: - - https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime - technology: - - aws - - aws-lambda - - terraform - patterns: - - pattern-inside: | - resource "aws_lambda_function" $FUNCTION { ... } - - pattern-inside: | - environment { ... } - - pattern-inside: | - variables = { ... } - - pattern: | - $VARIABLE = ... - - metavariable-pattern: - metavariable: $VARIABLE - patterns: - - pattern-either: - - pattern: _HANDLER - - pattern: _X_AMZN_TRACE_ID - - pattern: AWS_DEFAULT_REGION - - pattern: AWS_REGION - - pattern: AWS_EXECUTION_ENV - - pattern: AWS_LAMBDA_FUNCTION_NAME - - pattern: AWS_LAMBDA_FUNCTION_MEMORY_SIZE - - pattern: AWS_LAMBDA_FUNCTION_VERSION - - pattern: AWS_LAMBDA_INITIALIZATION_TYPE - - pattern: AWS_LAMBDA_LOG_GROUP_NAME - - pattern: AWS_LAMBDA_LOG_STREAM_NAME - - pattern: AWS_ACCESS_KEY - - pattern: AWS_ACCESS_KEY_ID - - pattern: AWS_SECRET_ACCESS_KEY - - pattern: AWS_LAMBDA_RUNTIME_API - - pattern: LAMBDA_TASK_ROOT - - pattern: LAMBDA_RUNTIME_DIR - severity: WARNING - - id: terraform.aws.correctness.subscription-filter-missing-depends.subscription-filter-missing-depends - languages: - - hcl - message: The `aws_cloudwatch_log_subscription_filter` resource "$NAME" needs a `depends_on` clause on the `aws_lambda_permission`, otherwise Terraform may try to create these out-of-order and fail. - metadata: - category: correctness - confidence: MEDIUM - references: - - https://stackoverflow.com/questions/38407660/terraform-configuring-cloudwatch-log-subscription-delivery-to-lambda/38428834#38428834 - technology: - - aws - - terraform - - aws-lambda - - cloudwatch - patterns: - - pattern: | - resource "aws_cloudwatch_log_subscription_filter" $NAME { - ... - destination_arn = aws_lambda_function.$LAMBDA_NAME.arn - } - - pattern-not-inside: | - resource "aws_cloudwatch_log_subscription_filter" $NAME { - ... - depends_on = [..., aws_lambda_permission.$PERMISSION_NAME, ...] - } - severity: WARNING - - id: terraform.aws.security.aws-athena-client-can-disable-workgroup-encryption.aws-athena-client-can-disable-workgroup-encryption - languages: - - hcl - message: The Athena workgroup configuration can be overriden by client-side settings. The client can make changes to disable encryption settings. Enforce the configuration to prevent client overrides. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_athena_workgroup" $ANYTHING { - ... - configuration { - ... - enforce_workgroup_configuration = false - ... - result_configuration { - ... - encryption_configuration { - ... - } - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-athena-database-unencrypted.aws-athena-database-unencrypted - languages: - - hcl - message: The Athena database is unencrypted at rest. These databases are generally derived from data in S3 buckets and should have the same level of at rest protection. The AWS KMS encryption key protects database contents. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_athena_database" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_athena_database" $ANYTHING { - ... - encryption_configuration { - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-athena-workgroup-unencrypted.aws-athena-workgroup-unencrypted - languages: - - hcl - message: The AWS Athena Work Group is unencrypted. The AWS KMS encryption key protects backups in the work group. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_athena_workgroup" $ANYTHING { - ... - configuration { - ... - result_configuration { - ... - } - ... - } - ... - } - - pattern-not-inside: | - resource "aws_athena_workgroup" $ANYTHING { - ... - configuration { - ... - result_configuration { - ... - encryption_configuration { - ... - } - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-backup-vault-unencrypted.aws-backup-vault-unencrypted - languages: - - hcl - message: The AWS Backup vault is unencrypted. The AWS KMS encryption key protects backups in the Backup vault. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - aws - - terraform - patterns: - - pattern-not-inside: | - resource "aws_backup_vault" $BACKUP { - ... - kms_key_arn = ... - ... - } - - pattern: resource "aws_backup_vault" $BACKUP {...} - severity: WARNING - - id: terraform.aws.security.aws-cloudfront-insecure-tls.aws-insecure-cloudfront-distribution-tls-version - languages: - - hcl - message: Detected an AWS CloudFront Distribution with an insecure TLS version. TLS versions less than 1.2 are considered insecure because they can be broken. To fix this, set your `minimum_protocol_version` to `"TLSv1.2_2018", "TLSv1.2_2019" or "TLSv1.2_2021"`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_cloudfront_distribution" $ANYTHING { - ... - viewer_certificate { - ... - } - ... - } - - pattern-not-inside: | - resource "aws_cloudfront_distribution" $ANYTHING { - ... - viewer_certificate { - ... - minimum_protocol_version = "TLSv1.2_2018" - ... - } - ... - } - - pattern-not-inside: | - resource "aws_cloudfront_distribution" $ANYTHING { - ... - viewer_certificate { - ... - minimum_protocol_version = "TLSv1.2_2019" - ... - } - ... - } - - pattern-not-inside: | - resource "aws_cloudfront_distribution" $ANYTHING { - ... - viewer_certificate { - ... - minimum_protocol_version = "TLSv1.2_2021" - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-cloudtrail-encrypted-with-cmk.aws-cloudtrail-encrypted-with-cmk - languages: - - hcl - message: Ensure CloudTrail logs are encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_cloudtrail" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_cloudtrail" $ANYTHING { - ... - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-cloudwatch-log-group-no-retention.aws-cloudwatch-log-group-no-retention - languages: - - hcl - message: The AWS CloudWatch Log Group has no retention. Missing retention in log groups can cause losing important event information. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern: | - resource "aws_cloudwatch_log_group" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_cloudwatch_log_group" $ANYTHING { - ... - retention_in_days = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-cloudwatch-log-group-unencrypted.aws-cloudwatch-log-group-unencrypted - languages: - - hcl - message: By default, AWS CloudWatch Log Group is encrypted using AWS-managed keys. However, for added security, it's recommended to configure your own AWS KMS encryption key to protect your log group in CloudWatch. You can either create a new aws_kms_key resource or use the ARN of an existing key in your AWS account to do so. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: LOW - likelihood: LOW - owasp: - - A02:2021 - Cryptographic Failures - references: - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - audit - technology: - - aws - - terraform - patterns: - - pattern: | - resource "aws_cloudwatch_log_group" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_cloudwatch_log_group" $ANYTHING { - ... - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-codebuild-artifacts-unencrypted.aws-codebuild-artifacts-unencrypted - languages: - - hcl - message: The CodeBuild project artifacts are unencrypted. All artifacts produced by your CodeBuild project pipeline should be encrypted to prevent them from being read if compromised. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/codebuild_project#encryption_disabled - - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-artifacts.html - - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codebuild-project.html - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-inside: | - resource "aws_codebuild_project" "$ANYTHING" { - ... - } - - pattern: | - $ARTIFACTS { - ... - type = "$TYPE" - encryption_disabled = true - ... - } - - metavariable-regex: - metavariable: $ARTIFACTS - regex: ^(artifacts|secondary_artifacts)$ - - metavariable-regex: - metavariable: $TYPE - regex: ^(CODEPIPELINE|S3)$ - severity: WARNING - - id: terraform.aws.security.aws-codebuild-project-artifacts-unencrypted.aws-codebuild-project-artifacts-unencrypted - languages: - - hcl - message: The AWS CodeBuild Project Artifacts are unencrypted. The AWS KMS encryption key protects artifacts in the CodeBuild Projects. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - aws - - terraform - patterns: - - pattern: | - resource "aws_codebuild_project" $ANYTHING { - ... - artifacts { - ... - encryption_disabled = true - ... - } - ... - } - - pattern-not-inside: | - resource "aws_codebuild_project" $ANYTHING { - ... - artifacts { - type = "NO_ARTIFACTS" - encryption_disabled = true - } - ... - } - - pattern-not-inside: | - resource "aws_codebuild_project" $ANYTHING { - ... - artifacts { - type = "NO_ARTIFACTS" - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-codebuild-project-unencrypted.aws-codebuild-project-unencrypted - languages: - - hcl - message: The AWS CodeBuild Project is unencrypted. The AWS KMS encryption key protects projects in the CodeBuild. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern: | - resource "aws_codebuild_project" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_codebuild_project" $ANYTHING { - ... - encryption_key = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-config-aggregator-not-all-regions.aws-config-aggregator-not-all-regions - languages: - - hcl - message: The AWS configuration aggregator does not aggregate all AWS Config region. This may result in unmonitored configuration in regions that are thought to be unused. Configure the aggregator with all_regions for the source. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-778: Insufficient Logging' - impact: MEDIUM - likelihood: LOW - owasp: - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ - subcategory: - - audit - technology: - - terraform - - aws - pattern-either: - - pattern: | - resource "aws_config_configuration_aggregator" $ANYTHING { - ... - account_aggregation_source { - ... - regions = ... - ... - } - ... - } - - pattern: | - resource "aws_config_configuration_aggregator" $ANYTHING { - ... - organization_aggregation_source { - ... - regions = ... - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-db-instance-no-logging.aws-db-instance-no-logging - languages: - - hcl - message: Database instance has no logging. Missing logs can cause missing important event information. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: LOW - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern: | - resource "aws_db_instance" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_db_instance" $ANYTHING { - ... - enabled_cloudwatch_logs_exports = [$SOMETHING, ...] - ... - } - severity: WARNING - - id: terraform.aws.security.aws-docdb-encrypted-with-cmk.aws-docdb-encrypted-with-cmk - languages: - - hcl - message: Ensure DocDB is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_docdb_cluster" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_docdb_cluster" $ANYTHING { - ... - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-documentdb-auditing-disabled.aws-documentdb-auditing-disabled - languages: - - hcl - message: Auditing is not enabled for DocumentDB. To ensure that you are able to accurately audit the usage of your DocumentDB cluster, you should enable auditing and export logs to CloudWatch. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-778: Insufficient Logging' - impact: LOW - likelihood: LOW - owasp: - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_cluster#enabled_cloudwatch_logs_exports - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_docdb_cluster" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_docdb_cluster" $ANYTHING { - ... - enabled_cloudwatch_logs_exports = [..., "audit", ...] - ... - } - severity: INFO - - id: terraform.aws.security.aws-documentdb-storage-unencrypted.aws-documentdb-storage-unencrypted - languages: - - hcl - message: The AWS DocumentDB cluster is unencrypted. The data could be read if the underlying disks are compromised. You should enable storage encryption. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_cluster#storage_encrypted - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_docdb_cluster" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_docdb_cluster" $ANYTHING { - ... - storage_encrypted = true - ... - } - severity: WARNING - - id: terraform.aws.security.aws-dynamodb-point-in-time-recovery-disabled.aws-dynamodb-point-in-time-recovery-disabled - languages: - - hcl - message: Point-in-time recovery is not enabled for the DynamoDB table. DynamoDB tables should be protected against accidental or malicious write/delete actions. By enabling point-in-time-recovery you can restore to a known point in the event of loss of data. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-221: Information Loss or Omission' - impact: LOW - likelihood: LOW - owasp: - - A09:2021 – Security Logging and Monitoring Failures - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table#point_in_time_recovery - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_dynamodb_table" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_dynamodb_table" $ANYTHING { - ... - point_in_time_recovery { - ... - enabled = true - ... - } - ... - } - severity: INFO - - id: terraform.aws.security.aws-dynamodb-table-unencrypted.aws-dynamodb-table-unencrypted - languages: - - hcl - message: By default, AWS DynamoDB Table is encrypted using AWS-managed keys. However, for added security, it's recommended to configure your own AWS KMS encryption key to protect your data in the DynamoDB table. You can either create a new aws_kms_key resource or use the ARN of an existing key in your AWS account to do so. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern: | - resource "aws_dynamodb_table" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_dynamodb_table" $ANYTHING { - ... - server_side_encryption { - enabled = true - kms_key_arn = ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ebs-snapshot-encrypted-with-cmk.aws-ebs-snapshot-encrypted-with-cmk - languages: - - hcl - message: Ensure EBS Snapshot is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_ebs_snapshot_copy" $ANYTHING { - ... - encrypted = true - ... - } - - pattern-not-inside: | - resource "aws_ebs_snapshot_copy" $ANYTHING { - ... - encrypted = true - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ebs-unencrypted.aws-ebs-unencrypted - languages: - - hcl - message: The AWS EBS is unencrypted. The AWS EBS encryption protects data in the EBS. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern: | - resource "aws_ebs_encryption_by_default" $ANYTHING { - ... - enabled = false - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ebs-volume-encrypted-with-cmk.aws-ebs-volume-encrypted-with-cmk - languages: - - hcl - message: Ensure EBS Volume is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_ebs_volume" $ANYTHING { - ... - encrypted = true - ... - } - - pattern-not-inside: | - resource "aws_ebs_volume" $ANYTHING { - ... - encrypted = true - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ebs-volume-unencrypted.aws-ebs-volume-unencrypted - languages: - - hcl - message: The AWS EBS volume is unencrypted. The volume, the disk I/O and any derived snapshots could be read if compromised. Volumes should be encrypted to ensure sensitive data is stored securely. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume#encrypted - - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_ebs_volume" $ANYTHING { - ... - } - - pattern-not: | - resource "aws_ebs_volume" $ANYTHING { - ... - encrypted = true - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ec2-has-public-ip.aws-ec2-has-public-ip - languages: - - hcl - message: EC2 instances should not have a public IP address attached in order to block public access to the instances. To fix this, set your `associate_public_ip_address` to `"false"`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-284: Improper Access Control' - impact: MEDIUM - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - terraform - - aws - patterns: - - pattern-either: - - pattern: | - resource "aws_instance" $ANYTHING { - ... - associate_public_ip_address = true - ... - } - - pattern: | - resource "aws_launch_template" $ANYTHING { - ... - network_interfaces { - ... - associate_public_ip_address = true - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ec2-launch-configuration-ebs-block-device-unencrypted.aws-ec2-launch-configuration-ebs-block-device-unencrypted - languages: - - hcl - message: The AWS launch configuration EBS block device is unencrypted. The block device could be read if compromised. Block devices should be encrypted to ensure sensitive data is held securely at rest. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration#block-devices - - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html - rule-origin-note: published from /src/aws-ec2-launch-configuration-block-device-unencrypted.yml in None - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-inside: | - resource "aws_launch_configuration" $ANYTHING { - ... - } - - pattern: | - ebs_block_device { - ... - } - - pattern-not: | - ebs_block_device { - ... - encrypted = true - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ec2-launch-configuration-root-block-device-unencrypted.aws-ec2-launch-configuration-root-block-device-unencrypted - languages: - - hcl - message: The AWS launch configuration root block device is unencrypted. The block device could be read if compromised. Block devices should be encrypted to ensure sensitive data is held securely at rest. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration#block-devices - - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html - rule-origin-note: published from /src/aws-ec2-launch-configuration-block-device-unencrypted.yml in None - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_launch_configuration" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_launch_configuration" $ANYTHING { - ... - root_block_device { - ... - encrypted = true - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ec2-launch-template-metadata-service-v1-enabled.aws-ec2-launch-template-metadata-service-v1-enabled - languages: - - hcl - message: The EC2 launch template has Instance Metadata Service Version 1 (IMDSv1) enabled. IMDSv2 introduced session authentication tokens which improve security when talking to IMDS. You should either disable IMDS or require the use of IMDSv2. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-1390: Weak Authentication' - impact: HIGH - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration#metadata_options - - https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_launch_template" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_launch_template" $ANYTHING { - ... - metadata_options { - ... - http_endpoint = "disabled" - ... - } - ... - } - - pattern-not-inside: | - resource "aws_launch_template" $ANYTHING { - ... - metadata_options { - ... - http_tokens = "required" - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ec2-security-group-allows-public-ingress.aws-ec2-security-group-allows-public-ingress - languages: - - hcl - message: The security group rule allows ingress from public internet. Opening up ports to the public internet is potentially dangerous. You should restrict access to IP addresses or ranges that explicitly require it where possible. Set a more restrictive CIDR range. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule#cidr_blocks - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule#cidr_ipv4 - - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-rules-reference.html - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-either: - - pattern: | - resource "aws_security_group_rule" $ANYTHING { - ... - type = "ingress" - cidr_blocks = [..., "$PUBLIC_IPV4_CIDR", ...] - ... - } - - pattern: | - resource "aws_vpc_security_group_ingress_rule" $ANYTHING { - ... - cidr_ipv4 = "$PUBLIC_IPV4_CIDR" - ... - } - - patterns: - - pattern-inside: | - resource "aws_security_group" $ANYTHING { - ... - } - - pattern: | - ingress { - ... - cidr_blocks = [..., "$PUBLIC_IPV4_CIDR", ...] - ... - } - - metavariable-pattern: - language: generic - metavariable: $PUBLIC_IPV4_CIDR - patterns: - - pattern-not-regex: ^127\.\d{1,3}\.\d{1,3}\.\d{1,3}/(8|9|[1-3][0-9])$ - - pattern-not-regex: ^10\.\d{1,3}\.\d{1,3}\.\d{1,3}/(8|9|[1-3][0-9])$ - - pattern-not-regex: ^172\.(1[6-9]|2[0-9]|3[01])\.\d{1,3}\.\d{1,3}/(1[2-9]|[23][0-9])$ - - pattern-not-regex: ^192\.168\.\d{1,3}\.\d{1,3}/(1[6-9]|[23][0-9])$ - - pattern-not-regex: ^169\.254\.\d{1,3}\.\d{1,3}/(1[6-9]|[23][0-9])$ - - pattern-not-regex: ^100\.(6[4-9]|[7-9][0-9]|1[01][0-9]|12[0-7])\.\d{1,3}\.\d{1,3}/[1-3][0-9]$ - - pattern-not-regex: ^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/32$ - severity: WARNING - - id: terraform.aws.security.aws-ec2-security-group-rule-missing-description.aws-ec2-security-group-rule-missing-description - languages: - - hcl - message: The AWS security group rule is missing a description, or its description is empty or the default value. Security groups rules should include a meaningful description in order to simplify auditing, debugging, and managing security groups. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-223: Omission of Security-relevant Information' - impact: LOW - likelihood: LOW - owasp: - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://shisho.dev/dojo/providers/aws/Amazon_EC2/aws-security-group/#:~:text=Ensure%20to%20keep%20the%20description%20of%20your%20security%20group%20up%2Dto%2Ddate - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group#description - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-either: - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - resource "aws_security_group" $ANYTHING { - ... - $INGRESS { - ... - description = $DESCR - ... - } - ... - } - - metavariable-regex: - metavariable: $INGRESS - regex: ^(ingress|egress)$ - - patterns: - - pattern-inside: | - resource "$SECGROUP" $ANYTHING { - ... - description = $DESCR - ... - } - - metavariable-regex: - metavariable: $SECGROUP - regex: ^(aws_security_group_rule|aws_security_group)$ - - metavariable-regex: - metavariable: $DESCR - regex: ^(['\"]['\"]|['\"]Managed by Terraform['\"])$ - - focus-metavariable: $DESCR - - patterns: - - metavariable-regex: - metavariable: $INGRESS - regex: ^(ingress|egress)$ - - pattern: | - resource "aws_security_group" $ANYTHING { - ... - $INGRESS { - ... - } - ... - } - - pattern-not: | - resource "aws_security_group" $ANYTHING { - ... - $INGRESS { - ... - description = ... - ... - } - ... - } - - patterns: - - metavariable-regex: - metavariable: $SECGROUP - regex: ^(aws_security_group_rule|aws_security_group)$ - - pattern: | - resource "$SECGROUP" $ANYTHING { - ... - } - - pattern-not: | - resource "$SECGROUP" $ANYTHING { - ... - description = ... - ... - } - severity: INFO - - id: terraform.aws.security.aws-ecr-image-scanning-disabled.aws-ecr-image-scanning-disabled - languages: - - hcl - message: The ECR repository has image scans disabled. Repository image scans should be enabled to ensure vulnerable software can be discovered and remediated as soon as possible. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-223: Omission of Security-relevant Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository#image_scanning_configuration - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_ecr_repository" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_ecr_repository" $ANYTHING { - ... - image_scanning_configuration { - ... - scan_on_push = true - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ecr-mutable-image-tags.aws-ecr-mutable-image-tags - languages: - - hcl - message: The ECR repository allows tag mutability. Image tags could be overwritten with compromised images. ECR images should be set to IMMUTABLE to prevent code injection through image mutation. This can be done by setting `image_tag_mutability` to IMMUTABLE. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-345: Insufficient Verification of Data Authenticity' - impact: HIGH - likelihood: LOW - owasp: - - A08:2021 - Software and Data Integrity Failures - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository#image_tag_mutability - - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/ - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_ecr_repository" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_ecr_repository" $ANYTHING { - ... - image_tag_mutability = "IMMUTABLE" - ... - } - severity: WARNING - - id: terraform.aws.security.aws-ecr-repository-wildcard-principal.aws-ecr-repository-wildcard-principal - languages: - - hcl - message: Detected wildcard access granted in your ECR repository policy principal. This grants access to all users, including anonymous users (public access). Instead, limit principals, actions and resources to what you need according to least privilege. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository_policy - - https://docs.aws.amazon.com/lambda/latest/operatorguide/wildcard-permissions-iam.html - - https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/monitor-amazon-ecr-repositories-for-wildcard-permissions-using-aws-cloudformation-and-aws-config.html - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern-inside: | - resource "aws_ecr_repository_policy" $ANYTHING { - ... - } - - pattern-either: - - patterns: - - pattern: policy = "$JSONPOLICY" - - metavariable-pattern: - language: json - metavariable: $JSONPOLICY - patterns: - - pattern-not-inside: | - {..., "Effect": "Deny", ...} - - pattern-either: - - pattern: | - {..., "Principal": "*", ...} - - pattern: | - {..., "Principal": [..., "*", ...], ...} - - pattern: | - {..., "Principal": { "AWS": "*" }, ...} - - pattern: | - {..., "Principal": { "AWS": [..., "*", ...] }, ...} - - patterns: - - pattern-inside: policy = jsonencode(...) - - pattern-not-inside: | - {..., Effect = "Deny", ...} - - pattern-either: - - pattern: | - {..., Principal = "*", ...} - - pattern: | - {..., Principal = [..., "*", ...], ...} - - pattern: | - {..., Principal = { AWS = "*" }, ...} - - pattern: | - {..., Principal = { AWS = [..., "*", ...] }, ...} - severity: WARNING - - id: terraform.aws.security.aws-efs-filesystem-encrypted-with-cmk.aws-efs-filesystem-encrypted-with-cmk - languages: - - hcl - message: Ensure EFS filesystem is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_efs_file_system" $ANYTHING { - ... - encrypted = true - ... - } - - pattern-not-inside: | - resource "aws_efs_file_system" $ANYTHING { - ... - encrypted = true - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-elasticsearch-insecure-tls-version.aws-elasticsearch-insecure-tls-version - languages: - - terraform - message: Detected an AWS Elasticsearch domain using an insecure version of TLS. To fix this, set "tls_security_policy" equal to "Policy-Min-TLS-1-2-2019-07". - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform - pattern: | - resource "aws_elasticsearch_domain" $ANYTHING { - ... - domain_endpoint_options { - ... - enforce_https = true - tls_security_policy = "Policy-Min-TLS-1-0-2019-07" - ... - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-elasticsearch-nodetonode-encryption.aws-elasticsearch-nodetonode-encryption-not-enabled - languages: - - hcl - message: "Ensure all Elasticsearch has node-to-node encryption enabled.\t" - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - aws - patterns: - - pattern-either: - - pattern: | - resource "aws_elasticsearch_domain" $ANYTHING { - ... - node_to_node_encryption { - ... - enabled = false - ... - } - ... - } - - pattern: | - resource "aws_elasticsearch_domain" $ANYTHING { - ... - cluster_config { - ... - instance_count = $COUNT - ... - } - } - - pattern-not-inside: | - resource "aws_elasticsearch_domain" $ANYTHING { - ... - cluster_config { - ... - instance_count = $COUNT - ... - } - node_to_node_encryption { - ... - enabled = true - ... - } - } - - metavariable-comparison: - comparison: $COUNT > 1 - metavariable: $COUNT - severity: WARNING - - id: terraform.aws.security.aws-elb-access-logs-not-enabled.aws-elb-access-logs-not-enabled - languages: - - hcl - message: ELB has no logging. Missing logs can cause missing important event information. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - aws - - terraform - patterns: - - pattern-either: - - pattern: | - resource "aws_lb" $ANYTHING { - ... - } - - pattern: | - resource "aws_alb" $ANYTHING { - ... - } - - pattern-not-inside: | - resource $ANYLB $ANYTHING { - ... - access_logs { - ... - enabled = true - ... - } - ... - } - - pattern-not-inside: "resource $ANYLB $ANYTHING {\n ...\n subnet_mapping {\n ...\n }\n ...\n} \n" - severity: WARNING - - id: terraform.aws.security.aws-emr-encrypted-with-cmk.aws-emr-encrypted-with-cmk - languages: - - hcl - message: Ensure EMR is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-inside: | - resource "aws_emr_security_configuration" $ANYTHING { - ... - } - - pattern: configuration = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: - - pattern-not-inside: | - "AwsKmsKey": ... - severity: WARNING - - id: terraform.aws.security.aws-fsx-lustre-files-ystem.aws-fsx-lustre-filesystem-encrypted-with-cmk - languages: - - hcl - message: Ensure FSX Lustre file system is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_fsx_lustre_file_system" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_fsx_lustre_file_system" $ANYTHING { - ... - kms_key_id = ... - ... - } - - pattern-regex: (^aws_kms_key\.(.*)) - severity: WARNING - - id: terraform.aws.security.aws-fsx-lustre-filesystem-encrypted-with-cmk.aws-fsx-lustre-filesystem-encrypted-with-cmk - languages: - - hcl - message: Ensure FSX Lustre file system is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_fsx_lustre_file_system" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_fsx_lustre_file_system" $ANYTHING { - ... - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-fsx-ontapfs-encrypted-with-cmk.aws-fsx-ontapfs-encrypted-with-cmk - languages: - - hcl - message: Ensure FSX ONTAP file system is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_fsx_ontap_file_system" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_fsx_ontap_file_system" $ANYTHING { - ... - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-fsx-windows-encrypted-with-cmk.aws-fsx-windows-encrypted-with-cmk - languages: - - hcl - message: Ensure FSX Windows file system is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_fsx_windows_file_system" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_fsx_windows_file_system" $ANYTHING { - ... - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-glacier-vault-any-principal.aws-glacier-vault-any-principal - languages: - - hcl - message: 'Detected wildcard access granted to Glacier Vault. This means anyone within your AWS account ID can perform actions on Glacier resources. Instead, limit to a specific identity in your account, like this: `arn:aws:iam:::`.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - vuln - technology: - - aws - patterns: - - pattern-inside: | - resource "aws_glacier_vault" $ANYTHING { - ... - } - - pattern: access_policy = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: - - pattern-inside: | - {..., "Effect": "Allow", ...} - - pattern-either: - - pattern: | - "Principal": "*" - - pattern: | - "Principal": {..., "AWS": "*", ...} - - pattern-inside: | - "Principal": {..., "AWS": ..., ...} - - pattern-regex: | - (^\"arn:aws:iam::\*:(.*)\"$) - severity: ERROR - - id: terraform.aws.security.aws-iam-admin-policy-ssoadmin.aws-iam-admin-policy-ssoadmin - languages: - - hcl - message: Detected admin access granted in your policy. This means anyone with this policy can perform administrative actions. Instead, limit actions and resources to what you need according to least privilege. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - vuln - technology: - - aws - patterns: - - pattern-inside: | - resource "aws_ssoadmin_permission_set_inline_policy" $ANYTHING { - ... - } - - pattern: inline_policy = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: - - pattern-not-inside: | - {..., "Effect": "Deny", ...} - - pattern-either: - - pattern: | - {..., "Action": [..., "*", ...], "Resource": [..., "*", ...], ...} - - pattern: | - {..., "Action": "*", "Resource": "*", ...} - - pattern: | - {..., "Action": "*", "Resource": [...], ...} - - pattern: | - {..., "Action": [...], "Resource": "*", ...} - severity: ERROR - - id: terraform.aws.security.aws-iam-admin-policy.aws-iam-admin-policy - languages: - - hcl - message: Detected admin access granted in your policy. This means anyone with this policy can perform administrative actions. Instead, limit actions and resources to what you need according to least privilege. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern-inside: | - resource "aws_iam_policy" $ANYTHING { - ... - } - - pattern: policy = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: - - pattern-not-inside: | - {..., "Effect": "Deny", ...} - - pattern-either: - - pattern: | - {..., "Action": [..., "*", ...], "Resource": [..., "*", ...], ...} - - pattern: | - {..., "Action": "*", "Resource": "*", ...} - - pattern: | - {..., "Action": "*", "Resource": [...], ...} - - pattern: | - {..., "Action": [...], "Resource": "*", ...} - severity: ERROR - - id: terraform.aws.security.aws-imagebuilder-component-encrypted-with-cmk.aws-imagebuilder-component-encrypted-with-cmk - languages: - - hcl - message: Ensure ImageBuilder component is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_imagebuilder_component" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_imagebuilder_component" $ANYTHING { - ... - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-insecure-api-gateway-tls-version.aws-insecure-api-gateway-tls-version - languages: - - terraform - message: Detected AWS API Gateway to be using an insecure version of TLS. To fix this issue make sure to set "security_policy" equal to "TLS_1_2". - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern-either: - - pattern: | - resource "aws_api_gateway_domain_name" $ANYTHING { - ... - security_policy = "..." - ... - } - - pattern: | - resource "aws_apigatewayv2_domain_name" $ANYTHING { - ... - domain_name_configuration {...} - ... - } - - pattern-not: | - resource "aws_api_gateway_domain_name" $ANYTHING { - ... - security_policy = "TLS_1_2" - ... - } - - pattern-not: | - resource "aws_apigatewayv2_domain_name" $ANYTHING { - ... - domain_name_configuration { - ... - security_policy = "TLS_1_2" - ... - } - } - severity: WARNING - - id: terraform.aws.security.aws-insecure-redshift-ssl-configuration.aws-insecure-redshift-ssl-configuration - languages: - - hcl - message: Detected an AWS Redshift configuration with a SSL disabled. To fix this, set your `require_ssl` to `"true"`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_redshift_parameter_group" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_redshift_parameter_group" $ANYTHING { - ... - parameter { - name = "require_ssl" - value = "true" - } - ... - } - - pattern-not-inside: | - resource "aws_redshift_parameter_group" $ANYTHING { - ... - parameter { - name = "require_ssl" - value = true - } - ... - } - severity: WARNING - - id: terraform.aws.security.aws-kinesis-stream-encrypted-with-cmk.aws-kinesis-stream-encrypted-with-cmk - languages: - - hcl - message: Ensure Kinesis stream is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_kinesis_stream" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_kinesis_stream" $ANYTHING { - ... - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-kinesis-stream-unencrypted.aws-kinesis-stream-unencrypted - languages: - - hcl - message: The AWS Kinesis stream does not encrypt data at rest. The data could be read if the Kinesis stream storage layer is compromised. Enable Kinesis stream server-side encryption. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kinesis_stream#encryption_type - - https://docs.aws.amazon.com/streams/latest/dev/server-side-encryption.html - rule-origin-note: published from /src/aws-kinesis-stream-unencrypted.yml in None - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_kinesis_stream" $ANYTHING { - ... - } - - pattern-not: | - resource "aws_kinesis_stream" $ANYTHING { - ... - encryption_type = "KMS" - ... - } - severity: WARNING - - id: terraform.aws.security.aws-kinesis-video-stream-encrypted-with-cmk.aws-kinesis-video-stream-encrypted-with-cmk - languages: - - hcl - message: Ensure Kinesis video stream is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource "aws_kinesis_video_stream" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_kinesis_video_stream" $ANYTHING { - ... - kms_key_id = ... - ... - } - severity: WARNING - - id: terraform.aws.security.aws-kms-key-wildcard-principal.aws-kms-key-wildcard-principal - languages: - - hcl - message: Detected wildcard access granted in your KMS key. This means anyone with this policy can perform administrative actions over the keys. Instead, limit principals, actions and resources to what you need according to least privilege. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://cwe.mitre.org/data/definitions/732.html - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern-inside: | - resource "aws_kms_key" $ANYTHING { - ... - } - - pattern: policy = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: - - pattern-not-inside: | - {..., "Effect": "Deny", ...} - - pattern-either: - - pattern: | - {..., "Principal": "*", "Action": "kms:*", "Resource": "*", ...} - - pattern: | - {..., "Principal": [..., "*", ...], "Action": "kms:*", "Resource": "*", ...} - - pattern: | - {..., "Principal": { "AWS": "*" }, "Action": "kms:*", "Resource": "*", ...} - - pattern: | - {..., "Principal": { "AWS": [..., "*", ...] }, "Action": "kms:*", "Resource": "*", ...} - severity: ERROR - - id: terraform.aws.security.aws-kms-no-rotation.aws-kms-no-rotation - languages: - - hcl - message: The AWS KMS has no rotation. Missing rotation can cause leaked key to be used by attackers. To fix this, set a `enable_key_rotation`. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - aws - - terraform - patterns: - - pattern-either: - - pattern: | - resource "aws_kms_key" $ANYTHING { - ... - enable_key_rotation = false - ... - } - - pattern: | - resource "aws_kms_key" $ANYTHING { - ... - customer_master_key_spec = "SYMMETRIC_DEFAULT" - enable_key_rotation = false - ... - } - - pattern: | - resource "aws_kms_key" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "aws_kms_key" $ANYTHING { - ... - enable_key_rotation = true - ... - } - - pattern-not-inside: | - resource "aws_kms_key" $ANYTHING { - ... - customer_master_key_spec = "RSA_2096" - ... - } - severity: WARNING - - id: terraform.aws.security.aws-lambda-environment-credentials.aws-lambda-environment-credentials - languages: - - hcl - message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: HIGH - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html - subcategory: - - vuln - technology: - - aws - - terraform - - secrets - patterns: - - pattern-inside: | - resource "$ANYTING" $ANYTHING { - ... - environment { - variables = { - ... - } - } - ... - } - - pattern-either: - - pattern-inside: | - AWS_ACCESS_KEY_ID = "$Y" - - pattern-regex: | - (?:root`.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A06:2017 - Security Misconfiguration - - A05:2021 - Security Misconfiguration - references: - - https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/ - subcategory: - - vuln - technology: - - aws - patterns: - - pattern-inside: | - resource "aws_iam_role" $NAME { - ... - } - - pattern: assume_role_policy = "$STATEMENT" - - metavariable-pattern: - language: json - metavariable: $STATEMENT - patterns: - - pattern-inside: | - {..., "Effect": "Allow", ..., "Action": "sts:AssumeRole", ...} - - pattern: | - "Principal": {..., "AWS": "*", ...} - severity: ERROR - - id: terraform.azure.best-practice.azure-ad-used-auth-service-fabric.azure-ad-used-auth-service-fabric - languages: - - hcl - message: "Ensures that Active Directory is used for authentication for Service Fabric\t" - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_service_fabric_cluster" "..." { - ... - azure_active_directory { - tenant_id = "..." - } - ... - } - - pattern-inside: | - resource "azurerm_service_fabric_cluster" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-aks-uses-azure-policies-addon.azure-aks-uses-azure-policies-addon - languages: - - hcl - message: Ensure that AKS uses Azure Policies Add-on - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_kubernetes_cluster" "..." { - ... - addon_profile { - azure_policy { - enabled = true - } - } - ... - } - - pattern-inside: | - resource "azurerm_kubernetes_cluster" "..." { - ... - } - severity: INFO - - id: terraform.azure.best-practice.azure-appgateway-enables-waf.azure-appgateway-enables-waf - languages: - - hcl - message: Ensure that Application Gateway enables WAF - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_application_gateway" "..." { - ... - waf_configuration { - enabled = true - } - ... - } - - pattern-inside: | - resource "azurerm_application_gateway" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-appservice-dotnet-framework-version.azure-appservice-dotnet-framework-version - languages: - - hcl - message: Ensure that Net Framework version is the latest, if used as a part of the web app - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - site_config { - ... - dotnet_framework_version = "v6.0" - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: INFO - - id: terraform.azure.best-practice.azure-appservice-ftps-state.azure-appservice-ftps-state - languages: - - hcl - message: Ensure FTP deployments are disabled - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - site_config { - ftps_state = "FtpsOnly" - } - ... - } - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - site_config { - ftps_state = "Disabled" - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-appservice-https-20-enabled.azure-appservice-https-20-enabled - languages: - - hcl - message: Ensure that HTTP Version is the latest if used to run the web app - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - site_config { - http2_enabled = true - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-appservice-java-version.azure-appservice-java-version - languages: - - hcl - message: Ensure that Java version is the latest, if used to run the web app - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - site_config { - ... - java_version = "11" - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: INFO - - id: terraform.azure.best-practice.azure-appservice-php-version.azure-appservice-php-version - languages: - - hcl - message: Ensure that PHP version is the latest, if used to run the web app - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - site_config { - ... - php_version = "7.4" - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: INFO - - id: terraform.azure.best-practice.azure-appservice-python-version.azure-appservice-python-version - languages: - - hcl - message: Ensure that Python version is the latest, if used to run the web app - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - site_config { - ... - python_version = "3.10" - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: INFO - - id: terraform.azure.best-practice.azure-appservice-used-azure-files.azure-appservice-used-azure-files - languages: - - hcl - message: Ensure that app services use Azure Files - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - storage_account { - ... - type = "AzureFiles" - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: INFO - - id: terraform.azure.best-practice.azure-defenderon-appservices.azure-defenderon-appservices - languages: - - hcl - message: Ensure that Azure Defender is set to On for App Service - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Standard" - resource_type = "AppServices" - ... - } - - pattern-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Free" - resource_type = "AppServices" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-defenderon-container-registry.azure-defenderon-container-registry - languages: - - hcl - message: Ensure that Azure Defender is set to On for Container - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Standard" - resource_type = "ContainerRegistry" - ... - } - - pattern-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Free" - resource_type = "ContainerRegistry" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-defenderon-keyvaults.azure-defenderon-keyvaults - languages: - - hcl - message: Ensure that Azure Defender is set to On for Key Vault - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Standard" - resource_type = "KeyVaults" - ... - } - - pattern-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Free" - resource_type = "KeyVaults" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-defenderon-kubernetes.azure-defenderon-kubernetes - languages: - - hcl - message: Ensure that Azure Defender is set to On for Kubernetes - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Standard" - resource_type = "KubernetesService" - ... - } - - pattern-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Free" - resource_type = "KubernetesService" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-defenderon-servers.azure-defenderon-servers - languages: - - hcl - message: Ensure that Azure Defender is set to On for Servers - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Standard" - resource_type = "VirtualMachines" - ... - } - - pattern-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Free" - resource_type = "VirtualMachines" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-defenderon-sqlservers-vms.azure-defenderon-sqlservers-vms - languages: - - hcl - message: Ensure that Azure Defender is set to On for SQL servers on machines - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Standard" - resource_type = "SqlServerVirtualMachines" - ... - } - - pattern-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Free" - resource_type = "SqlServerVirtualMachines" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-defenderon-sqlservers.azure-defenderon-sqlservers - languages: - - hcl - message: Ensure that Azure Defender is set to On for SQL servers - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Standard" - resource_type = "SqlServers" - ... - } - - pattern-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Free" - resource_type = "SqlServers" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-defenderon-storage.azure-defenderon-storage - languages: - - hcl - message: Ensure that Azure Defender is set to On for Storage - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Standard" - resource_type = "StorageAccounts" - ... - } - - pattern-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Free" - resource_type = "StorageAccounts" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-frontdoor-enables-waf.azure-frontdoor-enables-waf - languages: - - hcl - message: Ensure that Azure Front Door enables WAF - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_frontdoor" "..." { - ... - web_application_firewall_policy_link_id = "..." - ... - } - - pattern-inside: | - resource "azurerm_frontdoor" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-frontdoor-use-wafmode.azure-frontdoor-use-wafmode - languages: - - hcl - message: Ensure that Azure Front Door uses WAF and configured in “Detection” or “Prevention” modes - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_frontdoor_firewall_policy" "..." { - ... - policy_settings { - ... - enabled = false - ... - } - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-functionapp-http-version-latest.azure-functionapp-http-version-latest - languages: - - hcl - message: Ensure that HTTP Version is the latest if used to run the Function app - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_function_app" "..." { - ... - site_config { - ... - http2_enabled = true - ... - } - ... - } - - pattern-inside: | - resource "azurerm_function_app" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-functionapps-accessible-over-https.azure-functionapps-accessible-over-https - languages: - - hcl - message: Ensure that HTTP Version is the latest if used to run the Function app - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - https_only = true - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-keyvault-enables-firewall-rules-settings.azure-keyvault-enables-firewall-rules-settings - languages: - - hcl - message: Ensure that key vault allows firewall rules settings - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault" "..." { - ... - network_acls { - ... - default_action = "Deny" - ... - } - ... - } - - pattern-inside: | - resource "azurerm_key_vault" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-keyvault-enables-purge-protection.azure-keyvault-enables-purge-protection - languages: - - hcl - message: Ensure that key vault enables purge protection - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault" "..." { - ... - purge_protection_enabled = true - } - - pattern-inside: | - resource "azurerm_key_vault" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-keyvault-enables-soft-delete.azure-keyvault-enables-soft-delete - languages: - - hcl - message: Ensure that key vault enables soft delete - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_key_vault" "..." { - ... - soft_delete_enabled = false - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-keyvault-recovery-enabled.azure-keyvault-recovery-enabled - languages: - - hcl - message: Ensure the key vault is recoverable https://docs.bridgecrew.io/docs/ensure-the-key-vault-is-recoverable - metadata: - category: best-practice - references: - - https://docs.bridgecrew.io/docs/ensure-the-key-vault-is-recoverable - technology: - - terraform - - azure - patterns: - - pattern: | - resource "azurerm_key_vault" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_key_vault" "..." { - ... - purge_protection_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-mariadb-geo-backup-enabled.azure-mariadb-geo-backup-enabled - languages: - - hcl - message: Ensure that MariaDB server enables geo-redundant backups - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_mariadb_server" "..." { - ... - geo_redundant_backup_enabled = true - ... - } - - pattern-inside: | - resource "azurerm_mariadb_server" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-mariadb-sslenforcement-enabled.azure-mariadb-sslenforcement-enabled - languages: - - hcl - message: Ensure Enforce SSL connection is set to Enabled for MariaDB servers - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_mariadb_server" "..." { - ... - ssl_enforcement_enabled = true - ... - } - - pattern-inside: | - resource "azurerm_mariadb_server" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-monitor-log-profile-categories.azure-monitor-log-profile-categories - languages: - - hcl - message: Ensure audit profile captures all the activities - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_monitor_log_profile" "..." { - ... - categories = [ - "Action", - "Delete", - "Write", - ] - ... - } - - pattern-inside: | - resource "azurerm_monitor_log_profile" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-monitor-log-profile-retention-days.azure-monitor-log-profile-retention-days - languages: - - hcl - message: Ensure that Activity Log Retention is set 365 days or greater - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_monitor_log_profile" "..." { - ... - retention_policy { - ... - enabled = true - days = 365 - ... - } - ... - } - - pattern-not-inside: | - resource "azurerm_monitor_log_profile" "..." { - ... - retention_policy { - ... - enabled = false - days = 0 - ... - } - ... - } - - pattern-inside: | - resource "azurerm_monitor_log_profile" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-mysql-geo-backup-enabled.azure-mysql-geo-backup-enabled - languages: - - hcl - message: Ensure that MySQL server enables geo-redundant backups - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mysql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mysql_server" "..." { - ... - geo_redundant_backup_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-mysql-server-tlsenforcement-enabled.azure-mysql-server-tlsenforcement-enabled - languages: - - hcl - message: Ensure Enforce SSL connection is set to Enabled for MySQL servers - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mysql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mysql_server" "..." { - ... - ssl_enforcement_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-mysql-threat-detection-enabled.azure-mysql-threat-detection-enabled - languages: - - hcl - message: Ensure that MySQL server enables Threat detection policy - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mysql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mysql_server" "..." { - ... - threat_detection_policy { - ... - enabled = true - ... - } - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-networkinterface-enable-ip-forwarding.azure-networkinterface-enable-ip-forwarding - languages: - - hcl - message: Ensure that Network Interfaces disable IP forwarding - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_network_interface" "..." { - ... - enable_ip_forwarding = true - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-postgresql-flexi-server-geo-backup-enabled.azure-postgresql-flexi-server-geo-backup-enabled - languages: - - hcl - message: Ensure that PostgreSQL Flexible server enables geo-redundant backups - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_postgresql_flexible_server" "..." { - ... - geo_redundant_backup_enabled = true - ... - } - - pattern-inside: | - resource "azurerm_postgresql_flexible_server" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-postgresql-geo-backup-enabled.azure-postgresql-geo-backup-enabled - languages: - - hcl - message: Ensure that PostgreSQL server enables geo-redundant backups - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_postgresql_server" "..." { - ... - geo_redundant_backup_enabled = true - ... - } - - pattern-inside: | - resource "azurerm_postgresql_server" "..." { - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-postgresql-server-connection-throttling-enabled.azure-postgresql-server-connection-throttling-enabled - languages: - - hcl - message: Ensure server parameter connection_throttling is set to ON for PostgreSQL Database Server - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_postgresql_configuration" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_postgresql_configuration" "..." { - ... - name = "connection_throttling" - value = "on" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-postgresql-server-log-checkpoint-enabled.azure-postgresql-server-log-checkpoint-enabled - languages: - - hcl - message: Ensure server parameter log_checkpoints is set to ON for PostgreSQL Database Server - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_postgresql_configuration" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_postgresql_configuration" "..." { - ... - name = "log_checkpoints" - value = "on" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-postgresql-server-log-connections-enabled.azure-postgresql-server-log-connections-enabled - languages: - - hcl - message: Ensure server parameter log_connections is set to ON for PostgreSQL Database Server - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_postgresql_configuration" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_postgresql_configuration" "..." { - ... - name = "log_connections" - value = "on" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-postgresql-ssl-enforcement-enabled.azure-postgresql-ssl-enforcement-enabled - languages: - - hcl - message: Ensure Enforce SSL connection is set to Enabled for PostgreSQL servers - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_postgresql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_postgresql_server" "..." { - ... - ssl_enforcement_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-postgresql-threat-detection-enabled.azure-postgresql-threat-detection-enabled - languages: - - hcl - message: Ensure that PostgreSQL server enables Threat detection policy - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_postgresql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_postgresql_server" "..." { - ... - threat_detection_policy { - ... - enabled = true - ... - } - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-secret-content-type.azure-secret-content-type - languages: - - hcl - message: Ensure that key vault secrets have “content_type” set - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_key_vault_secret" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_key_vault_secret" "..." { - ... - content_type = "..." - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-secret-expiration-date.azure-secret-expiration-date - languages: - - hcl - message: Ensure that the expiration date is set on all secrets - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_key_vault_secret" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_key_vault_secret" "..." { - ... - expiration_date = "..." - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-securitcenter-email-alert.azure-securitcenter-email-alert - languages: - - hcl - message: Ensure that Send email notification for high severity alerts is set to On - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_security_center_contact" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_security_center_contact" "..." { - ... - alert_notifications = true - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-securitycenter-contact-emails.azure-securitycenter-contact-emails - languages: - - hcl - message: Ensure that Security contact emails is set - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_security_center_contact" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_security_center_contact" "..." { - ... - email = "..." - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-securitycenter-contact-phone.azure-securitycenter-contact-phone - languages: - - hcl - message: Ensure that Security contact Phone number is set - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_security_center_contact" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_security_center_contact" "..." { - ... - phone = "..." - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-securitycenter-email-alert-admins.azure-securitycenter-email-alert-admins - languages: - - hcl - message: Ensure that Send email notification for high severity alerts is set to On - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_security_center_contact" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_security_center_contact" "..." { - ... - alerts_to_admins = true - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-securitycenter-standard-pricing.azure-securitycenter-standard-pricing - languages: - - hcl - message: Ensure that standard pricing tier is selected - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_security_center_subscription_pricing" "..." { - ... - tier = "Standard" - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-sqlserver-email-alerts-enabled.azure-sqlserver-email-alerts-enabled - languages: - - hcl - message: Ensure that Send Alerts To is enabled for MSSQL servers - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mssql_server_security_alert_policy" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mssql_server_security_alert_policy" "..." { - ... - state = "Enabled" - email_addresses = ["...", ...] - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-sqlserver-email-alerts-toadmins-enabled.azure-sqlserver-email-alerts-toadmins-enabled - languages: - - hcl - message: Ensure that Email service and co-administrators is Enabled for MSSQL servers - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mssql_server_security_alert_policy" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mssql_server_security_alert_policy" "..." { - ... - state = "Enabled" - email_account_admins = true - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-sqlserver-threat-detection-types.azure-sqlserver-threat-detection-types - languages: - - hcl - message: Ensure that Threat Detection types is set to All - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mssql_server_security_alert_policy" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mssql_server_security_alert_policy" "..." { - ... - state = "Enabled" - disabled_alerts = [] - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-storage-account-enables-secure-transfer.azure-storage-account-enables-secure-transfer - languages: - - hcl - message: Ensure that storage account enables secure transfer - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - enable_https_traffic_only = false - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-synapse-workscape-enables-managed-virtual-network.azure-synapse-workscape-enables-managed-virtual-network - languages: - - hcl - message: Ensure that Azure Synapse workspaces enables managed virtual networks - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_synapse_workspace" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_synapse_workspace" "..." { - ... - managed_virtual_network_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-vmscale-sets-auto-os-image-patching-enabled.azure-vmscale-sets-auto-os-image-patching-enabled - languages: - - hcl - message: Ensure that automatic OS image patching is enabled for Virtual Machine Scale Sets - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_virtual_machine_scale_set" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_virtual_machine_scale_set" "..." { - ... - automatic_os_upgrade = true - os_profile_windows_config { - ... - enable_automatic_upgrades = true - ... - } - ... - } - severity: WARNING - - id: terraform.azure.best-practice.azure-waf-specificed-mode-app-gw.azure-waf-specificed-mode-app-gw - languages: - - hcl - message: Ensure that Application Gateway uses WAF in “Detection” or “Prevention” modes - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_web_application_firewall_policy" "..." { - ... - policy_settings { - enabled = false - } - ... - } - severity: WARNING - - id: terraform.azure.security.aks.azure-aks-apiserver-auth-ip-ranges.azure-aks-apiserver-auth-ip-ranges - languages: - - hcl - message: "Ensure AKS has an API Server Authorized IP Ranges enabled\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_kubernetes_cluster" "..." { - ... - api_server_authorized_ip_ranges = ["..."] - ... - } - - pattern-inside: | - resource "azurerm_kubernetes_cluster" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.aks.azure-aks-private-clusters-enabled.azure-aks-private-clusters-enabled - languages: - - hcl - message: "Ensure that AKS enables private clusters\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_kubernetes_cluster" "..." { - ... - private_cluster_enabled = true - ... - } - - pattern-inside: | - resource "azurerm_kubernetes_cluster" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.aks.azure-aks-uses-disk-encryptionset.azure-aks-uses-disk-encryptionset - languages: - - hcl - message: Ensure that AKS uses disk encryption set - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_kubernetes_cluster" "..." { - ... - disk_encryption_set_id = "..." - ... - } - - pattern-inside: | - resource "azurerm_kubernetes_cluster" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.apiservice.azure-apiservices-use-virtualnetwork.azure-apiservices-use-virtualnetwork - languages: - - hcl - message: Ensure that API management services use virtual networks - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_api_management" "..." { - ... - virtual_network_configuration { - subnet_id = ... - } - ... - } - - pattern-inside: | - resource "azurerm_api_management" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.appservice.appservice-account-identity-registered.appservice-account-identity-registered - languages: - - hcl - message: Registering the identity used by an App with AD allows it to interact with other services without using username and password. Set the `identity` block in your appservice. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-287: Improper Authentication' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A07:2021 - Identification and Authentication Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#identity - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - identity { - type = "..." - identity_ids = "..." - } - ... - } - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - identity { - type = "SystemAssigned" - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: INFO - - id: terraform.azure.security.appservice.appservice-authentication-enabled.appservice-authentication-enabled - languages: - - hcl - message: Enabling authentication ensures that all communications in the application are authenticated. The `auth_settings` block needs to be filled out with the appropriate auth backend settings - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-287: Improper Authentication' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A02:2017 - Broken Authentication - - A07:2021 - Identification and Authentication Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#auth_settings - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - auth_settings { - ... - enabled = true - ... - } - ... - } - - pattern-either: - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - auth_settings { - ... - enabled = false - ... - } - ... - } - severity: ERROR - - id: terraform.azure.security.appservice.appservice-enable-http2.appservice-enable-http2 - languages: - - hcl - message: Use the latest version of HTTP to ensure you are benefiting from security fixes. Add `http2_enabled = true` to your appservice resource block - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-444: Inconsistent Interpretation of HTTP Requests (''HTTP Request/Response Smuggling'')' - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#http2_enabled - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - site_config { - ... - http2_enabled = true - ... - } - ... - } - - pattern-either: - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - site_config { - ... - http2_enabled = false - ... - } - ... - } - severity: INFO - - id: terraform.azure.security.appservice.appservice-enable-https-only.appservice-enable-https-only - languages: - - hcl - message: By default, clients can connect to App Service by using both HTTP or HTTPS. HTTP should be disabled enabling the HTTPS Only setting. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#https_only - - https://docs.microsoft.com/en-us/azure/app-service/configure-ssl-bindings#enforce-https - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - https_only = true - ... - } - - pattern-either: - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - https_only = false - ... - } - severity: ERROR - - id: terraform.azure.security.appservice.appservice-require-client-cert.appservice-require-client-cert - languages: - - hcl - message: Detected an AppService that was not configured to use a client certificate. Add `client_cert_enabled = true` in your resource block. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-295: Improper Certificate Validation' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A07:2021 - Identification and Authentication Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#client_cert_enabled - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - client_cert_enabled = true - ... - } - - pattern-either: - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - client_cert_enabled = false - ... - } - severity: INFO - - id: terraform.azure.security.appservice.appservice-use-secure-tls-policy.appservice-use-secure-tls-policy - languages: - - hcl - message: Detected an AppService that was not configured to use TLS 1.2. Add `site_config.min_tls_version = "1.2"` in your resource block. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#min_tls_version - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: min_tls_version = $ANYTHING - - pattern-inside: | - resource "azurerm_app_service" "$NAME" { - ... - } - - pattern-not-inside: min_tls_version = "1.2" - severity: ERROR - - id: terraform.azure.security.appservice.azure-appservice-auth.azure-appservice-auth - languages: - - hcl - message: Ensure App Service Authentication is set on Azure App Service - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - auth_settings { - ... - enabled = true - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-client-certificate.azure-appservice-client-certificate - languages: - - hcl - message: Ensure the web app has Client Certificates - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - client_cert_enabled = true - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-detailed-errormessages-enabled.azure-appservice-detailed-errormessages-enabled - languages: - - hcl - message: Ensure that App service enables detailed error messages - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-778: Insufficient Logging' - impact: LOW - likelihood: LOW - owasp: - - A10:2017 - Insufficient Logging & Monitoring - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - logs { - ... - detailed_error_messages_enabled = true - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-disallowed-cors.azure-appservice-disallowed-cors - languages: - - hcl - message: Ensure that CORS disallows every resource to access app services - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-942: Permissive Cross-domain Policy with Untrusted Domains' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: | - ["*"] - - pattern-inside: allowed_origins = ... - - pattern-inside: | - $RESOURCE "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-enabled-failed-request.azure-appservice-enabled-failed-request - languages: - - hcl - message: Ensure that App service enables failed request tracing - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-778: Insufficient Logging' - impact: LOW - likelihood: LOW - owasp: - - A10:2017 - Insufficient Logging & Monitoring - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - logs { - ... - failed_request_tracing_enabled = true - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-http-logging-enabled.azure-appservice-http-logging-enabled - languages: - - hcl - message: Ensure that App service enables HTTP logging - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-778: Insufficient Logging' - impact: LOW - likelihood: LOW - owasp: - - A10:2017 - Insufficient Logging & Monitoring - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - logs { - ... - http_logs { - ... - } - } - ... - } - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - logs { - ... - dynamic "http_logs" { - ... - } - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-https-only.azure-appservice-https-only - languages: - - hcl - message: Ensure web app redirects all HTTP traffic to HTTPS in Azure App Service Slot - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - https_only = true - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-identity.azure-appservice-identity - languages: - - hcl - message: Ensure App Service Authentication is set on Azure App Service - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - client_cert_enabled = true - identity { - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-identityprovider-enabled.azure-appservice-identityprovider-enabled - languages: - - hcl - message: Ensure that Managed identity provider is enabled for app services - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_app_service" "..." { - ... - identity { - ... - type = "SystemAssigned" - ... - } - ... - } - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.appservice.azure-appservice-min-tls-version.azure-appservice-min-tls-version - languages: - - hcl - message: Ensure web app is using the latest version of TLS encryption - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern-either: - - pattern: | - "1.0" - - pattern: | - "1.1" - - pattern-inside: min_tls_version = ... - - pattern-inside: | - $RESOURCE "azurerm_app_service" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-automation-encrypted.azure-automation-encrypted - languages: - - hcl - message: Ensure that Automation account variables are encrypted - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern-either: - - pattern-inside: | - resource "azurerm_automation_variable_string" "..." { - ... - } - - pattern-inside: | - resource "azurerm_automation_variable_datetime" "..." { - ... - } - - pattern-inside: | - resource "azurerm_automation_variable_int" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_automation_variable_string" "..." { - ... - encrypted = true - ... - } - - pattern-not-inside: | - resource "azurerm_automation_variable_datetime" "..." { - ... - encrypted = true - ... - } - - pattern-not-inside: | - resource "azurerm_automation_variable_int" "..." { - ... - encrypted = true - ... - } - severity: WARNING - - id: terraform.azure.security.azure-batchaccount-uses-keyvault-encrpytion.azure-batchaccount-uses-keyvault-encrpytion - languages: - - hcl - message: Ensure that Azure Batch account uses key vault to encrypt data - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_batch_account" "..." { - ... - key_vault_reference { - ... - } - ... - } - - pattern-inside: | - resource "azurerm_batch_account" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-cognitiveservices-disables-public-network.azure-cognitiveservices-disables-public-network - languages: - - hcl - message: Ensure that Cognitive Services accounts disable public network access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_cognitive_account" "..." { - ... - public_network_access_enabled = false - ... - } - - pattern-inside: | - resource "azurerm_cognitive_account" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-containergroup-deployed-into-virtualnetwork.azure-containergroup-deployed-into-virtualnetwork - languages: - - hcl - message: Ensure that Azure Container group is deployed into virtual network - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: "resource \"azurerm_container_group\" \"...\" {\n...\ncontainer {\n ...\n}\nnetwork_profile_id = \"...\" \n...\n}\n" - - pattern-inside: | - resource "azurerm_container_group" "..." { - ... - container { - ... - } - ... - } - severity: WARNING - - id: terraform.azure.security.azure-cosmosdb-accounts-restricted-access.azure-cosmosdb-accounts-restricted-access - languages: - - hcl - message: Ensure Cosmos DB accounts have restricted access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_cosmosdb_account" "..." { - ... - public_network_access_enabled = false - ... - } - - pattern-not-inside: | - resource "azurerm_cosmosdb_account" "..." { - ... - is_virtual_network_filter_enabled = true - virtual_network_rule = ... - ... - } - - pattern-not-inside: | - resource "azurerm_cosmosdb_account" "..." { - ... - is_virtual_network_filter_enabled = true - ip_range_filter = [...] - ... - } - - pattern-inside: | - resource "azurerm_cosmosdb_account" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-cosmosdb-disable-access-key-write.azure-cosmosdb-disable-access-key-write - languages: - - hcl - message: Ensure that Cosmos DB accounts have access key write capability disabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_cosmosdb_account" "..." { - ... - access_key_metadata_writes_enabled = false - ... - } - - pattern-inside: | - resource "azurerm_cosmosdb_account" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-cosmosdb-disables-public-network.azure-cosmosdb-disables-public-network - languages: - - hcl - message: Ensure that Azure Cosmos DB disables public network access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_cosmosdb_account" "..." { - ... - public_network_access_enabled = false - ... - } - - pattern-inside: | - resource "azurerm_cosmosdb_account" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-cosmosdb-have-cmk.azure-cosmosdb-have-cmk - languages: - - hcl - message: Ensure that Cosmos DB accounts have customer-managed keys to encrypt data at rest - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_cosmosdb_account" "..." { - ... - key_vault_key_id = ... - ... - } - - pattern-inside: | - resource "azurerm_cosmosdb_account" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-customrole-definition-subscription-owner.azure-customrole-definition-subscription-owner - languages: - - hcl - message: Ensure that no custom subscription owner roles are created - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: | - ["*"] - - pattern-inside: | - resource "azurerm_role_definition" "..." { - permissions { - ... - } - } - - pattern-inside: actions = ... - severity: WARNING - - id: terraform.azure.security.azure-dataexplorer-double-encryption-enabled.azure-dataexplorer-double-encryption-enabled - languages: - - hcl - message: Ensure that Azure Data Explorer uses double encryption - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_kusto_cluster" "..." { - ... - double_encryption_enabled = true - ... - } - - pattern-inside: | - resource "azurerm_kusto_cluster" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-dataexplorer-uses-disk-encryption.azure-dataexplorer-uses-disk-encryption - languages: - - hcl - message: Ensure that Azure Data Explorer uses disk encryption - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_kusto_cluster" "..." { - ... - enable_disk_encryption = true - ... - } - - pattern-inside: | - resource "azurerm_kusto_cluster" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-datafactory-no-public-network-access.azure-datafactory-no-public-network-access - languages: - - hcl - message: Ensure that Azure Data factory public network access is disabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_data_factory" "..." { - ... - public_network_enabled = false - ... - } - - pattern-inside: | - resource "azurerm_data_factory" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-datafactory-uses-git-repository.azure-datafactory-uses-git-repository - languages: - - hcl - message: Ensure that Azure Data Factory uses Git repository for source control - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_data_factory" "..." { - ... - github_configuration { - ... - } - ... - } - - pattern-not-inside: | - resource "azurerm_data_factory" "..." { - ... - vsts_configuration { - ... - } - ... - } - - pattern-inside: | - resource "azurerm_data_factory" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-datalake-store-encryption.azure-datalake-store-encryption - languages: - - hcl - message: Ensure that Data Lake Store accounts enables encryption - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_data_lake_store" "..." { - ... - encryption_state = "Enabled" - ... - } - - pattern-inside: | - resource "azurerm_data_lake_store" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-eventgrid-domain-network-access.azure-eventgrid-domain-network-access - languages: - - hcl - message: Ensure that Azure Event Grid Domain public network access is disabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_eventgrid_domain" "..." { - ... - public_network_access_enabled = false - ... - } - - pattern-inside: | - resource "azurerm_eventgrid_domain" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-functionapp-disallow-cors.azure-functionapp-disallow-cors - languages: - - hcl - message: ensure that CORS disallows all resources to access Function app - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-942: Permissive Cross-domain Policy with Untrusted Domains' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: | - ["*"] - - pattern-inside: allowed_origins = ... - - pattern-inside: | - $RESOURCE "azurerm_function_app" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-functionapps-enable-auth.azure-functionapps-enable-auth - languages: - - hcl - message: Ensure that function apps enables Authentication - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_function_app" "..." { - ... - auth_settings { - ... - enabled = true - ... - } - ... - } - - pattern-inside: | - resource "azurerm_function_app" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-instance-extensions.azure-instance-extensions - languages: - - hcl - message: Ensure Virtual Machine Extensions are not Installed - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "azurerm_linux_virtual_machine" "..." { - ... - } - - pattern-inside: | - resource "azurerm_windows_virtual_machine" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_linux_virtual_machine" "..." { - ... - allow_extension_operations = false - ... - } - - pattern-not-inside: | - resource "azurerm_windows_virtual_machine" "..." { - ... - allow_extension_operations = false - ... - } - severity: WARNING - - id: terraform.azure.security.azure-iot-no-public-network-access.azure-iot-no-public-network-access - languages: - - hcl - message: Ensure that Azure IoT Hub disables public network access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_iothub" "..." { - ... - public_network_access_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.security.azure-key-backedby-hsm.azure-key-backedby-hsm - languages: - - hcl - message: Ensure that key vault key is backed by HSM - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault_key" "..." { - ... - key_type = "EC-HSM" - ... - } - - pattern-not-inside: | - resource "azurerm_key_vault_key" "..." { - ... - key_type = "RSA-HSM" - ... - } - - pattern-inside: | - resource "azurerm_key_vault_key" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-key-no-expiration-date.azure-key-no-expiration-date - languages: - - hcl - message: Ensure that the expiration date is set on all keys - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault_key" "..." { - ... - expiration_date = "..." - ... - } - - pattern-inside: | - resource "azurerm_key_vault_key" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-managed-disk-encryption-set.azure-managed-disk-encryption-set - languages: - - hcl - message: Ensure that managed disks use a specific set of disk encryption sets for the customer-managed key encryption - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_managed_disk" "..." { - ... - disk_encryption_set_id = ... - ... - } - - pattern-inside: | - resource "azurerm_managed_disk" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-managed-disk-encryption.azure-managed-disk-encryption - languages: - - hcl - message: Ensure Azure managed disk has encryption enabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_managed_disk" "..." { - ... - encryption_settings { - ... - enabled = false - ... - } - ... - } - severity: WARNING - - id: terraform.azure.security.azure-mariadb-public-access-disabled.azure-mariadb-public-access-disabled - languages: - - hcl - message: Ensure public network access enabled is set to False for MariaDB servers - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mariadb_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mariadb_server" "..." { - ... - public_network_access_enabled = false - ... - } - severity: WARNING - - id: terraform.azure.security.azure-monitor-log-profile-retention-days.azure-monitor-log-profile-retention-days - languages: - - hcl - message: Ensure that Activity Log Retention is set 365 days or greater - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "azurerm_monitor_log_profile" "..." { - ... - retention_policy { - ... - enabled = true - days = $DAYS - ... - } - ... - } - - pattern-not-inside: | - resource "azurerm_monitor_log_profile" "..." { - ... - retention_policy { - ... - enabled = false - days = 0 - ... - } - ... - } - - metavariable-comparison: - comparison: $DAYS < 365 - metavariable: $DAYS - severity: WARNING - - id: terraform.azure.security.azure-mssql-service-mintls-version.azure-mssql-service-mintls-version - languages: - - hcl - message: Ensure MSSQL is using the latest version of TLS encryption - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern-either: - - pattern: | - "1.0" - - pattern: | - "1.1" - - pattern-inside: minimum_tls_version = ... - - pattern-inside: | - $RESOURCE "azurerm_mssql_server" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-mysql-encryption-enabled.azure-mysql-encryption-enabled - languages: - - hcl - message: Ensure that MySQL server enables infrastructure encryption - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mysql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mysql_server" "..." { - ... - infrastructure_encryption_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.security.azure-mysql-mintls-version.azure-mysql-mintls-version - languages: - - hcl - message: Ensure MySQL is using the latest version of TLS encryption - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern-either: - - pattern: | - "TLS1_0" - - pattern: | - "TLS1_1" - - pattern-inside: ssl_minimal_tls_version_enforced = ... - - pattern-inside: | - $RESOURCE "azurerm_mysql_server" "..." { - ... - } - severity: WARNING - - id: terraform.azure.security.azure-mysql-public-access-disabled.azure-mysql-public-access-disabled - languages: - - hcl - message: Ensure public network access enabled is set to False for MySQL servers - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mysql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mysql_server" "..." { - ... - public_network_access_enabled = false - ... - } - severity: WARNING - - id: terraform.azure.security.azure-network-watcher-flowlog-period.azure-network-watcher-flowlog-period - languages: - - hcl - message: Ensure that Network Security Group Flow Log retention period is 90 days or greater - metadata: - category: best-practice - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_network_watcher_flow_log" "..." { - ... - retention_policy { - ... - enabled = true - days = $DAYS - ... - } - ... - } - - pattern-not-inside: | - resource "azurerm_network_watcher_flow_log" "..." { - ... - retention_policy { - ... - enabled = true - days = 0 - ... - } - ... - } - - metavariable-comparison: - comparison: $DAYS < 90 - metavariable: $DAYS - severity: WARNING - - id: terraform.azure.security.azure-postgresql-encryption-enabled.azure-postgresql-encryption-enabled - languages: - - hcl - message: Ensure that PostgreSQL server enables infrastructure encryption - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_postgresql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_postgresql_server" "..." { - ... - infrastructure_encryption_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.security.azure-postgresql-min-tls-version.azure-postgresql-min-tls-version - languages: - - hcl - message: Ensure PostgreSQL is using the latest version of TLS encryption - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern-either: - - pattern: | - "TLS1_2" - - pattern: | - "TLS1_1" - - pattern: | - "TLS1_0" - - pattern-inside: ssl_minimal_tls_version_enforced = ... - - pattern-inside: | - $RESOURCE "azurerm_postgresql_server" "..." { - ... - } - - pattern-not-inside: | - $RESOURCE "azurerm_postgresql_server" "..." { - ... - ssl_enforcement_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.security.azure-postgresql-server-public-access-disabled.azure-postgresql-server-public-access-disabled - languages: - - hcl - message: Ensure public network access enabled is set to False for PostgreSQL servers - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_postgresql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_postgresql_server" "..." { - ... - public_network_access_enabled = false - ... - } - severity: WARNING - - id: terraform.azure.security.azure-redis-cache-enable-non-ssl-port.azure-redis-cache-enable-non-ssl-port - languages: - - hcl - message: Ensure that only SSL are enabled for Cache for Redis - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_redis_cache" "..." { - ... - enable_non_ssl_port = true - ... - } - severity: WARNING - - id: terraform.azure.security.azure-redis-cache-public-network-access-enabled.azure-redis-cache-public-network-access-enabled - languages: - - hcl - message: Ensure that Azure Cache for Redis disables public network access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_redis_cache" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_redis_cache" "..." { - ... - public_network_access_enabled = false - ... - } - severity: WARNING - - id: terraform.azure.security.azure-remote-debugging-not-enabled.azure-remote-debugging-not-enabled - languages: - - hcl - message: Ensure that remote debugging is not enabled for app services - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_app_service" "..." { - ... - remote_debugging_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.security.azure-scale-set-password.azure-scale-set-password - languages: - - hcl - message: Ensure that Virtual machine does not enable password authentication - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_linux_virtual_machine_scale_set" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_linux_virtual_machine_scale_set" "..." { - ... - disable_password_authentication = true - ... - } - severity: WARNING - - id: terraform.azure.security.azure-search-publicnetwork-access-disabled.azure-search-publicnetwork-access-disabled - languages: - - hcl - message: Ensure that Azure Cognitive Search disables public network access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_search_service" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_search_service" "..." { - ... - public_network_access_enabled = false - ... - } - severity: WARNING - - id: terraform.azure.security.azure-service-fabric-cluster-protection-level.azure-service-fabric-cluster-protection-level - languages: - - hcl - message: Ensure that Service Fabric use three levels of protection available - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_service_fabric_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_service_fabric_cluster" "..." { - ... - fabric_settings { - name = "Security" - parameters = { - ... - name = "ClusterProtectionLevel" - value = "EncryptAndSign" - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.azure.security.azure-sqlserver-no-public-access.azure-sqlserver-no-public-access - languages: - - hcl - message: Ensure no SQL Databases allow ingress from 0.0.0.0/0 (ANY IP) - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mysql_firewall_rule" "..." { - ... - start_ip_address = "0.0.0.0" - end_ip_address = "255.255.255.255" - ... - } - severity: WARNING - - id: terraform.azure.security.azure-sqlserver-public-access-disabled.azure-sqlserver-public-access-disabled - languages: - - hcl - message: Ensure that SQL server disables public network access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_mssql_server" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_mssql_server" "..." { - ... - public_network_access_enabled = false - ... - } - severity: WARNING - - id: terraform.azure.security.azure-storage-account-disable-public-access.azure-storage-account-disable-public-access - languages: - - hcl - message: Ensure default network access rule for Storage Accounts is set to deny - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - allow_blob_public_access = true - ... - } - severity: WARNING - - id: terraform.azure.security.azure-storage-account-minimum-tlsversion.azure-storage-account-minimum-tlsversion - languages: - - hcl - message: Ensure Storage Account is using the latest version of TLS encryption - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_storage_account" "..." { - ... - min_tls_version = "TLS1_2" - ... - } - - pattern-not-inside: | - resource "azurerm_storage_account" "..." { - ... - min_tls_version = "TLS1_3" - ... - } - severity: WARNING - - id: terraform.azure.security.azure-storage-blob-service-container-private-access.azure-storage-blob-service-container-private-access - languages: - - hcl - message: Ensure that Public access level is set to Private for blob containers - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_storage_container" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_storage_container" "..." { - ... - container_access_type = "private" - ... - } - severity: WARNING - - id: terraform.azure.security.azure-storage-sync-public-access-disabled.azure-storage-sync-public-access-disabled - languages: - - hcl - message: Ensure that Azure File Sync disables public network access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-inside: | - resource "azurerm_storage_sync" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_storage_sync" "..." { - ... - incoming_traffic_policy = AllowVirtualNetworksOnly - ... - } - severity: WARNING - - id: terraform.azure.security.azure-vmencryption-at-host-enabled.azure-vmencryption-at-host-enabled - languages: - - hcl - message: Ensure that Virtual machine scale sets have encryption at host enabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "azurerm_windows_virtual_machine_scale_set" "..." { - ... - } - - pattern-inside: | - resource "azurerm_linux_virtual_machine_scale_set" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_windows_virtual_machine_scale_set" "..." { - ... - encryption_at_host_enabled = true - ... - } - - pattern-not-inside: | - resource "azurerm_linux_virtual_machine_scale_set" "..." { - ... - encryption_at_host_enabled = true - ... - } - severity: WARNING - - id: terraform.azure.security.functionapp.functionapp-authentication-enabled.functionapp-authentication-enabled - languages: - - hcl - message: Enabling authentication ensures that all communications in the application are authenticated. The `auth_settings` block needs to be filled out with the appropriate auth backend settings - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-287: Improper Authentication' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A02:2017 - Broken Authentication - - A07:2021 - Identification and Authentication Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/function_app#enabled - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_function_app" "..." { - ... - auth_settings { - ... - enabled = true - ... - } - ... - } - - pattern-either: - - pattern-inside: | - resource "azurerm_function_app" "..." { - ... - } - - pattern-inside: | - resource "azurerm_function_app" "..." { - ... - auth_settings { - ... - enabled = false - ... - } - ... - } - severity: INFO - - id: terraform.azure.security.functionapp.functionapp-enable-http2.functionapp-enable-http2 - languages: - - hcl - message: Use the latest version of HTTP to ensure you are benefiting from security fixes. Add `http2_enabled = true` to your function app resource block - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-444: Inconsistent Interpretation of HTTP Requests (''HTTP Request/Response Smuggling'')' - impact: LOW - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/function_app#http2_enabled - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_function_app" "..." { - ... - site_config { - ... - http2_enabled = true - ... - } - ... - } - - pattern-either: - - pattern-inside: | - resource "azurerm_function_app" "..." { - ... - } - - pattern-inside: | - resource "azurerm_function_app" "..." { - ... - site_config { - ... - http2_enabled = false - ... - } - ... - } - severity: INFO - - id: terraform.azure.security.keyvault.keyvault-content-type-for-secret.keyvault-content-type-for-secret - languages: - - hcl - message: Key vault Secret should have a content type set - metadata: - category: correctness - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret#content_type - - https://docs.microsoft.com/en-us/azure/key-vault/secrets/about-secrets - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault_secret" "..." { - ... - content_type = "..." - ... - } - - pattern-inside: | - resource "azurerm_key_vault_secret" "..." { - ... - } - severity: INFO - - id: terraform.azure.security.keyvault.keyvault-ensure-key-expires.keyvault-ensure-key-expires - languages: - - hcl - message: Ensure that the expiration date is set on all keys - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-262: Not Using Password Aging' - impact: MEDIUM - likelihood: LOW - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key#expiration_date - - https://docs.microsoft.com/en-us/powershell/module/az.keyvault/update-azkeyvaultkey?view=azps-5.8.0#example-1--modify-a-key-to-enable-it--and-set-the-expiration-date-and-tags - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault_key" "..." { - ... - expiration_date = "..." - ... - } - - pattern-inside: | - resource "azurerm_key_vault_key" "..." { - ... - } - severity: INFO - - id: terraform.azure.security.keyvault.keyvault-ensure-secret-expires.keyvault-ensure-secret-expires - languages: - - hcl - message: Ensure that the expiration date is set on all secrets - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-262: Not Using Password Aging' - impact: MEDIUM - likelihood: LOW - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret#expiration_date - - https://docs.microsoft.com/en-us/azure/key-vault/secrets/about-secrets - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault_secret" "..." { - ... - expiration_date = "..." - ... - } - - pattern-inside: | - resource "azurerm_key_vault_secret" "..." { - ... - } - severity: INFO - - id: terraform.azure.security.keyvault.keyvault-purge-enabled.keyvault-purge-enabled - languages: - - hcl - message: Key vault should have purge protection enabled - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-693: Protection Mechanism Failure' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault#purge_protection_enabled - - https://docs.microsoft.com/en-us/azure/key-vault/general/soft-delete-overview#purge-protection - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault" "..." { - ... - purge_protection_enabled = true - ... - } - - pattern-either: - - pattern-inside: | - resource "azurerm_key_vault" "..." { - ... - } - - pattern-inside: | - resource "azurerm_key_vault" "..." { - ... - purge_protection_enabled = false - ... - } - severity: WARNING - - id: terraform.azure.security.keyvault.keyvault-specify-network-acl.keyvault-specify-network-acl - languages: - - hcl - message: Network ACLs allow you to reduce your exposure to risk by limiting what can access your key vault. The default action of the Network ACL should be set to deny for when IPs are not matched. Azure services can be allowed to bypass. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault#network_acls - - https://docs.microsoft.com/en-us/azure/key-vault/general/network-security - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_key_vault" "..." { - ... - network_acls { - ... - default_action = "Deny" - ... - } - ... - } - - pattern-either: - - pattern-inside: | - resource "azurerm_key_vault" "..." { - ... - } - - pattern-inside: | - resource "azurerm_key_vault" "..." { - ... - network_acls { - ... - default_action = "Allow" - ... - } - ... - } - severity: ERROR - - id: terraform.azure.security.storage.storage-allow-microsoft-service-bypass.storage-allow-microsoft-service-bypass - languages: - - hcl - message: Some Microsoft services that interact with storage accounts operate from networks that can't be granted access through network rules. To help this type of service work as intended, allow the set of trusted Microsoft services to bypass the network rules - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#bypass - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account_network_rules#bypass - - https://docs.microsoft.com/en-us/azure/storage/common/storage-network-security#trusted-microsoft-services - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern-not-inside: | - resource "azurerm_storage_account" "..." { - ... - network_rules { - ... - bypass = ["...", "AzureServices"] - ... - } - ... - } - - pattern-not-inside: | - resource "azurerm_storage_account_network_rules" "..." { - ... - bypass = ["...", "AzureServices"] - ... - } - - pattern-either: - - pattern-inside: | - resource "azurerm_storage_account_network_rules" "..." { - ... - bypass = [$ANYTHING] - ... - } - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - network_rules { - ... - bypass = [$ANYTHING] - ... - } - ... - } - severity: WARNING - - id: terraform.azure.security.storage.storage-default-action-deny.storage-default-action-deny - languages: - - hcl - message: Detected a Storage that was not configured to deny action by default. Add `default_action = "Deny"` in your resource block. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-16: CWE CATEGORY: Configuration' - impact: LOW - likelihood: LOW - owasp: - - A06:2017 - Security Misconfiguration - - A05:2021 - Security Misconfiguration - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account_network_rules#default_action - - https://docs.microsoft.com/en-us/azure/firewall/rule-processing - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern: resource - - pattern-not-inside: | - resource "azurerm_storage_account_network_rules" "..." { - ... - default_action = "Deny" - ... - } - - pattern-inside: | - resource "azurerm_storage_account_network_rules" "..." { - ... - default_action = "Allow" - ... - } - severity: ERROR - - id: terraform.azure.security.storage.storage-enforce-https.storage-enforce-https - languages: - - hcl - message: Detected a Storage that was not configured to deny action by default. Add `enable_https_traffic_only = true` in your resource block. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#enable_https_traffic_only - - https://docs.microsoft.com/en-us/azure/storage/common/storage-require-secure-transfer - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern-not-inside: | - resource "azurerm_storage_account" "..." { - ... - enable_https_traffic_only = true - ... - } - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - enable_https_traffic_only = false - ... - } - severity: WARNING - - id: terraform.azure.security.storage.storage-queue-services-logging.storage-queue-services-logging - languages: - - hcl - message: Storage Analytics logs detailed information about successful and failed requests to a storage service. This information can be used to monitor individual requests and to diagnose issues with a storage service. Requests are logged on a best-effort basis. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-778: Insufficient Logging' - impact: LOW - likelihood: LOW - owasp: - - A10:2017 - Insufficient Logging & Monitoring - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging - - https://docs.microsoft.com/en-us/azure/storage/common/storage-analytics-logging?tabs=dotnet - subcategory: - - audit - technology: - - terraform - - azure - patterns: - - pattern-either: - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - queue_properties { - ... - } - ... - } - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_storage_account" "..." { - ... - queue_properties { - ... - logging { - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.azure.security.storage.storage-use-secure-tls-policy.storage-use-secure-tls-policy - languages: - - hcl - message: 'Azure Storage currently supports three versions of the TLS protocol: 1.0, 1.1, and 1.2. Azure Storage uses TLS 1.2 on public HTTPS endpoints, but TLS 1.0 and TLS 1.1 are still supported for backward compatibility. This check will warn if the minimum TLS is not set to TLS1_2.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#min_tls_version - - https://docs.microsoft.com/en-us/azure/storage/common/transport-layer-security-configure-minimum-version - subcategory: - - vuln - technology: - - terraform - - azure - patterns: - - pattern-either: - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - min_tls_version = "$ANYTHING" - ... - } - - pattern-inside: | - resource "azurerm_storage_account" "..." { - ... - } - - pattern-not-inside: | - resource "azurerm_storage_account" "..." { - ... - min_tls_version = "TLS1_2" - ... - } - severity: ERROR - - id: terraform.gcp.best-practice.gcp-compute-shielded-vm.gcp-compute-shielded-vm - languages: - - hcl - message: Ensure Compute instances are launched with Shielded VM enabled - metadata: - category: best-practice - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_compute_instance" "..." { - ... - } - - pattern-inside: | - resource "google_compute_instance" "..." { - ... - shielded_instance_config { - ... - enable_integrity_monitoring = false - ... - } - ... - } - - pattern-not-inside: | - resource "google_compute_instance" "..." { - ... - shielded_instance_config { - ... - enable_integrity_monitoring = true - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-compute-template-shielded-vm.gcp-compute-template-shielded-vm - languages: - - hcl - message: Ensure Compute instances are launched with Shielded VM enabled - metadata: - category: best-practice - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_compute_instance_template" "..." { - ... - shielded_instance_config { - ... - enable_integrity_monitoring = false - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-dnssec-enabled.gcp-dnssec-enabled - languages: - - hcl - message: "Ensure that RSASHA1 is not used for the zone-signing and key-signing keys in Cloud DNS DNSSEC\t" - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_dns_managed_zone" "..." { - ... - } - - pattern-not-inside: | - resource "google_dns_managed_zone" "..." { - ... - dnssec_config { - state = on - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-alias-ip-enabled.gcp-gke-alias-ip-enabled - languages: - - hcl - message: Ensure Kubernetes Cluster is created with Alias IP ranges enabled - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - ip_allocation_policy { - ... - use_ip_aliases = "false" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-binary-authorization.gcp-gke-binary-authorization - languages: - - hcl - message: "Ensure use of Binary Authorization\t" - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - enable_binary_authorization = true - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-enable-shielded-nodes.gcp-gke-enable-shielded-nodes - languages: - - hcl - message: Ensure Shielded GKE Nodes are Enabled - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - enable_shielded_nodes = false - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-has-labels.gcp-gke-has-labels - languages: - - hcl - message: Ensure Kubernetes Clusters are configured with Labels - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - resource_labels = { - "..." = "..." - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-metadata-server-enabled.gcp-gke-metadata-server-enabled - languages: - - hcl - message: "Ensure the GKE Metadata Server is Enabled\t" - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - node_config { - ... - workload_metadata_config { - ... - node_metadata = "GKE_METADATA_SERVER" - ... - } - ... - } - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - node_config { - ... - workload_metadata_config { - ... - mode = "GKE_METADATA" - ... - } - ... - } - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - node_config { - ... - workload_metadata_config = ... - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-nodepool-auto-repair-enabled.gcp-gke-nodepool-auto-repair-enabled - languages: - - hcl - message: Ensure 'Automatic node repair' is enabled for Kubernetes Clusters - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_node_pool" "..." { - ... - management { - ... - auto_repair = false - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-nodepool-auto-upgrade-enabled.gcp-gke-nodepool-auto-upgrade-enabled - languages: - - hcl - message: Ensure 'Automatic node upgrade' is enabled for Kubernetes Clusters - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_node_pool" "..." { - ... - management { - ... - auto_upgrade = false - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-nodepool-metadata-server-enabled.gcp-gke-nodepool-metadata-server-enabled - languages: - - hcl - message: "Ensure the GKE Metadata Server is Enabled\t" - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_node_pool" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_node_pool" "..." { - ... - node_config { - ... - workload_metadata_config { - ... - node_metadata = "GKE_METADATA_SERVER" - ... - } - ... - } - ... - } - - pattern-not-inside: | - resource "google_container_node_pool" "..." { - ... - node_config { - ... - workload_metadata_config { - ... - mode = "GKE_METADATA" - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-nodepool-secure-boot-for-shielded-nodes.gcp-gke-nodepool-secure-boot-for-shielded-nodes - languages: - - hcl - message: "Ensure Secure Boot for Shielded GKE Nodes is Enabled\t" - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_node_pool" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_node_pool" "..." { - ... - shielded_instance_config { - ... - enable_secure_boot = true - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-sql-backup-configuration-enabled.gcp-gke-sql-backup-configuration-enabled - languages: - - hcl - message: Ensure all Cloud SQL database instance have backup configuration enabled - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - } - - pattern-not-inside: | - resource "google_sql_database_instance" "..." { - ... - settings { - ... - backup_configuration { - ... - enabled = true - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-gke-use-cos-image.gcp-gke-use-cos-image - languages: - - hcl - message: Ensure Container-Optimized OS (cos) is used for Kubernetes Engine Clusters Node image - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_node_pool" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_node_pool" "..." { - ... - node_config { - ... - image_type = "COS" - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-ipv6-private-google-enabled.gcp-ipv6-private-google-enabled - languages: - - hcl - message: Ensure that Private google access is enabled for IPV6 - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_compute_subnetwork" "..." { - ... - } - - pattern-not-inside: | - resource "google_compute_subnetwork" "..." { - ... - private_ipv6_google_access = "ENABLE_OUTBOUND_VM_ACCESS_TO_GOOGLE" - ... - } - - pattern-not-inside: | - resource "google_compute_subnetwork" "..." { - ... - private_ipv6_google_access = "ENABLE_BIDIRECTIONAL_ACCESS_TO_GOOGLE" - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-mysql-local-in-file-off.gcp-mysql-local-in-file-off - languages: - - hcl - message: Ensure MySQL database 'local_infile' flag is set to 'off' - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - database_flags { - ... - name = "local_infile" - value = "on" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-postgresql-log-checkpoints.gcp-postgresql-log-checkpoints - languages: - - hcl - message: Ensure PostgreSQL database 'log_checkpoints' flag is set to 'on' - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - database_flags { - ... - name = "log_checkpoints" - value = "off" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-postgresql-log-connection.gcp-postgresql-log-connection - languages: - - hcl - message: Ensure PostgreSQL database 'log_connections' flag is set to 'on' - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - database_flags { - ... - name = "log_connections" - value = "off" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-postgresql-log-disconnection.gcp-postgresql-log-disconnection - languages: - - hcl - message: Ensure PostgreSQL database 'log_disconnections' flag is set to 'on' - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - database_flags { - ... - name = "log_disconnections" - value = "off" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-postgresql-log-lock-waits.gcp-postgresql-log-lock-waits - languages: - - hcl - message: Ensure PostgreSQL database 'log_lock_waits' flag is set to 'on' - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - database_flags { - ... - name = "log_lock_waits" - value = "off" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-postgresql-log-min-duration.gcp-postgresql-log-min-duration - languages: - - hcl - message: Ensure PostgreSQL database 'log_min_duration_statement' flag is set to '-1' - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - database_flags { - ... - } - ... - } - - pattern-not-inside: | - resource "google_sql_database_instance" "..." { - ... - database_flags { - ... - name = "log_min_duration_statement" - value = "-1" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-postgresql-log-min-message.gcp-postgresql-log-min-message - languages: - - hcl - message: Ensure PostgreSQL database 'log_min_messages' flag is set to a valid value - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - database_flags { - ... - name = "log_min_messages" - value = "$VALUE" - ... - } - ... - } - - metavariable-pattern: - language: generic - metavariable: $VALUE - patterns: - - pattern-not-regex: (?i)(DEBUG5|DEBUG4|DEBUG3|DEBUG2|DEBUG1|INFO|NOTICE|WARNING|ERROR|LOG|FATAL|PANIC) - severity: WARNING - - id: terraform.gcp.best-practice.gcp-postgresql-log-temp.gcp-postgresql-log-temp - languages: - - hcl - message: Ensure PostgreSQL database 'log_temp_files' flag is set to '0' - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - database_flags { - ... - } - ... - } - - pattern-not-inside: | - resource "google_sql_database_instance" "..." { - ... - database_flags { - ... - name = "log_temp_files" - value = "0" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.best-practice.gcp-storage-versioning-enabled.gcp-storage-versioning-enabled - languages: - - hcl - message: Ensure Cloud storage has versioning enabled - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_storage_bucket" "..." { - ... - } - - pattern-not-inside: | - resource "google_storage_bucket" "..." { - ... - versioning = { - enabled = true - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-artifact-registry-encrypted-with-cmk.gcp-artifact-registry-encrypted-with-cmk - languages: - - hcl - message: Ensure Artifact Registry Repositories are encrypted with Customer Supplied Encryption Keys (CSEK) - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_artifact_registry_repository" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_artifact_registry_repository" $ANYTHING { - ... - kms_key_name = ... - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-artifact-registry-private-repo-iam-binding.gcp-artifact-registry-private-repo-iam-binding - languages: - - hcl - message: "Ensure that Artifact Registry repositories are not anonymously or publicly accessible\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_artifact_registry_repository_iam_binding" "..." { - ... - members = [ ..., "allAuthenticatedUsers", ...] - ... - } - - pattern-inside: | - resource "google_artifact_registry_repository_iam_binding" "..." { - ... - members = [ ..., "allUsers", ...] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-artifact-registry-private-repo-iam-member.gcp-artifact-registry-private-repo-iam-member - languages: - - hcl - message: "Ensure that Artifact Registry repositories are not anonymously or publicly accessible\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_artifact_registry_repository_iam_member" "..." { - ... - member = "allUsers" - ... - } - - pattern-inside: | - resource "google_artifact_registry_repository_iam_member" "..." { - ... - member = "allAuthenticatedUsers" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-bigquery-dataset-encrypted-with-cmk.gcp-bigquery-dataset-encrypted-with-cmk - languages: - - hcl - message: "Ensure that BigQuery datasets are not anonymously or publicly accessible\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_bigquery_dataset" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_bigquery_dataset" $ANYTHING { - ... - default_encryption_configuration { - ... - kms_key_name = ... - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-bigquery-private-table-iam-binding.gcp-bigquery-private-table-iam-binding - languages: - - hcl - message: "Ensure that BigQuery Tables are not anonymously or publicly accessible\t\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_bigquery_table_iam_binding" "..." { - ... - members = [ ..., "allAuthenticatedUsers", ...] - ... - } - - pattern-inside: | - resource "google_bigquery_table_iam_binding" "..." { - ... - members = [ ..., "allUsers", ...] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-bigquery-private-table-iam-member.gcp-bigquery-private-table-iam-member - languages: - - hcl - message: "Ensure that BigQuery Tables are not anonymously or publicly accessible\t\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_bigquery_table_iam_member" "..." { - ... - member = "allAuthenticatedUsers" - ... - } - - pattern-inside: | - resource "google_bigquery_table_iam_member" "..." { - ... - member = "allUsers" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-bigquery-table-encrypted-with-cmk.gcp-bigquery-table-encrypted-with-cmk - languages: - - hcl - message: "Ensure Big Query Tables are encrypted with Customer Supplied Encryption Keys (CSEK)\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_bigquery_table" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_bigquery_table" $ANYTHING { - ... - encryption_configuration { - ... - kms_key_name = ... - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-bigtable-instance-encrypted-with-cmk.gcp-bigtable-instance-encrypted-with-cmk - languages: - - hcl - message: "Ensure Big Table Instances are encrypted with Customer Supplied Encryption Keys (CSEK)\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_bigtable_instance" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_bigtable_instance" $ANYTHING { - ... - cluster { - ... - kms_key_name = ... - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-build-workers-private.gcp-build-workers-private - languages: - - hcl - message: "Ensure Cloud build workers are private\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_cloudbuild_worker_pool" "..." { - ... - } - - pattern-not-inside: | - resource "google_cloudbuild_worker_pool" "..." { - ... - worker_config { - ... - no_external_ip = true - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-cloud-storage-logging.gcp-cloud-storage-logging - languages: - - hcl - message: Ensure bucket logs access. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-778: Insufficient Logging' - impact: LOW - likelihood: LOW - owasp: - - A10:2017 - Insufficient Logging & Monitoring - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - vuln - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_storage_bucket" $ANYTHING { - ... - } - - pattern-not-inside: "resource \"google_storage_bucket\" $ANYTHING {\n ...\n logging {\n log_bucket = ...\n } \n ...\n}\n" - severity: WARNING - - id: terraform.gcp.security.gcp-compute-boot-disk-encryption.gcp-compute-boot-disk-encryption - languages: - - hcl - message: Ensure VM disks for critical VMs are encrypted with Customer Supplied Encryption Keys (CSEK) - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_compute_instance" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_compute_instance" $ANYTHING { - ... - boot_disk { - disk_encryption_key_raw = ... - } - ... - } - - pattern-not-inside: | - resource "google_compute_instance" $ANYTHING { - ... - boot_disk { - kms_key_self_link = ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-disk-encryption.gcp-compute-disk-encryption - languages: - - hcl - message: Ensure VM disks for critical VMs are encrypted with Customer Supplied Encryption Keys (CSEK) - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_compute_disk" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_compute_disk" $ANYTHING { - ... - disk_encryption_key { - raw_key = ... - } - ... - } - - pattern-not-inside: | - resource "google_compute_disk" $ANYTHING { - ... - disk_encryption_key { - kms_key_self_link = ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-20.gcp-compute-firewall-unrestricted-ingress-20 - languages: - - hcl - message: Ensure Google compute firewall ingress does not allow unrestricted FTP access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [20] - } - source_ranges = ["0.0.0.0/0"] - ... - } - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [..., "20", ...] - } - source_ranges = ["0.0.0.0/0"] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-21.gcp-compute-firewall-unrestricted-ingress-21 - languages: - - hcl - message: Ensure Google compute firewall ingress does not allow unrestricted FTP access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [21] - } - source_ranges = ["0.0.0.0/0"] - ... - } - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [..., "21", ...] - } - source_ranges = ["0.0.0.0/0"] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-22.gcp-compute-firewall-unrestricted-ingress-22 - languages: - - hcl - message: Ensure Google compute firewall ingress does not allow unrestricted SSH access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [22] - } - source_ranges = ["0.0.0.0/0"] - ... - } - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [..., "22", ...] - } - source_ranges = ["0.0.0.0/0"] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-3306.gcp-compute-firewall-unrestricted-ingress-3306 - languages: - - hcl - message: Ensure Google compute firewall ingress does not allow unrestricted MySQL access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [3306] - } - source_ranges = ["0.0.0.0/0"] - ... - } - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [..., "3306", ...] - } - source_ranges = ["0.0.0.0/0"] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-3389.gcp-compute-firewall-unrestricted-ingress-3389 - languages: - - hcl - message: Ensure Google compute firewall ingress does not allow unrestricted RDP access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [3389] - } - source_ranges = ["0.0.0.0/0"] - ... - } - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [..., "3389", ...] - } - source_ranges = ["0.0.0.0/0"] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-firewall-unrestricted-ingress-80.gcp-compute-firewall-unrestricted-ingress-80 - languages: - - hcl - message: Ensure Google compute firewall ingress does not allow unrestricted HTTP access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [80] - } - source_ranges = ["0.0.0.0/0"] - ... - } - - pattern-inside: | - resource "google_compute_firewall" "..." { - ... - allow { - protocol = "tcp" - ports = [..., "80", ...] - } - source_ranges = ["0.0.0.0/0"] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-ip-forward.gcp-compute-ip-forward - languages: - - hcl - message: "Ensure that IP forwarding is not enabled on Instances. This lets the instance act as a traffic router and receive traffic not intended for it, which may route traffic through unintended passages.\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_compute_instance" "..." { - ... - can_ip_forward = true - ... - } - severity: INFO - - id: terraform.gcp.security.gcp-compute-os-login.gcp-compute-os-login - languages: - - hcl - message: "Ensure that no instance in the project overrides the project setting for enabling OSLogin (OSLogin needs to be enabled in project metadata for all instances)\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_compute_instance" "..." { - ... - metadata = { - enable-oslogin = false - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-project-os-login.gcp-compute-project-os-login - languages: - - hcl - message: "Ensure oslogin is enabled for a Project\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_compute_project_metadata" "..." { - ... - } - - pattern-not-inside: | - resource "google_compute_project_metadata" "..." { - ... - metadata = { - enable-oslogin = "True" - } - ... - } - - pattern-not-inside: | - resource "google_compute_project_metadata" "..." { - ... - metadata = { - enable-oslogin = True - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-public-ip.gcp-compute-public-ip - languages: - - hcl - message: "Ensure that Compute instances do not have public IP addresses\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_compute_instance" "..." { - ... - network_interface { - ... - network = "default" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-serial-ports.gcp-compute-serial-ports - languages: - - hcl - message: "Ensure 'Enable connecting to serial ports' is not enabled for VM Instance\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_compute_instance" "..." { - ... - metadata = { - serial-port-enable = true - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-ssl-policy.gcp-compute-ssl-policy - languages: - - hcl - message: Ensure no HTTPS or SSL proxy load balancers permit SSL policies with weak cipher suites - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_compute_ssl_policy" "..." { - ... - profile = "MODERN" - ... - } - - pattern-inside: | - resource "google_compute_ssl_policy" "..." { - ... - profile = "CUSTOM" - custom_features = [..., "TLS_RSA_WITH_AES_256_GCM_SHA384", ...] - ... - } - - pattern-not-inside: | - resource "google_compute_ssl_policy" "..." { - ... - profile = "MODERN" - min_tls_version = "TLS_1_2" - ... - } - - pattern-not-inside: | - resource "google_compute_ssl_policy" "..." { - ... - profile = "CUSTOM" - custom_features = ["TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-compute-template-ip-forward.gcp-compute-template-ip-forward - languages: - - hcl - message: Ensure that IP forwarding is not enabled on Instances. This lets the instance act as a traffic router and receive traffic not intended for it, which may route traffic through unintended passages. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/disable-ip-forwarding.html - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_compute_instance_template" "..." { - ... - can_ip_forward = true - ... - } - severity: INFO - - id: terraform.gcp.security.gcp-compute-template-public-ip.gcp-compute-template-public-ip - languages: - - hcl - message: "Ensure that Compute instances do not have public IP addresses\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_compute_instance_template" "..." { - ... - network_interface { - ... - network = "default" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-dataflow-job-encrypted-with-cmk.gcp-dataflow-job-encrypted-with-cmk - languages: - - hcl - message: Ensure data flow jobs are encrypted with Customer Supplied Encryption Keys (CSEK) - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_dataflow_job" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_dataflow_job" $ANYTHING { - ... - kms_key_name = ... - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-dataflow-private-job.gcp-dataflow-private-job - languages: - - hcl - message: Ensure Dataflow jobs are private - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_dataflow_job" "..." { - ... - } - - pattern-not-inside: | - resource "google_dataflow_job" "..." { - ... - ip_configuration = "WORKER_IP_PRIVATE" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-datafusion-private-instance.gcp-datafusion-private-instance - languages: - - hcl - message: Ensure Data fusion instances are private - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_data_fusion_instance" "..." { - ... - } - - pattern-not-inside: | - resource "google_data_fusion_instance" "..." { - ... - private_instance = true - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-datafusion-stack-driver-logging.gcp-datafusion-stack-driver-logging - languages: - - hcl - message: Ensure Datafusion has stack driver logging enabled. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern-inside: | - resource "google_data_fusion_instance" $ANYTHING { - ... - } - - pattern-not-inside: "resource \"google_data_fusion_instance\" $ANYTHING {\n ...\n enable_stackdriver_logging = true \n ...\n}\n" - severity: WARNING - - id: terraform.gcp.security.gcp-datafusion-stack-driver-monitoring.gcp-datafusion-stack-driver-monitoring - languages: - - hcl - message: Ensure Datafusion has stack driver monitoring enabled. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern-inside: | - resource "google_data_fusion_instance" $ANYTHING { - ... - } - - pattern-not-inside: "resource \"google_data_fusion_instance\" $ANYTHING {\n ...\n enable_stackdriver_monitoring = true \n ...\n}\n" - severity: WARNING - - id: terraform.gcp.security.gcp-dataproc-cluster-encrypted-with-cmk.gcp-dataproc-cluster-encrypted-with-cmk - languages: - - hcl - message: "Ensure Dataproc cluster is encrypted with Customer Supplied Encryption Keys (CSEK)\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_dataproc_cluster" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_dataproc_cluster" $ANYTHING { - ... - cluster_config { - encryption_config { - ... - kms_key_name = ... - ... - } - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-dataproc-cluster-public-ip.gcp-dataproc-cluster-public-ip - languages: - - hcl - message: Ensure Dataproc Clusters do not have public IPs - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_dataproc_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_dataproc_cluster" "..." { - ... - cluster_config { - gce_cluster_config { - ... - internal_ip_only = true - ... - } - ... - } - } - severity: WARNING - - id: terraform.gcp.security.gcp-dataproc-private-cluster-iam-binding.gcp-dataproc-private-cluster-iam-binding - languages: - - hcl - message: Ensure that Dataproc clusters are not anonymously or publicly accessible - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_dataproc_cluster_iam_binding" "..." { - ... - members = [ ..., "allAuthenticatedUsers", ...] - ... - } - - pattern-inside: | - resource "google_dataproc_cluster_iam_binding" "..." { - ... - members = [ ..., "allUsers", ...] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-dataproc-private-cluster-iam-member.gcp-dataproc-private-cluster-iam-member - languages: - - hcl - message: Ensure that Dataproc clusters are not anonymously or publicly accessible - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_dataproc_cluster_iam_member" "..." { - ... - member = "allUsers" - ... - } - - pattern-inside: | - resource "google_dataproc_cluster_iam_member" "..." { - ... - member = "allAuthenticatedUsers" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-dns-key-specs-rsasha1.gcp-dns-key-specs-rsasha1 - languages: - - hcl - message: "Ensure that RSASHA1 is not used for the zone-signing and key-signing keys in Cloud DNS DNSSEC\t" - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_dns_managed_zone" "..." { - ... - dnssec_config { - ... - default_key_specs { - ... - algorithm = "rsasha1" - key_type = "zoneSigning" - ... - } - ... - } - ... - } - - pattern-inside: | - resource "google_dns_managed_zone" "..." { - ... - dnssec_config { - ... - default_key_specs { - ... - algorithm = "rsasha1" - key_type = "keySigning" - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-folder-impersonation-roles-iam-binding.gcp-folder-impersonation-roles-iam-binding - languages: - - hcl - message: "Ensure no roles that enable to impersonate and manage all service accounts are used at a folder level\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_folder_iam_binding" "..." { - ... - role = "roles/editor" - members = [ ... ] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-folder-impersonation-roles-iam-member.gcp-folder-impersonation-roles-iam-member - languages: - - hcl - message: "Ensure no roles that enable to impersonate and manage all service accounts are used at a folder level\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_folder_iam_member" "..." { - ... - role = "roles/editor" - member = ... - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-folder-member-default-service-account-iam-binding.gcp-folder-member-default-service-account-iam-binding - languages: - - hcl - message: Ensure Default Service account is not used at a folder level - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_folder_iam_binding" "..." { - ... - members = [..., $MEMBER, ...] - ... - } - - metavariable-regex: - metavariable: $MEMBER - regex: ((.*)-compute@appspot.gserviceaccount.com) - severity: WARNING - - id: terraform.gcp.security.gcp-folder-member-default-service-account-iam-member.gcp-folder-member-default-service-account-iam-member - languages: - - hcl - message: Ensure Default Service account is not used at a folder level - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_folder_iam_member" "..." { - ... - member = $MEMBER - ... - } - - metavariable-regex: - metavariable: $MEMBER - regex: ((.*)-compute@developer.gserviceaccount.com) - severity: WARNING - - id: terraform.gcp.security.gcp-gke-basic-auth.gcp-gke-basic-auth - languages: - - hcl - message: "Ensure GKE basic auth is disabled\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - master_auth { - client_certificate_config { - ... - } - } - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - master_auth { - ... - username = "" - password = "" - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-client-certificate-disabled.gcp-gke-client-certificate-disabled - languages: - - hcl - message: Ensure client certificate authentication to Kubernetes Engine Clusters is disabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - master_auth { - ... - client_certificate_config { - ... - issue_client_certificate = false - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-cluster-logging.gcp-gke-cluster-logging - languages: - - hcl - message: Ensure logging is set to Enabled on Kubernetes Engine Clusters - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_container_cluster" $ANYTHING { - ... - logging_service = "none" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-enabled-vpc-flow-logs.gcp-gke-enabled-vpc-flow-logs - languages: - - hcl - message: Enable VPC Flow Logs and Intranode Visibility - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern-inside: | - resource "google_container_cluster" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" $ANYTHING { - ... - enable_intranode_visibility = true - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-ensure-integrity-monitoring.gcp-gke-ensure-integrity-monitoring - languages: - - hcl - message: Ensure Integrity Monitoring for Shielded GKE Nodes is Enabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern-inside: "resource \"google_container_cluster\" $ANYTHING {\n ...\n node_config {\n ...\n shielded_instance_config {\n enable_integrity_monitoring = false\n }\n ...\n } \n ...\n}\n" - severity: WARNING - - id: terraform.gcp.security.gcp-gke-kubernetes-rbac-google-groups.gcp-gke-kubernetes-rbac-google-groups - languages: - - hcl - message: Manage Kubernetes RBAC users with Google Groups for GKE - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - authenticator_groups_config { - ... - security_group = "..." - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-legacy-auth-enabled.gcp-gke-legacy-auth-enabled - languages: - - hcl - message: Ensure Legacy Authorization is set to Disabled on Kubernetes Engine Clusters - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - enable_legacy_abac = true - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-legacy-instance-metadata-disabled.gcp-gke-legacy-instance-metadata-disabled - languages: - - hcl - message: Ensure legacy Compute Engine instance metadata APIs are Disabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - min_master_version = 1.12 - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - min_master_version = 1.13 - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-master-authz-networks-enabled.gcp-gke-master-authz-networks-enabled - languages: - - hcl - message: Ensure master authorized networks is set to enabled in GKE clusters - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - master_authorized_networks_config { - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-monitoring-enabled.gcp-gke-monitoring-enabled - languages: - - hcl - message: Ensure monitoring is set to Enabled on Kubernetes Engine Clusters - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern-inside: "resource \"google_container_cluster\" $ANYTHING {\n ...\n monitoring_service = \"none\" \n ...\n}\n" - severity: WARNING - - id: terraform.gcp.security.gcp-gke-network-policy-enabled.gcp-gke-network-policy-enabled - languages: - - hcl - message: Ensure Network Policy is enabled on Kubernetes Engine Clusters - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - network_policy { - ... - enabled = false - ... - } - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - datapath_provider = "ADVANCED_DATAPATH" - network_policy { - ... - enabled = false - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-nodepool-integrity-monitoring.gcp-gke-nodepool-integrity-monitoring - languages: - - hcl - message: Ensure Integrity Monitoring for Shielded GKE Nodes is Enabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern-inside: "resource \"google_container_node_pool\" $ANYTHING {\n ...\n node_config {\n ...\n shielded_instance_config {\n enable_integrity_monitoring = false\n }\n ...\n } \n ...\n}\n" - severity: WARNING - - id: terraform.gcp.security.gcp-gke-pod-security-policy-enabled.gcp-gke-pod-security-policy-enabled - languages: - - hcl - message: Ensure PodSecurityPolicy controller is enabled on the Kubernetes Engine Clusters - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - pod_security_policy_config { - ... - enabled = true - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-private-cluster-config.gcp-gke-private-cluster-config - languages: - - hcl - message: Ensure Kubernetes Cluster is created with Private cluster enabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - private_cluster_config { - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-public-control-plane.gcp-gke-public-control-plane - languages: - - hcl - message: Ensure GKE Control Plane is not public - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - master_authorized_networks_config { - ... - cidr_blocks { - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-gke-secure-boot-for-shielded-nodes.gcp-gke-secure-boot-for-shielded-nodes - languages: - - hcl - message: "Ensure Secure Boot for Shielded GKE Nodes is Enabled\t" - metadata: - category: best-practice - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_container_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "google_container_cluster" "..." { - ... - shielded_instance_config { - ... - enable_secure_boot = true - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-insecure-load-balancer-tls-version.gcp-insecure-load-balancer-tls-version - languages: - - terraform - message: Detected GCP Load Balancer to be using an insecure version of TLS. To fix this set your "min_tls_version" to "TLS_1_2" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.bridgecrew.io/docs/google-cloud-policy-index - subcategory: - - audit - technology: - - gcp - - terraform - patterns: - - pattern: | - resource "google_compute_ssl_policy" $ANYTHING { - ... - min_tls_version = "..." - ... - } - - pattern-not: | - resource "google_compute_ssl_policy" $ANYTHING { - ... - min_tls_version = "TLS_1_2" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-kms-prevent-destroy.gcp-kms-prevent-destroy - languages: - - hcl - message: Ensure KMS keys are protected from deletion - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_kms_crypto_key" "..." { - ... - } - - pattern-not-inside: | - resource "google_kms_crypto_key" "..." { - ... - lifecycle { - prevent_destroy = true - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-memory-store-for-redis-auth-enabled.gcp-memory-store-for-redis-auth-enabled - languages: - - hcl - message: Ensure Memorystore for Redis has AUTH enabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_redis_instance" "..." { - ... - } - - pattern-not-inside: | - resource "google_redis_instance" "..." { - ... - auth_enabled = true - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-memory-store-for-redis-intransit-encryption.gcp-memory-store-for-redis-intransit-encryption - languages: - - hcl - message: Ensure Memorystore for Redis uses intransit encryption - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_redis_instance" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_redis_instance" $ANYTHING { - ... - transit_encryption_mode = "SERVER_AUTHENTICATION" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-org-impersonation-roles-iam-binding.gcp-org-impersonation-roles-iam-binding - languages: - - hcl - message: "Ensure no roles that enable to impersonate and manage all service accounts are used at an organization level\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_organization_iam_binding" "..." { - ... - role = "roles/editor" - members = [ ... ] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-org-impersonation-roles-iam-member.gcp-org-impersonation-roles-iam-member - languages: - - hcl - message: "Ensure no roles that enable to impersonate and manage all service accounts are used at an organization level\t" - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_organization_iam_member" "..." { - ... - role = "roles/editor" - member = ... - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-org-member-default-service-account-iam-binding.gcp-org-member-default-service-account-iam-binding - languages: - - hcl - message: Ensure default service account is not used at an organization level - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_organization_iam_binding" "..." { - ... - members = [..., $MEMBER, ...] - ... - } - - metavariable-regex: - metavariable: $MEMBER - regex: ((.*)-compute@developer.gserviceaccount.com) - severity: WARNING - - id: terraform.gcp.security.gcp-org-member-default-service-account-iam-member.gcp-org-member-default-service-account-iam-member - languages: - - hcl - message: Ensure default service account is not used at an organization level - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_organization_iam_member" "..." { - ... - member = $MEMBER - ... - } - - metavariable-regex: - metavariable: $MEMBER - regex: ((.*)-compute@developer.gserviceaccount.com) - severity: WARNING - - id: terraform.gcp.security.gcp-project-default-network.gcp-project-default-network - languages: - - hcl - message: Ensure that the default network does not exist in a project. Set auto_create_network to `false`. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_project" "..." { - ... - } - - pattern-not-inside: | - resource "google_project" "..." { - ... - auto_create_network = false - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-project-member-default-service-account-iam-binding.gcp-project-member-default-service-account-iam-binding - languages: - - hcl - message: Ensure Default Service account is not used at a project level - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_project_iam_binding" "..." { - ... - members = [..., $MEMBER, ...] - ... - } - - metavariable-regex: - metavariable: $MEMBER - regex: ((.*)-compute@developer.gserviceaccount.com) - severity: WARNING - - id: terraform.gcp.security.gcp-project-member-default-service-account-iam-member.gcp-project-member-default-service-account-iam-member - languages: - - hcl - message: Ensure Default Service account is not used at a project level - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_project_iam_member" "..." { - ... - member = $MEMBER - ... - } - - metavariable-regex: - metavariable: $MEMBER - regex: ((.*)-compute@developer.gserviceaccount.com) - severity: WARNING - - id: terraform.gcp.security.gcp-project-service-account-user-iam-binding.gcp-project-service-account-user-iam-binding - languages: - - hcl - message: Ensure that IAM users are not assigned the Service Account User or Service Account Token Creator roles at project level - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_project_iam_binding" "..." { - ... - role = "roles/iam.serviceAccountTokenCreator" - ... - } - - pattern-inside: | - resource "google_project_iam_binding" "..." { - ... - role = "roles/iam.serviceAccountUser" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-project-service-account-user-iam-member.gcp-project-service-account-user-iam-member - languages: - - hcl - message: Ensure that IAM users are not assigned the Service Account User or Service Account Token Creator roles at project level - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_project_iam_member" "..." { - ... - role = "roles/iam.serviceAccountTokenCreator" - ... - } - - pattern-inside: | - resource "google_project_iam_member" "..." { - ... - role = "roles/iam.serviceAccountUser" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-pubsub-encrypted-with-cmk.gcp-pubsub-encrypted-with-cmk - languages: - - hcl - message: Ensure PubSub Topics are encrypted with Customer Supplied Encryption Keys (CSEK) - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_pubsub_topic" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_pubsub_topic" $ANYTHING { - ... - kms_key_name = ... - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-pubsub-private-topic-iam-binding.gcp-pubsub-private-topic-iam-binding - languages: - - hcl - message: Ensure that Pub/Sub Topics are not anonymously or publicly accessible - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_pubsub_topic_iam_binding" "..." { - ... - members = [ ..., "allAuthenticatedUsers", ...] - ... - } - - pattern-inside: | - resource "google_pubsub_topic_iam_binding" "..." { - ... - members = [ ..., "allUsers", ...] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-pubsub-private-topic-iam-member.gcp-pubsub-private-topic-iam-member - languages: - - hcl - message: Ensure that Pub/Sub Topics are not anonymously or publicly accessible - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_pubsub_topic_iam_member" "..." { - ... - member = "allUsers" - ... - } - - pattern-inside: | - resource "google_pubsub_topic_iam_member" "..." { - ... - member = "allAuthenticatedUsers" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-run-private-service-iam-binding.gcp-run-private-service-iam-binding - languages: - - hcl - message: Ensure that GCP Cloud Run services are not anonymously or publicly accessible - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_cloud_run_service_iam_binding" "..." { - ... - members = [ ..., "allAuthenticatedUsers", ...] - ... - } - - pattern-inside: | - resource "google_cloud_run_service_iam_binding" "..." { - ... - members = [ ..., "allUsers", ...] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-run-private-service-iam-member.gcp-run-private-service-iam-member - languages: - - hcl - message: Ensure that GCP Cloud Run services are not anonymously or publicly accessible - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_cloud_run_service_iam_member" "..." { - ... - member = "allAuthenticatedUsers" - ... - } - - pattern-inside: | - resource "google_cloud_run_service_iam_member" "..." { - ... - member = "allUsers" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-spanner-database-encrypted-with-cmk.gcp-spanner-database-encrypted-with-cmk - languages: - - hcl - message: Ensure Spanner Database is encrypted with Customer Supplied Encryption Keys (CSEK) - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_spanner_database" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_spanner_database" $ANYTHING { - ... - encryption_config { - ... - kms_key_name = ... - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-sql-database-require-ssl.gcp-sql-database-require-ssl - languages: - - hcl - message: Ensure all Cloud SQL database instance requires all incoming connections to use SSL - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-326: Inadequate Encryption Strength' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - vuln - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - } - - pattern-not-inside: | - resource "google_sql_database_instance" "..." { - ... - ip_configuration { - ... - require_ssl = true - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-sql-public-database.gcp-sql-public-database - languages: - - hcl - message: Ensure that Cloud SQL database Instances are not open to the world - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-284: Improper Access Control' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - vuln - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-either: - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - ip_configuration { - ... - authorized_networks { - ... - value = "0.0.0.0/0" - ... - } - ... - } - ... - } - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - ip_configuration { - ... - dynamic "authorized_networks" { - ... - content { - ... - value = "0.0.0.0/0" - ... - } - ... - } - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-sqlserver-no-public-ip.gcp-sqlserver-no-public-ip - languages: - - hcl - message: Ensure Cloud SQL database does not have public IP - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_sql_database_instance" "..." { - ... - ip_configuration { - ... - ipv4_enabled = true - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-storage-bucket-not-public-iam-binding.gcp-storage-bucket-not-public-iam-binding - languages: - - hcl - message: Ensure that Container Registry repositories are not anonymously or publicly accessible - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_storage_bucket_iam_binding" "..." { - ... - members = [ ..., "allAuthenticatedUsers", ...] - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-storage-bucket-not-public-iam-member.gcp-storage-bucket-not-public-iam-member - languages: - - hcl - message: Ensure that Container Registry repositories are not anonymously or publicly accessible - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_storage_bucket_iam_member" "..." { - ... - member = "allUsers" - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-storage-bucket-uniform-access.gcp-storage-bucket-uniform-access - languages: - - hcl - message: Ensure that Cloud Storage buckets have uniform bucket-level access enabled - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_storage_bucket" "..." { - ... - } - - pattern-not-inside: | - resource "google_storage_bucket" "..." { - ... - uniform_bucket_level_access = true - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-sub-network-logging-enabled.gcp-sub-network-logging-enabled - languages: - - hcl - message: Ensure that VPC Flow Logs is enabled for every subnet in a VPC Network - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_compute_subnetwork" $ANYTHING { - ... - } - - pattern-not-inside: "resource \"google_compute_subnetwork\" $ANYTHING {\n ...\n log_config {\n ...\n } \n ...\n}\n" - severity: WARNING - - id: terraform.gcp.security.gcp-sub-network-private-google-enabled.gcp-sub-network-private-google-enabled - languages: - - hcl - message: Ensure that private_ip_google_access is enabled for Subnet - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_compute_subnetwork" "..." { - ... - } - - pattern-not-inside: | - resource "google_compute_subnetwork" "..." { - ... - private_ip_google_access = true - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-vertexai-dataset-encrypted-with-cmk.gcp-vertexai-dataset-encrypted-with-cmk - languages: - - hcl - message: Ensure Vertex AI datasets uses a CMK (Customer Manager Key) - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_vertex_ai_dataset" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_vertex_ai_dataset" $ANYTHING { - ... - encryption_spec { - ... - kms_key_name = ... - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-vertexai-metadata-store-encrypted-with-cmk.gcp-vertexai-metadata-store-encrypted-with-cmk - languages: - - hcl - message: Ensure Vertex AI Metadata Store uses a CMK (Customer Manager Key) - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-320: CWE CATEGORY: Key Management Errors' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: | - resource "google_vertex_ai_metadata_store" $ANYTHING { - ... - } - - pattern-not-inside: | - resource "google_vertex_ai_metadata_store" $ANYTHING { - ... - encryption_spec { - ... - kms_key_name = ... - ... - } - ... - } - severity: WARNING - - id: terraform.gcp.security.gcp-vertexai-private-instance.gcp-vertexai-private-instance - languages: - - hcl - message: Ensure Vertex AI instances are private - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - gcp - patterns: - - pattern: resource - - pattern-inside: | - resource "google_notebooks_instance" "..." { - ... - } - - pattern-not-inside: | - resource "google_notebooks_instance" "..." { - ... - no_public_ip = true - ... - } - severity: WARNING - - id: terraform.lang.security.ec2-imdsv1-optional.ec2-imdsv1-optional - languages: - - hcl - message: AWS EC2 Instance allowing use of the IMDSv1 - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-918: Server-Side Request Forgery (SSRF)' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A10:2021 - Server-Side Request Forgery (SSRF) - references: - - https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#metadata-options - subcategory: - - vuln - technology: - - terraform - - aws - pattern-either: - - patterns: - - pattern: http_tokens = "optional" - - pattern-inside: | - metadata_options { ... } - - patterns: - - pattern: | - resource "aws_instance" "$NAME" { - ... - } - - pattern-not: | - resource "aws_instance" "$NAME" { - ... - metadata_options { - ... - http_tokens = "required" - ... - } - ... - } - - pattern-not: | - resource "aws_instance" "$NAME" { - ... - metadata_options { - ... - http_tokens = "optional" - ... - } - ... - } - - pattern-not: | - resource "aws_instance" "$NAME" { - ... - metadata_options { - ... - http_endpoint = "disabled" - ... - } - ... - } - severity: ERROR - - id: terraform.lang.security.ecr-image-scan-on-push.ecr-image-scan-on-push - languages: - - hcl - message: The ECR Repository isn't configured to scan images on push - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-1104: Use of Unmaintained Third Party Components' - impact: LOW - likelihood: LOW - owasp: - - A06:2021 - Vulnerable and Outdated Components - references: - - https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: resource - - pattern-not-inside: | - resource "aws_ecr_repository" "..." { - ... - image_scanning_configuration { - ... - scan_on_push=true - ... - } - ... - } - - pattern-inside: | - resource "aws_ecr_repository" "..." { - ... - } - severity: WARNING - - id: terraform.lang.security.eks-insufficient-control-plane-logging.eks-insufficient-control-plane-logging - languages: - - hcl - message: Missing EKS control plane logging. It is recommended to enable at least Kubernetes API server component logs ("api") and audit logs ("audit") of the EKS control plane through the enabled_cluster_log_types attribute. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-778: Insufficient Logging' - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A10:2017 - Insufficient Logging & Monitoring - - A09:2021 - Security Logging and Monitoring Failures - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_cluster#enabling-control-plane-logging - - https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - name = ... - - pattern-inside: | - resource "aws_eks_cluster" "..." { - ... - } - - pattern-not-inside: | - resource "aws_eks_cluster" "..." { - ... - enabled_cluster_log_types = [..., "api", ..., "audit", ...] - ... - } - - pattern-not-inside: | - resource "aws_eks_cluster" "..." { - ... - enabled_cluster_log_types = [..., "audit", ..., "api", ...] - ... - } - severity: WARNING - - id: terraform.lang.security.eks-public-endpoint-enabled.eks-public-endpoint-enabled - languages: - - hcl - message: The vpc_config resource inside the eks cluster has not explicitly disabled public endpoint access - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource - - pattern-inside: | - resource "aws_eks_cluster" "..." {...} - - pattern-not-inside: | - resource "aws_eks_cluster" "..."{ - ... - vpc_config{ - ... - endpoint_public_access = false - ... - } - ... - } - severity: WARNING - - id: terraform.lang.security.elastic-search-encryption-at-rest.elastic-search-encryption-at-rest - languages: - - hcl - message: Encryption at rest is not enabled for the elastic search domain resource - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: LOW - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: | - resource - - pattern-not-inside: | - resource "aws_elasticsearch_domain" "..."{ - ... - encrypt_at_rest{ - ... - enabled = true - ... - } - ... - } - - pattern-inside: | - resource "aws_elasticsearch_domain" "..." {...} - severity: WARNING - - id: terraform.lang.security.iam.no-iam-admin-privileges.no-iam-admin-privileges - languages: - - hcl - message: IAM policies that allow full "*-*" admin privileges violates the principle of least privilege. This allows an attacker to take full control over all AWS account resources. Instead, give each user more fine-grained control with only the privileges they need. $TYPE - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-269: Improper Privilege Management' - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://github.com/bridgecrewio/checkov/blob/master/checkov/terraform/checks/data/aws/AdminPolicyDocument.py - subcategory: - - audit - technology: - - terraform - - aws - pattern-either: - - patterns: - - pattern-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ... - ] - ... - }) - ... - } - - pattern-not-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ..., - {... Effect = "Deny" ...}, - ... - ] - ... - }) - ... - } - - patterns: - - pattern: | - {..., Action = "*", ...} - - pattern: | - {..., Resource = "*", ...} - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: | - "aws_iam_role_policy" - - pattern: | - "aws_iam_policy" - - pattern: | - "aws_iam_user_policy" - - pattern: | - "aws_iam_group_policy" - - patterns: - - pattern-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - } - ... - } - - pattern-not-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - effect = "Deny" - ... - } - ... - } - - patterns: - - pattern: | - {..., resources = ["*"], ...} - - pattern: | - {..., actions = ["*"], ...} - severity: WARNING - - id: terraform.lang.security.iam.no-iam-creds-exposure.no-iam-creds-exposure - languages: - - hcl - message: Ensure IAM policies don't allow credentials exposure. Credentials exposure actions return credentials as part of the API response, and can possibly lead to leaking important credentials. Instead, use another action that doesn't return sensitive data as part of the API response. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://cloudsplaining.readthedocs.io/en/latest/glossary/credentials-exposure/ - - https://github.com/bridgecrewio/checkov/blob/ca830e14745c2c8e1b941985f305abe985d7f1f9/checkov/terraform/checks/data/aws/IAMCredentialsExposure.py - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ... - ] - ... - }) - ... - } - - pattern-not-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ..., - {... Effect = "Deny" ...}, - ... - ] - ... - }) - ... - } - - pattern: | - Action = $ACTION - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: | - "aws_iam_role_policy" - - pattern: | - "aws_iam_policy" - - pattern: | - "aws_iam_user_policy" - - pattern: | - "aws_iam_group_policy" - - patterns: - - pattern-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - } - ... - } - - pattern-not-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - effect = "Deny" - ... - } - ... - } - - pattern: | - actions = [..., $ACTION, ...] - - metavariable-pattern: - metavariable: $ACTION - pattern-either: - - pattern: | - "chime:CreateApiKey" - - pattern: | - "codepipeline:PollForJobs" - - pattern: | - "cognito-identity:GetOpenIdToken" - - pattern: | - "cognito-identity:GetOpenIdTokenForDeveloperEdentity" - - pattern: | - "cognito-identity:GetCredentialsForIdentity" - - pattern: | - "connect:GetFederationToken" - - pattern: | - "connect:GetFederationTokens" - - pattern: | - "ec2:GetPasswordData" - - pattern: | - "ecr:GetAuthorizationToken" - - pattern: | - "gamelift:RequestUploadCredentials" - - pattern: | - "iam:CreateAccessKey" - - pattern: | - "iam:CreateLoginProfile" - - pattern: | - "iam:CreateServiceSpecificCredential" - - pattern: | - "iam:ResetServiceSpecificCredential" - - pattern: | - "iam:UpdateAccessKey" - - pattern: | - "lightsail:GetInstanceAccessDetails" - - pattern: | - "lightsail:GetRelationalDatabaseMasterUserPassword" - - pattern: | - "rds-db:Connect" - - pattern: | - "redshift:GetClusterCredentials" - - pattern: | - "sso:GetRoleCredentials" - - pattern: | - "mediapackage:RotateChannelCredentials" - - pattern: | - "mediapackage:RotateIngestEndpointCredentials" - - pattern: | - "sts:AssumeRole" - - pattern: | - "sts:AssumeRoleWithSaml" - - pattern: | - "sts:AssumeRoleWithWebIdentity" - - pattern: | - "sts:GetFederationToken" - - pattern: | - "sts:GetSessionToken" - - pattern: | - "ec2:*" - - pattern: | - "codepipeline:*" - - pattern: | - "rds-db:*" - - pattern: | - "connect:*" - - pattern: | - "iam:*" - - pattern: | - "ecr:*" - - pattern: | - "sts:*" - - pattern: | - "chime:*" - - pattern: | - "mediapackage:*" - - pattern: | - "redshift:*" - - pattern: | - "gamelift:*" - - pattern: | - "cognito-identity:*" - - pattern: | - "lightsail:*" - - pattern: | - "sso:*" - severity: WARNING - - id: terraform.lang.security.iam.no-iam-data-exfiltration.no-iam-data-exfiltration - languages: - - hcl - message: Ensure that IAM policies don't allow data exfiltration actions that are not resource-constrained. This can allow the user to read sensitive data they don't need to read. Instead, make sure that the user granted these privileges are given these permissions on specific resources. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://github.com/bridgecrewio/checkov/blob/ca830e14745c2c8e1b941985f305abe985d7f1f9/checkov/terraform/checks/data/aws/IAMDataExfiltration.py - - https://cloudsplaining.readthedocs.io/en/latest/glossary/data-exfiltration/ - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ..., - {... Resource = "*" ...}, - ... - ] - ... - }) - ... - } - - pattern-not-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ..., - {... Effect = "Deny" ...}, - ... - ] - ... - }) - ... - } - - pattern: | - Action = $ACTION - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: | - "aws_iam_role_policy" - - pattern: | - "aws_iam_policy" - - pattern: | - "aws_iam_user_policy" - - pattern: | - "aws_iam_group_policy" - - patterns: - - pattern-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - resources = ["*"] - ... - } - ... - } - - pattern-not-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - effect = "Deny" - ... - } - ... - } - - pattern: | - actions = [..., $ACTION, ...] - - metavariable-pattern: - metavariable: $ACTION - pattern-either: - - pattern: | - "s3:GetObject" - - pattern: | - "ssm:GetParameter*" - - pattern: | - "secretsmanager:GetSecretValue" - - pattern: | - "rds:CopyDBSnapshot" - - pattern: | - "rds:CreateDBSnapshot" - - pattern: | - "ssm:*" - - pattern: | - "s3:*" - - pattern: | - "rds:*" - - pattern: | - "rn: secretsmanager:*" - severity: WARNING - - id: terraform.lang.security.iam.no-iam-priv-esc-funcs.no-iam-priv-esc-funcs - languages: - - hcl - message: Ensure that actions that can result in privilege escalation are not used. These actions could potentially result in an attacker gaining full administrator access of an AWS account. Try not to use these actions. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - references: - - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/ - - https://cloudsplaining.readthedocs.io/en/latest/glossary/privilege-escalation/ - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ... - ] - ... - }) - ... - } - - pattern-not-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ..., - {... Effect = "Deny" ...}, - ... - ] - ... - }) - ... - } - - pattern: Action = $ACTION - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: | - "aws_iam_role_policy" - - pattern: | - "aws_iam_policy" - - pattern: | - "aws_iam_user_policy" - - pattern: | - "aws_iam_group_policy" - - patterns: - - pattern-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - } - ... - } - - pattern-not-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - effect = "Deny" - ... - } - ... - } - - pattern: | - actions = [..., $ACTION, ...] - - metavariable-pattern: - metavariable: $ACTION - pattern-either: - - pattern: | - "iam:AddUserToGroup" - - pattern: | - "iam:CreatePolicyVersion" - - pattern: | - "iam:SetDefaultPolicyVersion" - - pattern: | - "iam:AttachUserPolicy" - - pattern: | - "iam:AttachGroupPolicy" - - pattern: | - "iam:AttachRolePolicy" - - pattern: | - "iam:PutUserPolicy" - - pattern: | - "iam:PutGroupPolicy" - - pattern: | - "iam:PutRolePolicy" - - pattern: | - "glue:UpdateDevEndpoint" - - pattern: | - "iam:*" - - pattern: | - "glue:*" - severity: WARNING - - id: terraform.lang.security.iam.no-iam-priv-esc-other-users.no-iam-priv-esc-other-users - languages: - - hcl - message: Ensure that IAM policies with permissions on other users don't allow for privilege escalation. This can lead to an attacker gaining full administrator access of AWS accounts. Instead, specify which user the permission should be used on or do not use the listed actions. $RESOURCE - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-269: Improper Privilege Management' - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://cloudsplaining.readthedocs.io/en/latest/glossary/privilege-escalation/ - - https://github.com/bridgecrewio/checkov/blob/ca830e14745c2c8e1b941985f305abe985d7f1f9/checkov/terraform/checks/data/aws/IAMPrivilegeEscalation.py - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ..., - {... Resource = $RESOURCE ...}, - ... - ] - ... - }) - ... - } - - pattern-not-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ..., - {... Effect = "Deny" ...}, - ... - ] - ... - }) - ... - } - - pattern: | - Action = $ACTION - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: | - "aws_iam_role_policy" - - pattern: | - "aws_iam_policy" - - pattern: | - "aws_iam_user_policy" - - pattern: | - "aws_iam_group_policy" - - patterns: - - pattern-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - resources = $RESOURCE - ... - } - ... - } - - pattern-not-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - effect = "Deny" - ... - } - ... - } - - pattern: | - actions = [..., $ACTION, ...] - - metavariable-pattern: - metavariable: $RESOURCE - pattern-either: - - pattern-regex: .*\*.* - - metavariable-pattern: - metavariable: $ACTION - pattern-either: - - pattern: | - "iam:CreateAccessKey" - - pattern: | - "iam:CreateLoginProfile" - - pattern: | - "iam:UpdateLoginProfile" - - pattern: | - "iam:*" - severity: WARNING - - id: terraform.lang.security.iam.no-iam-priv-esc-roles.no-iam-priv-esc-roles - languages: - - hcl - message: Ensure that groups of actions that include iam:PassRole and could result in privilege escalation are not all allowed for the same user. These actions could result in an attacker gaining full admin access of an AWS account. Try not to use these actions in conjuction. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-269: Improper Privilege Management' - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://cloudsplaining.readthedocs.io/en/latest/glossary/privilege-escalation/ - - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/ - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ... - ] - ... - }) - ... - } - - pattern-not-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ..., - {... Effect = "Deny" ...}, - ... - ] - ... - }) - ... - } - - pattern: | - Action = $ACTION - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: | - "aws_iam_role_policy" - - pattern: | - "aws_iam_policy" - - pattern: | - "aws_iam_user_policy" - - pattern: | - "aws_iam_group_policy" - - patterns: - - pattern-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - } - ... - } - - pattern-not-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - effect = "Deny" - ... - } - ... - } - - pattern: | - actions = $ACTION - - metavariable-pattern: - metavariable: $ACTION - pattern-either: - - patterns: - - pattern: | - [..., "sts:AssumeRole", ...] - - pattern: | - [..., "iam:UpdateAssumeRolePolicy", ...] - - patterns: - - pattern: | - [..., "iam:PassRole", ...] - - pattern: | - [..., "lambda:CreateFunction", ...] - - pattern: | - [..., "lambda:InvokeFunction", ...] - - patterns: - - pattern: | - [..., "iam:PassRole", ...] - - pattern: | - [..., "lambda:CreateFunction", ...] - - pattern: | - [..., "lambda:CreateEventSourceMapping", ...] - - pattern: | - "lambda:UpdateFunctionCode" - - patterns: - - pattern: | - [..., "iam:PassRole", ...] - - pattern: | - [..., "glue:CreateDevEndpoint", ...] - - patterns: - - pattern: | - [..., "iam:PassRole", ...] - - pattern: | - [..., "cloudformation:CreateStack", ...] - - patterns: - - pattern: | - [..., "iam:PassRole", ...] - - pattern: | - [..., "datapipeline:CreatePipeline", ...] - - pattern: | - [..., "datapipeline:PutPipelineDefinition", ...] - severity: WARNING - - id: terraform.lang.security.iam.no-iam-resource-exposure.no-iam-resource-exposure - languages: - - hcl - message: Ensure IAM policies don't allow resource exposure. These actions can expose AWS resources to the public. For example `ecr:SetRepositoryPolicy` could let an attacker retrieve container images. Instead, use another action that doesn't expose AWS resources. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://cloudsplaining.readthedocs.io/en/latest/glossary/resource-exposure/ - - https://github.com/bridgecrewio/checkov/blob/ca830e14745c2c8e1b941985f305abe985d7f1f9/checkov/terraform/checks/data/aws/IAMPermissionsManagement.py - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ... - ] - ... - }) - ... - } - - pattern-not-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ..., - {... Effect = "Deny" ...}, - ... - ] - ... - }) - ... - } - - pattern: | - Action = $ACTION - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: | - "aws_iam_role_policy" - - pattern: | - "aws_iam_policy" - - pattern: | - "aws_iam_user_policy" - - pattern: | - "aws_iam_group_policy" - - patterns: - - pattern-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - } - ... - } - - pattern-not-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - effect = "Deny" - ... - } - ... - } - - pattern: | - actions = [..., $ACTION, ...] - - metavariable-pattern: - metavariable: $ACTION - pattern-either: - - pattern: | - "acm-pca:CreatePermission" - - pattern: | - "acm-pca:DeletePermission" - - pattern: | - "acm-pca:DeletePolicy" - - pattern: | - "acm-pca:PutPolicy" - - pattern: | - "apigateway:UpdateRestApiPolicy" - - pattern: | - "backup:DeleteBackupVaultAccessPolicy" - - pattern: | - "backup:PutBackupVaultAccessPolicy" - - pattern: | - "chime:DeleteVoiceConnectorTerminationCredentials" - - pattern: | - "chime:PutVoiceConnectorTerminationCredentials" - - pattern: | - "cloudformation:SetStackPolicy" - - pattern: | - "cloudsearch:UpdateServiceAccessPolicies" - - pattern: | - "codeartifact:DeleteDomainPermissionsPolicy" - - pattern: | - "codeartifact:DeleteRepositoryPermissionsPolicy" - - pattern: | - "codebuild:DeleteResourcePolicy" - - pattern: | - "codebuild:DeleteSourceCredentials" - - pattern: | - "codebuild:ImportSourceCredentials" - - pattern: | - "codebuild:PutResourcePolicy" - - pattern: | - "codeguru-profiler:PutPermission" - - pattern: | - "codeguru-profiler:RemovePermission" - - pattern: | - "codestar:AssociateTeamMember" - - pattern: | - "codestar:CreateProject" - - pattern: | - "codestar:DeleteProject" - - pattern: | - "codestar:DisassociateTeamMember" - - pattern: | - "codestar:UpdateTeamMember" - - pattern: | - "cognito-identity:CreateIdentityPool" - - pattern: | - "cognito-identity:DeleteIdentities" - - pattern: | - "cognito-identity:DeleteIdentityPool" - - pattern: | - "cognito-identity:GetId" - - pattern: | - "cognito-identity:MergeDeveloperIdentities" - - pattern: | - "cognito-identity:SetIdentityPoolRoles" - - pattern: | - "cognito-identity:UnlinkDeveloperIdentity" - - pattern: | - "cognito-identity:UnlinkIdentity" - - pattern: | - "cognito-identity:UpdateIdentityPool" - - pattern: | - "deeplens:AssociateServiceRoleToAccount" - - pattern: | - "ds:CreateConditionalForwarder" - - pattern: | - "ds:CreateDirectory" - - pattern: | - "ds:CreateMicrosoftAD" - - pattern: | - "ds:CreateTrust" - - pattern: | - "ds:ShareDirectory" - - pattern: | - "ec2:CreateNetworkInterfacePermission" - - pattern: | - "ec2:DeleteNetworkInterfacePermission" - - pattern: | - "ec2:ModifySnapshotAttribute" - - pattern: | - "ec2:ModifyVpcEndpointServicePermissions" - - pattern: | - "ec2:ResetSnapshotAttribute" - - pattern: | - "ecr:DeleteRepositoryPolicy" - - pattern: | - "ecr:SetRepositoryPolicy" - - pattern: | - "elasticfilesystem:DeleteFileSystemPolicy" - - pattern: | - "elasticfilesystem:PutFileSystemPolicy" - - pattern: | - "elasticmapreduce:PutBlockPublicAccessConfiguration" - - pattern: | - "es:CreateElasticsearchDomain" - - pattern: | - "es:UpdateElasticsearchDomainConfig" - - pattern: | - "glacier:AbortVaultLock" - - pattern: | - "glacier:CompleteVaultLock" - - pattern: | - "glacier:DeleteVaultAccessPolicy" - - pattern: | - "glacier:InitiateVaultLock" - - pattern: | - "glacier:SetDataRetrievalPolicy" - - pattern: | - "glacier:SetVaultAccessPolicy" - - pattern: | - "glue:DeleteResourcePolicy" - - pattern: | - "glue:PutResourcePolicy" - - pattern: | - "greengrass:AssociateServiceRoleToAccount" - - pattern: | - "health:DisableHealthServiceAccessForOrganization" - - pattern: | - "health:EnableHealthServiceAccessForOrganization" - - pattern: | - "iam:AddClientIDToOpenIDConnectProvider" - - pattern: | - "iam:AddRoleToInstanceProfile" - - pattern: | - "iam:AddUserToGroup" - - pattern: | - "iam:AttachGroupPolicy" - - pattern: | - "iam:AttachRolePolicy" - - pattern: | - "iam:AttachUserPolicy" - - pattern: | - "iam:ChangePassword" - - pattern: | - "iam:CreateAccessKey" - - pattern: | - "iam:CreateAccountAlias" - - pattern: | - "iam:CreateGroup" - - pattern: | - "iam:CreateInstanceProfile" - - pattern: | - "iam:CreateLoginProfile" - - pattern: | - "iam:CreateOpenIDConnectProvider" - - pattern: | - "iam:CreatePolicy" - - pattern: | - "iam:CreatePolicyVersion" - - pattern: | - "iam:CreateRole" - - pattern: | - "iam:CreateSAMLProvider" - - pattern: | - "iam:CreateServiceLinkedRole" - - pattern: | - "iam:CreateServiceSpecificCredential" - - pattern: | - "iam:CreateUser" - - pattern: | - "iam:CreateVirtualMFADevice" - - pattern: | - "iam:DeactivateMFADevice" - - pattern: | - "iam:DeleteAccessKey" - - pattern: | - "iam:DeleteAccountAlias" - - pattern: | - "iam:DeleteAccountPasswordPolicy" - - pattern: | - "iam:DeleteGroup" - - pattern: | - "iam:DeleteGroupPolicy" - - pattern: | - "iam:DeleteInstanceProfile" - - pattern: | - "iam:DeleteLoginProfile" - - pattern: | - "iam:DeleteOpenIDConnectProvider" - - pattern: | - "iam:DeletePolicy" - - pattern: | - "iam:DeletePolicyVersion" - - pattern: | - "iam:DeleteRole" - - pattern: | - "iam:DeleteRolePermissionsBoundary" - - pattern: | - "iam:DeleteRolePolicy" - - pattern: | - "iam:DeleteSAMLProvider" - - pattern: | - "iam:DeleteSSHPublicKey" - - pattern: | - "iam:DeleteServerCertificate" - - pattern: | - "iam:DeleteServiceLinkedRole" - - pattern: | - "iam:DeleteServiceSpecificCredential" - - pattern: | - "iam:DeleteSigningCertificate" - - pattern: | - "iam:DeleteUser" - - pattern: | - "iam:DeleteUserPermissionsBoundary" - - pattern: | - "iam:DeleteUserPolicy" - - pattern: | - "iam:DeleteVirtualMFADevice" - - pattern: | - "iam:DetachGroupPolicy" - - pattern: | - "iam:DetachRolePolicy" - - pattern: | - "iam:DetachUserPolicy" - - pattern: | - "iam:EnableMFADevice" - - pattern: | - "iam:PassRole" - - pattern: | - "iam:PutGroupPolicy" - - pattern: | - "iam:PutRolePermissionsBoundary" - - pattern: | - "iam:PutRolePolicy" - - pattern: | - "iam:PutUserPermissionsBoundary" - - pattern: | - "iam:PutUserPolicy" - - pattern: | - "iam:RemoveClientIDFromOpenIDConnectProvider" - - pattern: | - "iam:RemoveRoleFromInstanceProfile" - - pattern: | - "iam:RemoveUserFromGroup" - - pattern: | - "iam:ResetServiceSpecificCredential" - - pattern: | - "iam:ResyncMFADevice" - - pattern: | - "iam:SetDefaultPolicyVersion" - - pattern: | - "iam:SetSecurityTokenServicePreferences" - - pattern: | - "iam:UpdateAccessKey" - - pattern: | - "iam:UpdateAccountPasswordPolicy" - - pattern: | - "iam:UpdateAssumeRolePolicy" - - pattern: | - "iam:UpdateGroup" - - pattern: | - "iam:UpdateLoginProfile" - - pattern: | - "iam:UpdateOpenIDConnectProviderThumbprint" - - pattern: | - "iam:UpdateRole" - - pattern: | - "iam:UpdateRoleDescription" - - pattern: | - "iam:UpdateSAMLProvider" - - pattern: | - "iam:UpdateSSHPublicKey" - - pattern: | - "iam:UpdateServerCertificate" - - pattern: | - "iam:UpdateServiceSpecificCredential" - - pattern: | - "iam:UpdateSigningCertificate" - - pattern: | - "iam:UpdateUser" - - pattern: | - "iam:UploadSSHPublicKey" - - pattern: | - "iam:UploadServerCertificate" - - pattern: | - "iam:UploadSigningCertificate" - - pattern: | - "imagebuilder:PutComponentPolicy" - - pattern: | - "imagebuilder:PutImagePolicy" - - pattern: | - "imagebuilder:PutImageRecipePolicy" - - pattern: | - "iot:AttachPolicy" - - pattern: | - "iot:AttachPrincipalPolicy" - - pattern: | - "iot:DetachPolicy" - - pattern: | - "iot:DetachPrincipalPolicy" - - pattern: | - "iot:SetDefaultAuthorizer" - - pattern: | - "iot:SetDefaultPolicyVersion" - - pattern: | - "iotsitewise:CreateAccessPolicy" - - pattern: | - "iotsitewise:DeleteAccessPolicy" - - pattern: | - "iotsitewise:UpdateAccessPolicy" - - pattern: | - "kms:CreateGrant" - - pattern: | - "kms:PutKeyPolicy" - - pattern: | - "kms:RetireGrant" - - pattern: | - "kms:RevokeGrant" - - pattern: | - "lakeformation:BatchGrantPermissions" - - pattern: | - "lakeformation:BatchRevokePermissions" - - pattern: | - "lakeformation:GrantPermissions" - - pattern: | - "lakeformation:PutDataLakeSettings" - - pattern: | - "lakeformation:RevokePermissions" - - pattern: | - "lambda:AddLayerVersionPermission" - - pattern: | - "lambda:AddPermission" - - pattern: | - "lambda:DisableReplication" - - pattern: | - "lambda:EnableReplication" - - pattern: | - "lambda:RemoveLayerVersionPermission" - - pattern: | - "lambda:RemovePermission" - - pattern: | - "license-manager:UpdateServiceSettings" - - pattern: | - "lightsail:GetRelationalDatabaseMasterUserPassword" - - pattern: | - "logs:DeleteResourcePolicy" - - pattern: | - "logs:PutResourcePolicy" - - pattern: | - "mediapackage:RotateIngestEndpointCredentials" - - pattern: | - "mediastore:DeleteContainerPolicy" - - pattern: | - "mediastore:PutContainerPolicy" - - pattern: | - "opsworks:SetPermission" - - pattern: | - "opsworks:UpdateUserProfile" - - pattern: | - "quicksight:CreateAdmin" - - pattern: | - "quicksight:CreateGroup" - - pattern: | - "quicksight:CreateGroupMembership" - - pattern: | - "quicksight:CreateIAMPolicyAssignment" - - pattern: | - "quicksight:CreateUser" - - pattern: | - "quicksight:DeleteGroup" - - pattern: | - "quicksight:DeleteGroupMembership" - - pattern: | - "quicksight:DeleteIAMPolicyAssignment" - - pattern: | - "quicksight:DeleteUser" - - pattern: | - "quicksight:DeleteUserByPrincipalId" - - pattern: | - "quicksight:RegisterUser" - - pattern: | - "quicksight:UpdateDashboardPermissions" - - pattern: | - "quicksight:UpdateGroup" - - pattern: | - "quicksight:UpdateIAMPolicyAssignment" - - pattern: | - "quicksight:UpdateTemplatePermissions" - - pattern: | - "quicksight:UpdateUser" - - pattern: | - "ram:AcceptResourceShareInvitation" - - pattern: | - "ram:AssociateResourceShare" - - pattern: | - "ram:CreateResourceShare" - - pattern: | - "ram:DeleteResourceShare" - - pattern: | - "ram:DisassociateResourceShare" - - pattern: | - "ram:EnableSharingWithAwsOrganization" - - pattern: | - "ram:RejectResourceShareInvitation" - - pattern: | - "ram:UpdateResourceShare" - - pattern: | - "rds:AuthorizeDBSecurityGroupIngress" - - pattern: | - "rds-db:connect" - - pattern: | - "redshift:AuthorizeSnapshotAccess" - - pattern: | - "redshift:CreateClusterUser" - - pattern: | - "redshift:CreateSnapshotCopyGrant" - - pattern: | - "redshift:JoinGroup" - - pattern: | - "redshift:ModifyClusterIamRoles" - - pattern: | - "redshift:RevokeSnapshotAccess" - - pattern: | - "route53resolver:PutResolverRulePolicy" - - pattern: | - "s3:BypassGovernanceRetention" - - pattern: | - "s3:DeleteAccessPointPolicy" - - pattern: | - "s3:DeleteBucketPolicy" - - pattern: | - "s3:ObjectOwnerOverrideToBucketOwner" - - pattern: | - "s3:PutAccessPointPolicy" - - pattern: | - "s3:PutAccountPublicAccessBlock" - - pattern: | - "s3:PutBucketAcl" - - pattern: | - "s3:PutBucketPolicy" - - pattern: | - "s3:PutBucketPublicAccessBlock" - - pattern: | - "s3:PutObjectAcl" - - pattern: | - "s3:PutObjectVersionAcl" - - pattern: | - "secretsmanager:DeleteResourcePolicy" - - pattern: | - "secretsmanager:PutResourcePolicy" - - pattern: | - "secretsmanager:ValidateResourcePolicy" - - pattern: | - "servicecatalog:CreatePortfolioShare" - - pattern: | - "servicecatalog:DeletePortfolioShare" - - pattern: | - "sns:AddPermission" - - pattern: | - "sns:CreateTopic" - - pattern: | - "sns:RemovePermission" - - pattern: | - "sns:SetTopicAttributes" - - pattern: | - "sqs:AddPermission" - - pattern: | - "sqs:CreateQueue" - - pattern: | - "sqs:RemovePermission" - - pattern: | - "sqs:SetQueueAttributes" - - pattern: | - "ssm:ModifyDocumentPermission" - - pattern: | - "sso:AssociateDirectory" - - pattern: | - "sso:AssociateProfile" - - pattern: | - "sso:CreateApplicationInstance" - - pattern: | - "sso:CreateApplicationInstanceCertificate" - - pattern: | - "sso:CreatePermissionSet" - - pattern: | - "sso:CreateProfile" - - pattern: | - "sso:CreateTrust" - - pattern: | - "sso:DeleteApplicationInstance" - - pattern: | - "sso:DeleteApplicationInstanceCertificate" - - pattern: | - "sso:DeletePermissionSet" - - pattern: | - "sso:DeletePermissionsPolicy" - - pattern: | - "sso:DeleteProfile" - - pattern: | - "sso:DisassociateDirectory" - - pattern: | - "sso:DisassociateProfile" - - pattern: | - "sso:ImportApplicationInstanceServiceProviderMetadata" - - pattern: | - "sso:PutPermissionsPolicy" - - pattern: | - "sso:StartSSO" - - pattern: | - "sso:UpdateApplicationInstanceActiveCertificate" - - pattern: | - "sso:UpdateApplicationInstanceDisplayData" - - pattern: | - "sso:UpdateApplicationInstanceResponseConfiguration" - - pattern: | - "sso:UpdateApplicationInstanceResponseSchemaConfiguration" - - pattern: | - "sso:UpdateApplicationInstanceSecurityConfiguration" - - pattern: | - "sso:UpdateApplicationInstanceServiceProviderConfiguration" - - pattern: | - "sso:UpdateApplicationInstanceStatus" - - pattern: | - "sso:UpdateDirectoryAssociation" - - pattern: | - "sso:UpdatePermissionSet" - - pattern: | - "sso:UpdateProfile" - - pattern: | - "sso:UpdateSSOConfiguration" - - pattern: | - "sso:UpdateTrust" - - pattern: | - "sso-directory:AddMemberToGroup" - - pattern: | - "sso-directory:CreateAlias" - - pattern: | - "sso-directory:CreateGroup" - - pattern: | - "sso-directory:CreateUser" - - pattern: | - "sso-directory:DeleteGroup" - - pattern: | - "sso-directory:DeleteUser" - - pattern: | - "sso-directory:DisableUser" - - pattern: | - "sso-directory:EnableUser" - - pattern: | - "sso-directory:RemoveMemberFromGroup" - - pattern: | - "sso-directory:UpdateGroup" - - pattern: | - "sso-directory:UpdatePassword" - - pattern: | - "sso-directory:UpdateUser" - - pattern: | - "sso-directory:VerifyEmail" - - pattern: | - "storagegateway:DeleteChapCredentials" - - pattern: | - "storagegateway:SetLocalConsolePassword" - - pattern: | - "storagegateway:SetSMBGuestPassword" - - pattern: | - "storagegateway:UpdateChapCredentials" - - pattern: | - "waf:DeletePermissionPolicy" - - pattern: | - "waf:PutPermissionPolicy" - - pattern: | - "waf-regional:DeletePermissionPolicy" - - pattern: | - "waf-regional:PutPermissionPolicy" - - pattern: | - "wafv2:CreateWebACL" - - pattern: | - "wafv2:DeletePermissionPolicy" - - pattern: | - "wafv2:DeleteWebACL" - - pattern: | - "wafv2:PutPermissionPolicy" - - pattern: | - "wafv2:UpdateWebACL" - - pattern: | - "worklink:UpdateDevicePolicyConfiguration" - - pattern: | - "workmail:ResetPassword" - - pattern: | - "workmail:ResetUserPassword" - - pattern: | - "xray:PutEncryptionConfig" - - pattern: | - "worklink:*" - - pattern: | - "route53resolver:*" - - pattern: | - "es:*" - - pattern: | - "greengrass:*" - - pattern: | - "redshift:*" - - pattern: | - "license-manager:*" - - pattern: | - "rds:*" - - pattern: | - "lambda:*" - - pattern: | - "elasticfilesystem:*" - - pattern: | - "logs:*" - - pattern: | - "sso:*" - - pattern: | - "waf:*" - - pattern: | - "mediastore:*" - - pattern: | - "acm-pca:*" - - pattern: | - "sso-directory:*" - - pattern: | - "imagebuilder:*" - - pattern: | - "sqs:*" - - pattern: | - "codeguru-profiler:*" - - pattern: | - "wafv2:*" - - pattern: | - "cloudformation:*" - - pattern: | - "xray:*" - - pattern: | - "codeartifact:*" - - pattern: | - "iotsitewise:*" - - pattern: | - "workmail:*" - - pattern: | - "glue:*" - - pattern: | - "deeplens:*" - - pattern: | - "chime:*" - - pattern: | - "mediapackage:*" - - pattern: | - "opsworks:*" - - pattern: | - "ds:*" - - pattern: | - "ram:*" - - pattern: | - "iam:*" - - pattern: | - "waf-regional:*" - - pattern: | - "glacier:*" - - pattern: | - "cloudsearch:*" - - pattern: | - "lakeformation:*" - - pattern: | - "elasticmapreduce:*" - - pattern: | - "quicksight:*" - - pattern: | - "sns:*" - - pattern: | - "ec2:*" - - pattern: | - "health:*" - - pattern: | - "lightsail:*" - - pattern: | - "codestar:*" - - pattern: | - "kms:*" - - pattern: | - "codebuild:*" - - pattern: | - "s3:*" - - pattern: | - "cognito-identity:*" - - pattern: | - "apigateway:*" - - pattern: | - "rds-db:*" - - pattern: | - "iot:*" - - pattern: | - "backup:*" - - pattern: | - "secretsmanager:*" - - pattern: | - "servicecatalog:*" - - pattern: | - "ssm:*" - - pattern: | - "storagegateway:*" - - pattern: | - "ecr:*" - severity: WARNING - - id: terraform.lang.security.iam.no-iam-star-actions.no-iam-star-actions - languages: - - hcl - message: Ensure that no IAM policies allow "*" as a statement's actions. This allows all actions to be performed on the specified resources, and is a violation of the principle of least privilege. Instead, specify the actions that a certain user or policy is allowed to take. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-269: Improper Privilege Management' - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy - - https://github.com/bridgecrewio/checkov/blob/ca830e14745c2c8e1b941985f305abe985d7f1f9/checkov/terraform/checks/data/aws/StarActionPolicyDocument.py - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ... - ] - ... - }) - ... - } - - pattern-not-inside: | - resource $TYPE "..." { - ... - policy = jsonencode({ - ... - Statement = [ - ..., - {... Effect = "Deny" ...}, - ... - ] - ... - }) - ... - } - - pattern-either: - - pattern: Action = "*" - - pattern: Action = ["*"] - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: | - "aws_iam_role_policy" - - pattern: | - "aws_iam_policy" - - pattern: | - "aws_iam_user_policy" - - pattern: | - "aws_iam_group_policy" - - patterns: - - pattern-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - } - ... - } - - pattern-not-inside: | - data aws_iam_policy_document "..." { - ... - statement { - ... - effect = "Deny" - ... - } - ... - } - - pattern: | - actions = ["*"] - severity: WARNING - - id: terraform.lang.security.rds-insecure-password-storage-in-source-code.rds-insecure-password-storage-in-source-code - languages: - - hcl - message: RDS instance or cluster with hardcoded credentials in source code. It is recommended to pass the credentials at runtime, or generate random credentials using the random_password resource. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-522: Insufficiently Protected Credentials' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A02:2017 - Broken Authentication - - A04:2021 - Insecure Design - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#master_password - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster#master_password - - https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password - subcategory: - - vuln - technology: - - terraform - - aws - pattern-either: - - patterns: - - pattern: password = "..." - - pattern-inside: | - resource "aws_db_instance" "..." { - ... - } - - patterns: - - pattern: master_password = "..." - - pattern-inside: | - resource "aws_rds_cluster" "..." { - ... - } - severity: WARNING - - id: terraform.lang.security.rds-public-access.rds-public-access - languages: - - hcl - message: RDS instance accessible from the Internet detected. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: LOW - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#publicly_accessible - - https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html#USER_VPC.Hiding - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern: publicly_accessible = true - - pattern-inside: | - resource "aws_db_instance" "..." { - ... - } - severity: WARNING - - id: terraform.lang.security.s3-cors-all-origins.all-origins-allowed - languages: - - hcl - message: CORS rule on bucket permits any origin - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-942: Permissive Cross-domain Policy with Untrusted Domains' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#using-cors - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-inside: cors_rule { ... } - - pattern: allowed_origins = ["*"] - severity: WARNING - - id: terraform.lang.security.s3-public-read-bucket.s3-public-read-bucket - languages: - - hcl - message: S3 bucket with public read access detected. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#acl - - https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl - subcategory: - - audit - technology: - - terraform - - aws - patterns: - - pattern-either: - - pattern: acl = "public-read" - - pattern: acl = "authenticated-read" - - pattern-not-inside: | - resource "aws_s3_bucket" "..." { - ... - website { ... } - ... - } - severity: WARNING - - id: terraform.lang.security.s3-public-rw-bucket.s3-public-rw-bucket - languages: - - hcl - message: S3 bucket with public read-write access detected. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' - cwe2021-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#acl - - https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl - subcategory: - - vuln - technology: - - terraform - - aws - pattern: acl = "public-read-write" - severity: ERROR - - id: terraform.lang.security.s3-unencrypted-bucket.s3-unencrypted-bucket - languages: - - hcl - message: This rule has been deprecated, as all s3 buckets are encrypted by default with no way to disable it. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration for more info. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - deprecated: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#server_side_encryption_configuration - - https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html - subcategory: - - vuln - technology: - - terraform - - aws - patterns: - - pattern: a - - pattern: b - severity: INFO - - id: typescript.angular.security.audit.angular-domsanitizer.angular-bypasssecuritytrust - languages: - - typescript - message: Detected the use of `$TRUST`. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. If you have to use `$TRUST`, ensure it does not come from user-input or use the appropriate prevention mechanism e.g. input validation or sanitization depending on the context. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://angular.io/api/platform-browser/DomSanitizer - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html - subcategory: - - vuln - technology: - - angular - - browser - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; - ... - - pattern-inside: | - $S = require("sanitize-html") - ... - - pattern: $S(...) - - patterns: - - pattern: sanitizer.sanitize(...) - - pattern-not: sanitizer.sanitize(SecurityContext.NONE, ...); - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $X.$TRUST($Y) - - focus-metavariable: $Y - - pattern-not: | - $X.$TRUST(`...`) - - pattern-not: | - $X.$TRUST("...") - - metavariable-regex: - metavariable: $TRUST - regex: (bypassSecurityTrustHtml|bypassSecurityTrustStyle|bypassSecurityTrustScript|bypassSecurityTrustUrl|bypassSecurityTrustResourceUrl) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - function ...({..., $X: string, ...}) { ... } - - pattern-inside: | - function ...(..., $X: string, ...) { ... } - - focus-metavariable: $X - severity: WARNING - - id: typescript.aws-cdk.security.audit.awscdk-bucket-encryption.awscdk-bucket-encryption - languages: - - typescript - message: 'Add "encryption: $Y.BucketEncryption.KMS_MANAGED" or "encryption: $Y.BucketEncryption.S3_MANAGED" to the bucket props for Bucket construct $X' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html - subcategory: - - vuln - technology: - - AWS-CDK - pattern-either: - - patterns: - - pattern-inside: | - import {Bucket} from '@aws-cdk/aws-s3' - ... - - pattern: const $X = new Bucket(...) - - pattern-not: | - const $X = new Bucket(..., {..., encryption: BucketEncryption.KMS_MANAGED, ...}) - - pattern-not: | - const $X = new Bucket(..., {..., encryption: BucketEncryption.KMS, ...}) - - pattern-not: | - const $X = new Bucket(..., {..., encryption: BucketEncryption.S3_MANAGED, ...}) - - patterns: - - pattern-inside: | - import * as $Y from '@aws-cdk/aws-s3' - ... - - pattern: const $X = new $Y.Bucket(...) - - pattern-not: | - const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.KMS_MANAGED, ...}) - - pattern-not: | - const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.KMS, ...}) - - pattern-not: | - const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.S3_MANAGED, ...}) - severity: ERROR - - id: typescript.aws-cdk.security.audit.awscdk-bucket-enforcessl.aws-cdk-bucket-enforcessl - languages: - - ts - message: Bucket $X is not set to enforce encryption-in-transit, if not explictly setting this on the bucket policy - the property "enforceSSL" should be set to true - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html - subcategory: - - vuln - technology: - - AWS-CDK - pattern-either: - - patterns: - - pattern-inside: | - import {Bucket} from '@aws-cdk/aws-s3'; - ... - - pattern: const $X = new Bucket(...) - - pattern-not: | - const $X = new Bucket(..., {enforceSSL: true}, ...) - - patterns: - - pattern-inside: | - import * as $Y from '@aws-cdk/aws-s3'; - ... - - pattern: const $X = new $Y.Bucket(...) - - pattern-not: | - const $X = new $Y.Bucket(..., {..., enforceSSL: true, ...}) - severity: ERROR - - id: typescript.aws-cdk.security.audit.awscdk-sqs-unencryptedqueue.awscdk-sqs-unencryptedqueue - languages: - - ts - message: 'Queue $X is missing encryption at rest. Add "encryption: $Y.QueueEncryption.KMS" or "encryption: $Y.QueueEncryption.KMS_MANAGED" to the queue props to enable encryption at rest for the queue.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-311: Missing Encryption of Sensitive Data' - impact: HIGH - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A04:2021 - Insecure Design - references: - - https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-data-protection.html - subcategory: - - vuln - technology: - - AWS-CDK - pattern-either: - - patterns: - - pattern-inside: | - import {Queue} from '@aws-cdk/aws-sqs' - ... - - pattern: const $X = new Queue(...) - - pattern-not: | - const $X = new Queue(..., {..., encryption: QueueEncryption.KMS_MANAGED, ...}) - - pattern-not: | - const $X = new Queue(..., {..., encryption: QueueEncryption.KMS, ...}) - - patterns: - - pattern-inside: | - import * as $Y from '@aws-cdk/aws-sqs' - ... - - pattern: const $X = new $Y.Queue(...) - - pattern-not: | - const $X = new $Y.Queue(..., {..., encryption: $Y.QueueEncryption.KMS_MANAGED, ...}) - - pattern-not: | - const $X = new $Y.Queue(..., {..., encryption: $Y.QueueEncryption.KMS, ...}) - severity: WARNING - - id: typescript.aws-cdk.security.awscdk-bucket-grantpublicaccessmethod.awscdk-bucket-grantpublicaccessmethod - languages: - - ts - message: Using the GrantPublicAccess method on bucket contruct $X will make the objects in the bucket world accessible. Verify if this is intentional. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-306: Missing Authentication for Critical Function' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: HIGH - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-overview.html - subcategory: - - vuln - technology: - - AWS-CDK - pattern-either: - - patterns: - - pattern-inside: | - import {Bucket} from '@aws-cdk/aws-s3' - ... - - pattern: | - const $X = new Bucket(...) - ... - $X.grantPublicAccess(...) - - patterns: - - pattern-inside: | - import * as $Y from '@aws-cdk/aws-s3' - ... - - pattern: | - const $X = new $Y.Bucket(...) - ... - $X.grantPublicAccess(...) - severity: WARNING - - id: typescript.aws-cdk.security.awscdk-codebuild-project-public.awscdk-codebuild-project-public - languages: - - ts - message: CodeBuild Project $X is set to have a public URL. This will make the build results, logs, artifacts publically accessible, including builds prior to the project being public. Ensure this is acceptable for the project. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-306: Missing Authentication for Critical Function' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://docs.aws.amazon.com/codebuild/latest/userguide/public-builds.html - subcategory: - - vuln - technology: - - AWS-CDK - pattern-either: - - patterns: - - pattern-inside: | - import {Project} from '@aws-cdk/aws-codebuild' - ... - - pattern: | - const $X = new Project(..., {..., badge: true, ...}) - - patterns: - - pattern-inside: | - import * as $Y from '@aws-cdk/aws-codebuild' - ... - - pattern: | - const $X = new $Y.Project(..., {..., badge: true, ...}) - severity: WARNING - - id: typescript.lang.best-practice.moment-deprecated.moment-deprecated - languages: - - typescript - - javascript - message: Moment is a legacy project in maintenance mode. Consider using libraries that are actively supported, e.g. `dayjs`. - metadata: - category: best-practice - references: - - https://momentjs.com/docs/#/-project-status/ - - https://day.js.org/ - technology: - - moment - - dayjs - pattern: | - import 'moment' - severity: INFO - - id: typescript.lang.correctness.useless-ternary.useless-ternary - languages: - - typescript - - javascript - message: It looks like no matter how $CONDITION is evaluated, this expression returns $ANS. This is probably a copy-paste error. - metadata: - category: correctness - technology: - - react - pattern: | - $CONDITION ? $ANS : $ANS - severity: ERROR - - id: typescript.lang.security.audit.cors-regex-wildcard.cors-regex-wildcard - languages: - - ts - message: 'Unescaped ''.'' character in CORS domain regex $CORS: $PATTERN' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-183: Permissive List of Allowed Inputs' - impact: LOW - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://owasp.org/Top10/A04_2021-Insecure_Design - subcategory: - - audit - technology: - - cors - patterns: - - pattern-either: - - pattern: $CORS = [...,/$PATTERN/,...] - - pattern: $CORS = /$PATTERN/ - - focus-metavariable: $PATTERN - - metavariable-regex: - metavariable: $PATTERN - regex: .+?(?} - - pattern: | - this.state = {$NAME: <... this.props.$PROP ...>} - - metavariable-regex: - metavariable: $NAME - regex: ^(?!default|initial).*$ - - patterns: - - pattern-either: - - pattern-inside: | - function $FN({$PROP},...) { - ... - } - - pattern-inside: | - function $FN($PROP,...) { - ... - } - - pattern-either: - - pattern: useState(<... $PROP ...>) - - pattern: useState(<... $PROP.$KEY ...>) - - pattern: | - useState(function $X(...) { - ... - <... $PROP ...> - ... - }) - - pattern: | - useState(function $X(...) { - ... - <... $PROP.$KEY ...> - ... - }) - - metavariable-regex: - metavariable: $PROP - regex: ^(?!default|initial).*$ - severity: WARNING - - id: typescript.react.best-practice.react-props-spreading.react-props-spreading - languages: - - typescript - - javascript - message: It's best practice to explicitly pass props to an HTML component rather than use the spread operator. The spread operator risks passing invalid HTML props to an HTML element, which can cause console warnings or worse, give malicious actors a way to inject unexpected attributes. - metadata: - category: best-practice - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - references: - - https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md - source-rule-url: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md - technology: - - react - patterns: - - pattern: <$X {...$PROPS} /> - - focus-metavariable: $PROPS - severity: WARNING - - id: typescript.react.portability.i18next.i18next-key-format.i18next-key-format - languages: - - typescript - - javascript - message: Translation key '$KEY' should match format 'MODULE.FEATURE.*' - metadata: - category: portability - references: - - https://www.notion.so/hendyirawan/Internationalization-Localization-Policy-318c21674e5f44c48d6f136a6eb2e024 - - https://mui.com/ - - https://react.i18next.com/ - technology: - - react - - mui - - i18next - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: t('$KEY') - - pattern: t('$KEY', $OPTIONS) - - pattern: t([$DYNAMIC_KEY, '$KEY']) - - pattern: t([$DYNAMIC_KEY, '$KEY'], $OPTIONS) - - metavariable-regex: - metavariable: $KEY - regex: (?!^[a-z0-9-]+\.[a-z0-9-]+\.[a-zA-Z0-9_.-]+$) - - patterns: - - pattern-either: - - pattern: t([$DYNAMIC_KEY, '$KEY']) - - pattern: t([$DYNAMIC_KEY, '$KEY'], $OPTIONS) - - metavariable-regex: - metavariable: $DYNAMIC_KEY - regex: (?!^[`][a-z0-9-]+[.][a-z0-9-]+[.]\S+$) - - patterns: - - pattern-either: - - pattern: $I18NEXT.t('$KEY') - - pattern: $I18NEXT.t('$KEY', $OPTIONS) - - pattern: $I18NEXT.t([$DYNAMIC_KEY, '$KEY']) - - pattern: $I18NEXT.t([$DYNAMIC_KEY, '$KEY'], $OPTIONS) - - metavariable-regex: - metavariable: $I18NEXT - regex: (^i18n|i18next$) - - metavariable-regex: - metavariable: $KEY - regex: (?!^[a-z0-9-]+\.[a-z0-9-]+\.[a-zA-Z0-9_.-]+$) - - patterns: - - pattern-either: - - pattern: $I18NEXT.t([$DYNAMIC_KEY, '$KEY']) - - pattern: $I18NEXT.t([$DYNAMIC_KEY, '$KEY'], $OPTIONS) - - metavariable-regex: - metavariable: $I18NEXT - regex: (^(i18n|i18next)$) - - metavariable-regex: - metavariable: $DYNAMIC_KEY - regex: (?!^[`][a-z0-9-]+[.][a-z0-9-]+[.]\S+$) - severity: WARNING - - id: typescript.react.portability.i18next.jsx-label-not-i18n.jsx-label-not-i18n - languages: - - typescript - - javascript - message: 'JSX Component label not internationalized: ''$MESSAGE''' - metadata: - category: portability - references: - - https://www.notion.so/hendyirawan/Internationalization-Localization-Policy-318c21674e5f44c48d6f136a6eb2e024 - - https://mui.com/ - - https://react.i18next.com/ - technology: - - react - - mui - - i18next - patterns: - - pattern-either: - - pattern: - - pattern: - - metavariable-regex: - metavariable: $MESSAGE - regex: (.*[a-zA-Z]+.*) - - pattern-not: <$ELEMENT ... label="" ... /> - - pattern-not: <$ELEMENT ... label={t($KEY, ...)} ... /> - severity: WARNING - - id: typescript.react.portability.i18next.jsx-not-internationalized.jsx-not-internationalized - languages: - - typescript - - javascript - message: 'JSX element not internationalized: ''$MESSAGE''. You should support different languages in your website or app with internationalization. Instead, use packages such as `i18next` in order to internationalize your elements.' - metadata: - category: portability - references: - - https://www.notion.so/hendyirawan/Internationalization-Localization-Policy-318c21674e5f44c48d6f136a6eb2e024 - - https://mui.com/ - - https://react.i18next.com/ - technology: - - react - - mui - - i18next - patterns: - - pattern: <$ELEMENT>$MESSAGE - - metavariable-regex: - metavariable: $MESSAGE - regex: ([A-Za-z\n ]+[A-Za-z]+[A-Za-z\n ]+) - - pattern-not: <$ELEMENT>t('$KEY', ...) - severity: WARNING - - id: typescript.react.portability.i18next.mui-snackbar-message.mui-snackbar-message - languages: - - typescript - - javascript - message: 'React MUI enqueueSnackbar() title is not internationalized: ''$MESSAGE''' - metadata: - category: portability - references: - - https://hendyirawan.notion.site/Internationalization-Localization-Policy-318c21674e5f44c48d6f136a6eb2e024 - - https://mui.com/ - - https://react.i18next.com/ - technology: - - react - - mui - - i18next - patterns: - - pattern: enqueueSnackbar('$MESSAGE', $X2) - - pattern-not: enqueueSnackbar(t($KEY), $X2) - severity: WARNING - - id: typescript.react.portability.i18next.useselect-label-not-i18n.useselect-label-not-i18n - languages: - - typescript - - javascript - message: React useSelect() label is not internationalized - '$LABEL'. You should support different langauges in your website or app with internationalization. Instead, use packages such as `i18next` to internationalize your elements. - metadata: - category: portability - references: - - https://www.notion.so/hendyirawan/Internationalization-Localization-Policy-318c21674e5f44c48d6f136a6eb2e024 - - https://react.i18next.com/ - technology: - - react - - mui - - i18next - patterns: - - pattern: useSelect($X1, $X2, '$LABEL', $X4) - - metavariable-regex: - metavariable: $LABEL - regex: (.*[A-Za-z].*) - - pattern-not: useSelect($X1, $X2, t('...'), $X4) - severity: WARNING - - id: typescript.react.security.audit.react-dangerouslysetinnerhtml.react-dangerouslysetinnerhtml - languages: - - typescript - - javascript - message: Detection of dangerouslySetInnerHTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use dangerouslySetInnerHTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html - subcategory: - - vuln - technology: - - react - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; - ... - - pattern-inside: | - $S = require("sanitize-html") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - $S = new Remarkable() - ... - - pattern: $S.render(...) - pattern-sinks: - - patterns: - - focus-metavariable: $X - - pattern-either: - - pattern: | - {...,dangerouslySetInnerHTML: {__html: $X},...} - - pattern: | - <$Y ... dangerouslySetInnerHTML={{__html: $X}} /> - - pattern-not: | - <$Y ... dangerouslySetInnerHTML={{__html: "..."}} /> - - pattern-not: | - {...,dangerouslySetInnerHTML:{__html: "..."},...} - - metavariable-pattern: - metavariable: $X - patterns: - - pattern-not: | - {...} - - pattern-not: | - <... {__html: "..."} ...> - - pattern-not: | - <... {__html: `...`} ...> - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - function ...({..., $X, ...}) { ... } - - pattern-inside: | - function ...(..., $X, ...) { ... } - - focus-metavariable: $X - - pattern-not-inside: | - $F. ... .$SANITIZEUNC(...) - severity: WARNING - - id: typescript.react.security.audit.react-href-var.react-href-var - languages: - - typescript - - javascript - message: Detected a variable used in an anchor tag with the 'href' attribute. A malicious actor may be able to input the 'javascript:' URI, which could cause cross-site scripting (XSS). It is recommended to disallow 'javascript:' URIs within your application. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://reactjs.org/blog/2019/08/08/react-v16.9.0.html#deprecating-javascript-urls - - https://pragmaticwebsecurity.com/articles/spasecurity/react-xss-part1.html - subcategory: - - audit - technology: - - react - mode: taint - pattern-sinks: - - patterns: - - focus-metavariable: $X - - pattern-either: - - pattern: | - <$EL href={$X} /> - - pattern: | - React.createElement($EL, {href: $X}) - - pattern-inside: | - $PARAMS = {href: $X}; - ... - React.createElement($EL, $PARAMS); - - metavariable-pattern: - metavariable: $EL - patterns: - - pattern-not-regex: (?i)(button) - requires: TAINTED and not CONCAT and not CLEAN - pattern-sources: - - label: TAINTED - patterns: - - pattern-either: - - pattern-inside: | - function ...({..., $X, ...}) { ... } - - pattern-inside: | - function ...(..., $X, ...) { ... } - - focus-metavariable: $X - - pattern-either: - - pattern: $X.$Y - - pattern: $X[...] - - pattern-not-inside: | - $F. ... .$SANITIZEUNC(...) - - label: CONCAT - patterns: - - pattern-either: - - pattern: | - `...${$X}...` - - pattern: | - $SANITIZE + <... $X ...> - - pattern-not: | - `${$X}...` - - pattern-not: | - $X + ... - - focus-metavariable: $X - requires: TAINTED - - by-side-effect: true - label: CLEAN - patterns: - - pattern-either: - - pattern: $A($SOURCE) - - pattern: $SANITIZE. ... .$A($SOURCE) - - pattern: $A. ... .$SANITIZE($SOURCE) - - focus-metavariable: $SOURCE - - metavariable-regex: - metavariable: $A - regex: (?i)(.*valid|.*sanitiz) - severity: WARNING - - id: typescript.react.security.audit.react-jwt-decoded-property.react-jwt-decoded-property - languages: - - typescript - - javascript - message: Property decoded from JWT token without verifying and cannot be trustworthy. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-922: Insecure Storage of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://pragmaticwebsecurity.com/articles/oauthoidc/localstorage-xss.html - subcategory: - - audit - technology: - - react - patterns: - - pattern-inside: | - import jwt_decode from "jwt-decode"; - ... - - pattern-inside: | - $DECODED = jwt_decode($TOKEN,...); - ... - - pattern: $DECODED.$PROPERTY - severity: INFO - - id: typescript.react.security.audit.react-jwt-in-localstorage.react-jwt-in-localstorage - languages: - - typescript - - javascript - message: Storing JWT tokens in localStorage known to be a bad practice, consider moving your tokens from localStorage to a HTTP cookie. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-922: Insecure Storage of Sensitive Information' - impact: LOW - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies - subcategory: - - audit - technology: - - react - patterns: - - pattern-inside: | - import jwt_decode from "jwt-decode"; - ... - - pattern-either: - - pattern: | - $DECODED = jwt_decode($TOKEN,...); - ... - localStorage.setItem($NAME, <... $TOKEN ...>); - - pattern: | - $DECODED = jwt_decode(...); - ... - localStorage.setItem($NAME, <... $DECODED ...>); - severity: INFO - - id: typescript.react.security.audit.react-unsanitized-method.react-unsanitized-method - languages: - - typescript - - javascript - message: Detection of $HTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use $HTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://developer.mozilla.org/en-US/docs/Web/API/Document/writeln - - https://developer.mozilla.org/en-US/docs/Web/API/Document/write - - https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML - subcategory: - - vuln - technology: - - react - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; - ... - - pattern-inside: | - $S = require("sanitize-html") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - $S = new Remarkable() - ... - - pattern: $S.render(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: "this.window.document. ... .$HTML('...',$SINK) \n" - - pattern: "window.document. ... .$HTML('...',$SINK) \n" - - pattern: "document.$HTML($SINK) \n" - - metavariable-regex: - metavariable: $HTML - regex: (writeln|write) - - focus-metavariable: $SINK - - patterns: - - pattern-either: - - pattern: "$PROP. ... .$HTML('...',$SINK) \n" - - metavariable-regex: - metavariable: $HTML - regex: (insertAdjacentHTML) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - function ...({..., $X, ...}) { ... } - - pattern-inside: | - function ...(..., $X, ...) { ... } - - focus-metavariable: $X - - pattern-either: - - pattern: $X.$Y - - pattern: $X[...] - severity: WARNING - - id: typescript.react.security.audit.react-unsanitized-property.react-unsanitized-property - languages: - - typescript - - javascript - message: Detection of $HTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use $HTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html - subcategory: - - vuln - technology: - - react - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - import * as $S from "underscore.string" - ... - - pattern-inside: | - import $S from "underscore.string" - ... - - pattern-inside: | - $S = require("underscore.string") - ... - - pattern-either: - - pattern: $S.escapeHTML(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from "dompurify" - ... - - pattern-inside: | - import { ..., $S,... } from "dompurify" - ... - - pattern-inside: | - import * as $S from "dompurify" - ... - - pattern-inside: | - $S = require("dompurify") - ... - - pattern-inside: | - import $S from "isomorphic-dompurify" - ... - - pattern-inside: | - import * as $S from "isomorphic-dompurify" - ... - - pattern-inside: | - $S = require("isomorphic-dompurify") - ... - - pattern-either: - - patterns: - - pattern-inside: | - $VALUE = $S(...) - ... - - pattern: $VALUE.sanitize(...) - - patterns: - - pattern-inside: | - $VALUE = $S.sanitize - ... - - pattern: $S(...) - - pattern: $S.sanitize(...) - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'xss'; - ... - - pattern-inside: | - import * as $S from 'xss'; - ... - - pattern-inside: | - $S = require("xss") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - import $S from 'sanitize-html'; - ... - - pattern-inside: | - import * as $S from "sanitize-html"; - ... - - pattern-inside: | - $S = require("sanitize-html") - ... - - pattern: $S(...) - - patterns: - - pattern-either: - - pattern-inside: | - $S = new Remarkable() - ... - - pattern: $S.render(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $BODY = $REACT.useRef(...) - ... - - pattern-inside: | - $BODY = useRef(...) - ... - - pattern-inside: | - $BODY = findDOMNode(...) - ... - - pattern-inside: | - $BODY = createRef(...) - ... - - pattern-inside: | - $BODY = $REACT.findDOMNode(...) - ... - - pattern-inside: | - $BODY = $REACT.createRef(...) - ... - - pattern-either: - - pattern: "$BODY. ... .$HTML = $SINK \n" - - pattern: "$BODY.$HTML = $SINK \n" - - metavariable-regex: - metavariable: $HTML - regex: (innerHTML|outerHTML) - - focus-metavariable: $SINK - - patterns: - - pattern-either: - - pattern: ReactDOM.findDOMNode(...).$HTML = $SINK - - metavariable-regex: - metavariable: $HTML - regex: (innerHTML|outerHTML) - - focus-metavariable: $SINK - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - function ...({..., $X, ...}) { ... } - - pattern-inside: | - function ...(..., $X, ...) { ... } - - focus-metavariable: $X - - pattern-either: - - pattern: $X.$Y - - pattern: $X[...] - severity: WARNING - - id: typescript.react.security.react-insecure-request.react-insecure-request - languages: - - typescript - - javascript - message: Unencrypted request over HTTP detected. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: LOW - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://www.npmjs.com/package/axios - subcategory: - - vuln - technology: - - react - vulnerability: Insecure Transport - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - import $AXIOS from 'axios'; - ... - $AXIOS.$METHOD(...) - - pattern-inside: | - $AXIOS = require('axios'); - ... - $AXIOS.$METHOD(...) - - pattern-either: - - pattern: $AXIOS.get("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.post("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.delete("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.head("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.patch("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.put("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - pattern: $AXIOS.options("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) - - patterns: - - pattern-either: - - pattern-inside: | - import $AXIOS from 'axios'; - ... - $AXIOS(...) - - pattern-inside: | - $AXIOS = require('axios'); - ... - $AXIOS(...) - - pattern-either: - - pattern: '$AXIOS({url: "=~/[Hh][Tt][Tt][Pp]:\/\/.*/"}, ...)' - - pattern: | - $OPTS = {url: "=~/[Hh][Tt][Tt][Pp]:\/\/.*/"} - ... - $AXIOS($OPTS, ...) - - pattern: fetch("=~/[Hh][Tt][Tt][Pp]:\/\/.*/", ...) - severity: ERROR - - id: typescript.react.security.react-markdown-insecure-html.react-markdown-insecure-html - languages: - - typescript - - javascript - message: Overwriting `transformLinkUri` or `transformImageUri` to something insecure, or turning `allowDangerousHtml` on, or turning `escapeHtml` off, will open the code up to XSS vectors. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' - cwe2021-top25: true - cwe2022-top25: true - impact: LOW - likelihood: LOW - owasp: - - A07:2017 - Cross-Site Scripting (XSS) - - A03:2021 - Injection - references: - - https://www.npmjs.com/package/react-markdown#security - subcategory: - - audit - technology: - - react - patterns: - - pattern-either: - - pattern-inside: | - $X = require('react-markdown/with-html'); - ... - - pattern-inside: | - $X = require('react-markdown'); - ... - - pattern-inside: | - import 'react-markdown/with-html'; - ... - - pattern-inside: | - import 'react-markdown'; - ... - - pattern-either: - - pattern: | - <$EL allowDangerousHtml /> - - pattern: | - <$EL escapeHtml={false} /> - - pattern: | - <$EL transformLinkUri=... /> - - pattern: | - <$EL transformImageUri=... /> - severity: WARNING - - id: yaml.argo.correctness.event-binding-payload-with-hyphen.event-binding-payload-with-hyphen - languages: - - yaml - match: - all: - - inside: | - apiVersion: argoproj.io/v1alpha1 - kind: WorkflowEventBinding - ... - - inside: | - spec: - ... - submit: - ... - arguments: - ... - parameters: - ... - - | - event: $VALUE - where: - - metavariable: $VALUE - regex: payload\..*-.* - message: The parameter `$VALUE` to this WorkflowEventBinding includes hyphens, which will, very confusingly, throw an error when Argo Workflows tries to invoke the workflow. Set the payload value to use underscores instead. - metadata: - category: correctness - references: - - https://argoproj.github.io/argo-workflows/variables/#expression - technology: - - argo - - argo-workflows - severity: WARNING - - id: yaml.argo.security.argo-workflow-parameter-command-injection.argo-workflow-parameter-command-injection - languages: - - yaml - message: Using input or workflow parameters in here-scripts can lead to command injection or code injection. Convert the parameters to env variables instead. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - impact: HIGH - likelihood: MEDIUM - owasp: - - A03:2021 – Injection - references: - - https://github.com/argoproj/argo-workflows/issues/5061 - - https://github.com/argoproj/argo-workflows/issues/5114#issue-808865370 - subcategory: - - vuln - technology: - - ci - - argo - patterns: - - pattern-inside: | - apiVersion: $VERSION - ... - - metavariable-regex: - metavariable: $VERSION - regex: (argoproj.io.*) - - pattern-either: - - patterns: - - pattern-inside: "command:\n ...\n - python\n ...\n...\nsource: \n $SCRIPT\n" - - focus-metavariable: $SCRIPT - - metavariable-pattern: - language: python - metavariable: $SCRIPT - patterns: - - pattern: | - $FUNC(..., $PARAM, ...) - - metavariable-pattern: - metavariable: $PARAM - pattern-either: - - pattern-regex: (.*{{.*inputs.parameters.*}}.*) - - pattern-regex: (.*{{.*workflow.parameters.*}}.*) - - patterns: - - pattern-inside: "command:\n ...\n - $LANG\n ...\n...\nsource: \n $SCRIPT\n" - - metavariable-regex: - metavariable: $LANG - regex: (bash|sh) - - focus-metavariable: $SCRIPT - - metavariable-pattern: - language: bash - metavariable: $SCRIPT - patterns: - - pattern: | - $CMD ... $PARAM ... - - metavariable-pattern: - metavariable: $PARAM - pattern-either: - - pattern-regex: (.*{{.*inputs.parameters.*}}.*) - - pattern-regex: (.*{{.*workflow.parameters.*}}.*) - - patterns: - - pattern-inside: | - container: - ... - command: $LANG - ... - args: $PARAM - - metavariable-regex: - metavariable: $LANG - regex: .*(sh|bash|ksh|csh|tcsh|zsh).* - - metavariable-pattern: - metavariable: $PARAM - pattern-either: - - pattern-regex: (.*{{.*inputs.parameters.*}}.*) - - pattern-regex: (.*{{.*workflow.parameters.*}}.*) - - focus-metavariable: $PARAM - severity: ERROR - - id: yaml.docker-compose.security.exposing-docker-socket-volume.exposing-docker-socket-volume - languages: - - yaml - message: Exposing host's Docker socket to containers via a volume. The owner of this socket is root. Giving someone access to it is equivalent to giving unrestricted root access to your host. Remove 'docker.sock' from volumes to prevent this. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: HIGH - likelihood: LOW - owasp: - - A06:2017 - Security Misconfiguration - - A05:2021 - Security Misconfiguration - references: - - https://docs.docker.com/compose/compose-file/compose-file-v3/#volume-configuration-reference - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-1-do-not-expose-the-docker-daemon-socket-even-to-the-containers - subcategory: - - audit - technology: - - docker-compose - patterns: - - pattern-inside: | - version: ... - ... - - pattern-either: - - pattern: | - volumes: - - ... - - /var/run/docker.sock:/var/run/docker.sock - - ... - - pattern: | - volumes: - - ... - - /run/docker.sock:/run/docker.sock - - ... - - pattern: | - volumes: - - ... - - /var/run/docker.sock:/run/docker.sock - - ... - - pattern: | - volumes: - - ... - - /run/docker.sock:/var/run/docker.sock - - ... - - pattern: | - volumes: - - ... - - /var/run/docker.sock - - ... - - pattern: | - volumes: - - ... - - /run/docker.sock - - ... - - pattern: | - volumes: - - ... - - ... - source: /var/run/docker.sock - ... - - ... - - pattern: | - volumes: - - ... - - ... - source: /run/docker.sock - ... - - ... - severity: WARNING - - id: yaml.docker-compose.security.no-new-privileges.no-new-privileges - languages: - - yaml - message: Service '$SERVICE' allows for privilege escalation via setuid or setgid binaries. Add 'no-new-privileges:true' in 'security_opt' to prevent this. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs/ - - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag - subcategory: - - audit - technology: - - docker-compose - patterns: - - pattern-inside: | - version: ... - ... - services: - ... - - pattern: | - $SERVICE: - ... - image: ... - - pattern-not: | - $SERVICE: - ... - image: ... - ... - security_opt: - - ... - - no-new-privileges:true - - ... - - focus-metavariable: $SERVICE - severity: WARNING - - fix: | - false - id: yaml.docker-compose.security.privileged-service.privileged-service - languages: - - yaml - message: Service '$SERVICE' is running in privileged mode. This grants the container the equivalent of root capabilities on the host machine. This can lead to container escapes, privilege escalation, and other security concerns. Remove the 'privileged' key to disable this capability. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: HIGH - owasp: - - A06:2017 - Security Misconfiguration - - A05:2021 - Security Misconfiguration - references: - - https://www.trendmicro.com/en_us/research/19/l/why-running-a-privileged-container-in-docker-is-a-bad-idea.html - - https://containerjournal.com/topics/container-security/why-running-a-privileged-container-is-not-a-good-idea/ - subcategory: - - vuln - technology: - - docker-compose - patterns: - - pattern-inside: | - version: ... - ... - services: - ... - $SERVICE: - ... - privileged: $TRUE - - focus-metavariable: $TRUE - - metavariable-regex: - metavariable: $TRUE - regex: (true) - severity: WARNING - - id: yaml.docker-compose.security.seccomp-confinement-disabled.seccomp-confinement-disabled - languages: - - yaml - message: Service '$SERVICE' is explicitly disabling seccomp confinement. This runs the service in an unrestricted state. Remove 'seccomp:unconfined' to prevent this. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: HIGH - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://docs.docker.com/engine/security/seccomp/ - subcategory: - - audit - technology: - - docker-compose - patterns: - - pattern-inside: | - version: ... - ... - services: - ... - - pattern: | - $SERVICE: - ... - image: ... - ... - security_opt: - - ... - - seccomp:unconfined - severity: WARNING - - id: yaml.docker-compose.security.selinux-separation-disabled.selinux-separation-disabled - languages: - - yaml - message: Service '$SERVICE' is explicitly disabling SELinux separation. This runs the service as an unconfined type. Remove 'label:disable' to prevent this. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-284: Improper Access Control' - impact: HIGH - likelihood: LOW - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://www.projectatomic.io/blog/2016/03/dwalsh_selinux_containers/ - - https://docs.docker.com/engine/reference/run/#security-configuration - subcategory: - - audit - technology: - - docker-compose - patterns: - - pattern-inside: | - version: ... - ... - services: - ... - - pattern: | - $SERVICE: - ... - image: ... - ... - security_opt: - - ... - - label:disable - severity: WARNING - - id: yaml.docker-compose.security.writable-filesystem-service.writable-filesystem-service - languages: - - yaml - message: 'Service ''$SERVICE'' is running with a writable root filesystem. This may allow malicious applications to download and run additional payloads, or modify container files. If an application inside a container has to save something temporarily consider using a tmpfs. Add ''read_only: true'' to this service to prevent this.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://docs.docker.com/compose/compose-file/compose-file-v3/#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir - - https://blog.atomist.com/security-of-docker-kubernetes/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-8-set-filesystem-and-volumes-to-read-only - subcategory: - - audit - technology: - - docker-compose - patterns: - - pattern-inside: | - version: ... - ... - services: - ... - - pattern: | - $SERVICE: - ... - image: ... - ... - - pattern-not: | - $SERVICE: - ... - image: ... - ... - read_only: true - - focus-metavariable: $SERVICE - severity: WARNING - - id: yaml.github-actions.security.allowed-unsecure-commands.allowed-unsecure-commands - languages: - - yaml - message: The environment variable `ACTIONS_ALLOW_UNSECURE_COMMANDS` grants this workflow permissions to use the `set-env` and `add-path` commands. There is a vulnerability in these commands that could result in environment variables being modified by an attacker. Depending on the use of the environment variable, this could enable an attacker to, at worst, modify the system path to run a different command than intended, resulting in arbitrary code execution. This could result in stolen code or secrets. Don't use `ACTIONS_ALLOW_UNSECURE_COMMANDS`. Instead, use Environment Files. See https://github.com/actions/toolkit/blob/main/docs/commands.md#environment-files for more information. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-749: Exposed Dangerous Method or Function' - impact: MEDIUM - likelihood: LOW - owasp: A06:2017 - Security Misconfiguration - references: - - https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/ - - https://github.com/actions/toolkit/security/advisories/GHSA-mfwh-5m23-j46w - - https://github.com/actions/toolkit/blob/main/docs/commands.md#environment-files - subcategory: - - vuln - technology: - - github-actions - patterns: - - pattern-either: - - patterns: - - pattern-inside: '{env: ...}' - - pattern: 'ACTIONS_ALLOW_UNSECURE_COMMANDS: true' - severity: WARNING - - id: yaml.github-actions.security.curl-eval.curl-eval - languages: - - yaml - message: Data is being eval'd from a `curl` command. An attacker with control of the server in the `curl` command could inject malicious code into the `eval`, resulting in a system comrpomise. Avoid eval'ing untrusted data if you can. If you must do this, consider checking the SHA sum of the content returned by the server to verify its integrity. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: LOW - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections - subcategory: - - audit - technology: - - github-actions - - bash - - curl - patterns: - - pattern-inside: 'steps: [...]' - - pattern-inside: | - - run: ... - ... - - pattern: 'run: $SHELL' - - metavariable-pattern: - language: bash - metavariable: $SHELL - patterns: - - pattern: | - $DATA=<... curl ...> - ... - eval <... $DATA ...> - severity: ERROR - - id: yaml.github-actions.security.github-script-injection.github-script-injection - languages: - - yaml - message: 'Using variable interpolation `${{...}}` with `github` context data in a `actions/github-script`''s `script:` step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. `github` context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with `env:` to store the data and use the environment variable in the `run:` script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' - cwe2022-top25: true - impact: HIGH - likelihood: HIGH - owasp: - - A03:2021 - Injection - references: - - https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections - - https://securitylab.github.com/research/github-actions-untrusted-input/ - - https://github.com/actions/github-script - subcategory: - - vuln - technology: - - github-actions - patterns: - - pattern-inside: 'steps: [...]' - - pattern-inside: | - uses: $ACTION - ... - - pattern-inside: | - with: - ... - script: ... - ... - - pattern: 'script: $SHELL' - - metavariable-regex: - metavariable: $ACTION - regex: actions/github-script@.* - - metavariable-pattern: - language: generic - metavariable: $SHELL - patterns: - - pattern-either: - - pattern: ${{ github.event.issue.title }} - - pattern: ${{ github.event.issue.body }} - - pattern: ${{ github.event.pull_request.title }} - - pattern: ${{ github.event.pull_request.body }} - - pattern: ${{ github.event.comment.body }} - - pattern: ${{ github.event.review.body }} - - pattern: ${{ github.event.review_comment.body }} - - pattern: ${{ github.event.pages. ... .page_name}} - - pattern: ${{ github.event.head_commit.message }} - - pattern: ${{ github.event.head_commit.author.email }} - - pattern: ${{ github.event.head_commit.author.name }} - - pattern: ${{ github.event.commits ... .author.email }} - - pattern: ${{ github.event.commits ... .author.name }} - - pattern: ${{ github.event.pull_request.head.ref }} - - pattern: ${{ github.event.pull_request.head.label }} - - pattern: ${{ github.event.pull_request.head.repo.default_branch }} - - pattern: ${{ github.head_ref }} - - pattern: ${{ github.event.inputs ... }} - severity: ERROR - - id: yaml.github-actions.security.pull-request-target-code-checkout.pull-request-target-code-checkout - languages: - - yaml - message: This GitHub Actions workflow file uses `pull_request_target` and checks out code from the incoming pull request. When using `pull_request_target`, the Action runs in the context of the target repository, which includes access to all repository secrets. Normally, this is safe because the Action only runs code from the target repository, not the incoming PR. However, by checking out the incoming PR code, you're now using the incoming code for the rest of the action. You may be inadvertently executing arbitrary code from the incoming PR with access to repository secrets, which would let an attacker steal repository secrets. This normally happens by running build scripts (e.g., `npm build` and `make`) or dependency installation scripts (e.g., `python setup.py install`). Audit your workflow file to make sure no code from the incoming PR is executed. Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-913: Improper Control of Dynamically-Managed Code Resources' - impact: MEDIUM - likelihood: LOW - owasp: - - A01:2021 - Broken Access Control - references: - - https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ - - https://github.com/justinsteven/advisories/blob/master/2021_github_actions_checkspelling_token_leak_via_advice_symlink.md - subcategory: - - audit - technology: - - github-actions - patterns: - - pattern-either: - - pattern-inside: | - on: - ... - pull_request_target: ... - ... - ... - - pattern-inside: | - on: [..., pull_request_target, ...] - ... - - pattern-inside: | - on: pull_request_target - ... - - pattern-inside: | - jobs: - ... - $JOBNAME: - ... - steps: - ... - - pattern: | - ... - uses: "$ACTION" - with: - ... - ref: $EXPR - - metavariable-regex: - metavariable: $ACTION - regex: actions/checkout@.* - - metavariable-pattern: - language: generic - metavariable: $EXPR - patterns: - - pattern: ${{ github.event.pull_request ... }} - severity: WARNING - - id: yaml.github-actions.security.run-shell-injection.run-shell-injection - languages: - - yaml - message: 'Using variable interpolation `${{...}}` with `github` context data in a `run:` step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. `github` context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with `env:` to store the data and use the environment variable in the `run:` script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' - cwe2021-top25: true - cwe2022-top25: true - impact: HIGH - likelihood: HIGH - owasp: - - A01:2017 - Injection - - A03:2021 - Injection - references: - - https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections - - https://securitylab.github.com/research/github-actions-untrusted-input/ - subcategory: - - vuln - technology: - - github-actions - patterns: - - pattern-inside: 'steps: [...]' - - pattern-inside: | - - run: ... - ... - - pattern: 'run: $SHELL' - - metavariable-pattern: - language: generic - metavariable: $SHELL - patterns: - - pattern-either: - - pattern: ${{ github.event.issue.title }} - - pattern: ${{ github.event.issue.body }} - - pattern: ${{ github.event.pull_request.title }} - - pattern: ${{ github.event.pull_request.body }} - - pattern: ${{ github.event.comment.body }} - - pattern: ${{ github.event.review.body }} - - pattern: ${{ github.event.review_comment.body }} - - pattern: ${{ github.event.pages. ... .page_name}} - - pattern: ${{ github.event.head_commit.message }} - - pattern: ${{ github.event.head_commit.author.email }} - - pattern: ${{ github.event.head_commit.author.name }} - - pattern: ${{ github.event.commits ... .author.email }} - - pattern: ${{ github.event.commits ... .author.name }} - - pattern: ${{ github.event.pull_request.head.ref }} - - pattern: ${{ github.event.pull_request.head.label }} - - pattern: ${{ github.event.pull_request.head.repo.default_branch }} - - pattern: ${{ github.head_ref }} - - pattern: ${{ github.event.inputs ... }} - severity: ERROR - - id: yaml.github-actions.security.third-party-action-not-pinned-to-commit-sha.third-party-action-not-pinned-to-commit-sha - languages: - - yaml - message: An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-1357: Reliance on Insufficiently Trustworthy Component' - - 'CWE-353: Missing Support for Integrity Check' - impact: LOW - likelihood: LOW - owasp: A06:2021 - Vulnerable and Outdated Components - references: - - https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components - - https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions - subcategory: - - vuln - technology: - - github-actions - patterns: - - pattern-inside: '{steps: ...}' - - pattern: | - uses: "$USES" - - metavariable-pattern: - language: generic - metavariable: $USES - patterns: - - pattern-not-regex: ^[.]/ - - pattern-not-regex: ^actions/ - - pattern-not-regex: ^github/ - - pattern-not-regex: '@[0-9a-f]{40}$' - - pattern-not-regex: ^docker://.*@sha256:[0-9a-f]{64}$ - severity: WARNING - - id: yaml.github-actions.security.workflow-run-target-code-checkout.workflow-run-target-code-checkout - languages: - - yaml - message: This GitHub Actions workflow file uses `workflow_run` and checks out code from the incoming pull request. When using `workflow_run`, the Action runs in the context of the target repository, which includes access to all repository secrets. Normally, this is safe because the Action only runs code from the target repository, not the incoming PR. However, by checking out the incoming PR code, you're now using the incoming code for the rest of the action. You may be inadvertently executing arbitrary code from the incoming PR with access to repository secrets, which would let an attacker steal repository secrets. This normally happens by running build scripts (e.g., `npm build` and `make`) or dependency installation scripts (e.g., `python setup.py install`). Audit your workflow file to make sure no code from the incoming PR is executed. Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations. - metadata: - category: security - confidence: MEDIUM - cwe: 'CWE-913: Improper Control of Dynamically-Managed Code Resources' - impact: MEDIUM - likelihood: MEDIUM - owasp: A01:2017 - Injection - references: - - https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ - - https://github.com/justinsteven/advisories/blob/master/2021_github_actions_checkspelling_token_leak_via_advice_symlink.md - - https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability - subcategory: - - vuln - technology: - - github-actions - patterns: - - pattern-inside: | - on: - ... - workflow_run: ... - ... - ... - - pattern-inside: | - jobs: - ... - $JOBNAME: - ... - steps: - ... - - pattern: | - ... - uses: "$ACTION" - with: - ... - ref: $EXPR - - metavariable-regex: - metavariable: $ACTION - regex: actions/checkout@.* - - metavariable-pattern: - language: generic - metavariable: $EXPR - patterns: - - pattern: ${{ github.event.workflow_run ... }} - severity: WARNING - - id: yaml.github-actions.semgrep-configuration.semgrep-github-action-push-without-branches.semgrep-github-action-push-without-branches - languages: - - yaml - message: The 'branches' field (in the push event configuration) contains no branches. This causes all branches to be scanned and may result in unneccessary duplicate findings across the entire codebase. - metadata: - category: correctness - technology: - - github-action - paths: - include: - - .github/workflows/semgrep.yml - - '*.test.yml' - patterns: - - pattern-either: - - pattern: | - on: [..., push, ...] - ... - - pattern: | - on: push - ... - - pattern: | - on: - ... - push: "" - ... - ... - - pattern: | - on: - ... - push: {} - ... - ... - - patterns: - - pattern-inside: | - on: - ... - push: ... - ... - ... - - pattern-either: - - pattern: | - branches: "" - - pattern: | - branches: [] - severity: WARNING - - id: yaml.gitlab.correctness.changes-with-when-never.changes-with-when-never - languages: - - yaml - message: 'This Gitlab CI YAML will never run on default branches due to a `changes` rule with `when:never`. To fix this, make sure the triggering event is a push event. You can do this with `if: ''$CI_PIPELINE_SOURCE == "push"''`. See https://docs.gitlab.com/ee/ci/yaml/index.html#ruleschanges' - metadata: - category: correctness - technology: - - gitlab - - gitlab-ci - pattern: | - - changes: - - ... - when: never - severity: WARNING - - fix: 'cpu: 1000m' - id: yaml.kubernetes.best-practice.no-fractional-cpu-limits.no-fractional-cpu-limits - languages: - - yaml - message: When you set a fractional CPU limit on a container, the CPU cycles available will be throttled, even though most nodes can handle processes alternating between using 100% of the CPU. - metadata: - category: best-practice - technology: - - kubernetes - patterns: - - pattern-inside: | - limits: - ... - - pattern: | - cpu: $CPU_LIMIT - - metavariable-regex: - metavariable: $CPU_LIMIT - regex: \d{0,3}m - severity: WARNING - - fix: | - securityContext: - allowPrivilegeEscalation: false - $NAME - id: yaml.kubernetes.security.allow-privilege-escalation-no-securitycontext.allow-privilege-escalation-no-securitycontext - languages: - - yaml - message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. By adding a `securityContext` to your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag - subcategory: - - vuln - technology: - - kubernetes - patterns: - - pattern-inside: | - containers: - ... - - pattern-inside: | - - $NAME: $CONTAINER - ... - - pattern: | - image: ... - ... - - pattern-not: | - image: ... - ... - securityContext: - ... - - metavariable-regex: - metavariable: $NAME - regex: name - - focus-metavariable: $NAME - severity: WARNING - - fix: | - false - id: yaml.kubernetes.security.allow-privilege-escalation-true.allow-privilege-escalation-true - languages: - - yaml - message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. In the container `$CONTAINER` this parameter is set to `true` which makes this container much more vulnerable to privelege escalation attacks. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag - subcategory: - - vuln - technology: - - kubernetes - patterns: - - pattern-inside: | - containers: - ... - - pattern-inside: | - - name: $CONTAINER - ... - - pattern-inside: | - image: ... - ... - - pattern-inside: | - securityContext: - ... - - pattern: | - allowPrivilegeEscalation: $TRUE - - metavariable-pattern: - metavariable: $TRUE - pattern: | - true - - focus-metavariable: $TRUE - severity: WARNING - - fix: | - securityContext: - allowPrivilegeEscalation: false # - id: yaml.kubernetes.security.allow-privilege-escalation.allow-privilege-escalation - languages: - - yaml - message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. By adding the `allowPrivilegeEscalation` parameter to your the `securityContext`, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag - subcategory: - - vuln - technology: - - kubernetes - patterns: - - pattern-inside: | - containers: - ... - - pattern-inside: | - - name: $CONTAINER - ... - - pattern: | - image: ... - ... - - pattern-inside: | - image: ... - ... - $SC: - ... - - metavariable-regex: - metavariable: $SC - regex: ^(securityContext)$ - - pattern-not-inside: | - image: ... - ... - securityContext: - ... - allowPrivilegeEscalation: $VAL - - focus-metavariable: $SC - severity: WARNING - - fix-regex: - regex: development - replacement: dev - id: yaml.kubernetes.security.env.flask-debugging-enabled.flask-debugging-enabled - languages: - - yaml - message: Do not set FLASK_ENV to "development" since that sets `debug=True` in Flask. Use "dev" or a similar term instead. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-489: Active Debug Code' - impact: MEDIUM - likelihood: LOW - owasp: A06:2017 - Security Misconfiguration - references: - - https://flask.palletsprojects.com/en/2.0.x/debugging/ - - https://flask.palletsprojects.com/en/2.0.x/config/#ENV - subcategory: - - audit - technology: - - kubernetes - - flask - patterns: - - pattern-inside: | - env: [...] - - pattern: | - {name: FLASK_ENV, value: "development"} - severity: WARNING - - id: yaml.kubernetes.security.exposing-docker-socket-hostpath.exposing-docker-socket-hostpath - languages: - - yaml - message: Exposing host's Docker socket to containers via a volume. The owner of this socket is root. Giving someone access to it is equivalent to giving unrestricted root access to your host. Remove 'docker.sock' from hostpath to prevent this. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: HIGH - likelihood: LOW - references: - - https://kubernetes.io/docs/concepts/storage/volumes/#hostpath - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#volumes-and-file-systems - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-1-do-not-expose-the-docker-daemon-socket-even-to-the-containers - subcategory: - - vuln - technology: - - kubernetes - patterns: - - pattern-inside: | - volumes: - ... - - pattern: | - hostPath: - ... - path: /var/run/docker.sock - severity: WARNING - - id: yaml.kubernetes.security.hostipc-pod.hostipc-pod - languages: - - yaml - message: Pod is sharing the host IPC namespace. This allows container processes to communicate with processes on the host which reduces isolation and bypasses container protection models. Remove the 'hostIPC' key to disable this functionality. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-693: Protection Mechanism Failure' - impact: MEDIUM - likelihood: LOW - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces - subcategory: - - audit - technology: - - kubernetes - patterns: - - pattern-inside: | - spec: - ... - - pattern: | - hostIPC: true - severity: WARNING - - id: yaml.kubernetes.security.hostnetwork-pod.hostnetwork-pod - languages: - - yaml - message: Pod may use the node network namespace. This gives the pod access to the loopback device, services listening on localhost, and could be used to snoop on network activity of other pods on the same node. Remove the 'hostNetwork' key to disable this functionality. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-406: Insufficient Control of Network Message Volume (Network Amplification)' - impact: MEDIUM - likelihood: LOW - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces - subcategory: - - audit - technology: - - kubernetes - patterns: - - pattern-inside: | - spec: - ... - - pattern: | - hostNetwork: true - severity: WARNING - - id: yaml.kubernetes.security.hostpid-pod.hostpid-pod - languages: - - yaml - message: Pod is sharing the host process ID namespace. When paired with ptrace this can be used to escalate privileges outside of the container. Remove the 'hostPID' key to disable this functionality. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-269: Improper Privilege Management' - impact: MEDIUM - likelihood: LOW - owasp: - - A04:2021 - Insecure Design - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces - subcategory: - - audit - technology: - - kubernetes - patterns: - - pattern-inside: | - spec: - ... - - pattern: | - hostPID: true - severity: WARNING - - id: yaml.kubernetes.security.legacy-api-clusterrole-excessive-permissions.legacy-api-clusterrole-excessive-permissions - languages: - - yaml - message: 'Semgrep detected a Kubernetes core API ClusterRole with excessive permissions. Attaching excessive permissions to a ClusterRole associated with the core namespace allows the V1 API to perform arbitrary actions on arbitrary resources attached to the cluster. Prefer explicit allowlists of verbs/resources when configuring the core API namespace. ' - metadata: - category: security - confidence: HIGH - cwe: - - 'CWE-269: Improper Privilege Management' - cwe2021-top25: false - impact: HIGH - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole - - https://kubernetes.io/docs/concepts/security/rbac-good-practices/#general-good-practice - - https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#api-groups - subcategory: - - vuln - technology: - - kubernetes - patterns: - - pattern: | - "*" - - pattern-inside: | - resources: $A - ... - - pattern-inside: | - verbs: $A - ... - - pattern-inside: | - - apiGroups: [""] - ... - - pattern-inside: | - apiVersion: rbac.authorization.k8s.io/v1 - ... - - pattern-inside: | - kind: ClusterRole - ... - severity: WARNING - - id: yaml.kubernetes.security.privileged-container.privileged-container - languages: - - yaml - message: Container or pod is running in privileged mode. This grants the container the equivalent of root capabilities on the host machine. This can lead to container escapes, privilege escalation, and other security concerns. Remove the 'privileged' key to disable this capability. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: MEDIUM - likelihood: MEDIUM - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privileged - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html - subcategory: - - vuln - technology: - - kubernetes - pattern-either: - - patterns: - - pattern-inside: | - containers: - ... - - pattern: | - image: ... - ... - securityContext: - ... - privileged: true - - patterns: - - pattern-inside: | - spec: - ... - - pattern-not-inside: | - image: ... - ... - - pattern: | - privileged: true - severity: WARNING - - fix: | - securityContext: - runAsNonRoot: true - $IMAGE - id: yaml.kubernetes.security.run-as-non-root-container-level-missing-security-context.run-as-non-root-container-level-missing-security-context - languages: - - yaml - message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user - subcategory: - - audit - technology: - - kubernetes - patterns: - - pattern-inside: | - spec: - ... - containers: - ... - ... - - pattern-not-inside: | - spec: - ... - securityContext: - ... - runAsNonRoot: $VAL - ... - - pattern-inside: | - spec: - ... - containers: - ... - - pattern-inside: | - spec: - ... - containers: - ... - - name: $NAME - image: ... - ... - securityContext: - ... - runAsNonRoot: $VALUE - - pattern: | - - name: $CONTAINER - $IMAGE: $IMAGEVAL - ... - - pattern-not: | - - name: $CONTAINER - image: $IMAGEVAL - ... - securityContext: - ... - - metavariable-regex: - metavariable: $IMAGE - regex: image - - focus-metavariable: $IMAGE - severity: INFO - - fix: | - $SC: - runAsNonRoot: true # - id: yaml.kubernetes.security.run-as-non-root-container-level.run-as-non-root-container-level - languages: - - yaml - message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user - subcategory: - - audit - technology: - - kubernetes - patterns: - - pattern-inside: | - spec: - ... - containers: - ... - ... - - pattern-not-inside: | - spec: - ... - securityContext: - ... - runAsNonRoot: $VAL - ... - - pattern-inside: | - spec: - ... - containers: - ... - - pattern-inside: | - spec: - ... - containers: - ... - - name: $NAME - image: ... - ... - securityContext: - ... - runAsNonRoot: $VALUE - - pattern: | - - name: $CONTAINER - image: ... - ... - $SC: - ... - - metavariable-regex: - metavariable: $SC - regex: ^(securityContext)$ - - pattern-not: | - - name: $CONTAINER - image: ... - ... - securityContext: - ... - runAsNonRoot: $VALUE - - focus-metavariable: $SC - severity: INFO - - fix: | - $SC: - runAsNonRoot: true # - id: yaml.kubernetes.security.run-as-non-root-security-context-pod-level.run-as-non-root-security-context-pod-level - languages: - - yaml - message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user - subcategory: - - audit - technology: - - kubernetes - patterns: - - pattern-inside: | - spec: - ... - $SC: - ... - ... - - metavariable-regex: - metavariable: $SC - regex: ^(securityContext)$ - - pattern-not-inside: | - spec: - ... - securityContext: - runAsNonRoot: $VAL - ... - - pattern-inside: | - $SPEC: - ... - containers: - ... - - pattern-not-inside: | - $SPEC: - ... - containers: - ... - - name: $NAME - image: ... - ... - securityContext: - ... - runAsNonRoot: $VALUE - - focus-metavariable: $SC - severity: INFO - - fix: | - true - id: yaml.kubernetes.security.run-as-non-root-unsafe-value.run-as-non-root-unsafe-value - languages: - - yaml - message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: HIGH - likelihood: MEDIUM - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user - subcategory: - - audit - technology: - - kubernetes - patterns: - - pattern-either: - - pattern: | - spec: - ... - securityContext: - ... - runAsNonRoot: $VALUE - - patterns: - - pattern-inside: | - containers: - ... - - pattern: | - image: ... - ... - securityContext: - ... - runAsNonRoot: $VALUE - - metavariable-pattern: - metavariable: $VALUE - pattern: | - false - - focus-metavariable: $VALUE - severity: INFO - - fix: | - $SPEC: - securityContext: - runAsNonRoot: true # - id: yaml.kubernetes.security.run-as-non-root.run-as-non-root - languages: - - yaml - message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-250: Execution with Unnecessary Privileges' - impact: LOW - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user - subcategory: - - audit - technology: - - kubernetes - patterns: - - pattern-inside: | - $SPEC: - ... - containers: - ... - ... - - metavariable-regex: - metavariable: $SPEC - regex: ^(spec)$ - - pattern-not-inside: | - spec: - ... - securityContext: - ... - ... - - pattern-inside: | - $SPEC: - ... - containers: - ... - - pattern-not-inside: | - $SPEC: - ... - containers: - ... - - name: $NAME - image: ... - ... - securityContext: - ... - runAsNonRoot: $VALUE - - focus-metavariable: $SPEC - severity: INFO - - id: yaml.kubernetes.security.seccomp-confinement-disabled.seccomp-confinement-disabled - languages: - - yaml - message: 'Container is explicitly disabling seccomp confinement. This runs the service in an unrestricted state. Remove ''seccompProfile: unconfined'' to prevent this.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-284: Improper Access Control' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A05:2017 - Broken Access Control - - A01:2021 - Broken Access Control - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - subcategory: - - vuln - technology: - - kubernetes - patterns: - - pattern-inside: | - containers: - ... - - pattern: | - image: ... - ... - securityContext: - ... - seccompProfile: unconfined - severity: WARNING - - id: yaml.kubernetes.security.secrets-in-config-file.secrets-in-config-file - languages: - - yaml - message: 'Secrets ($VALUE) should not be stored in infrastructure as code files. Use an alternative such as Bitnami Sealed Secrets or KSOPS to encrypt Kubernetes Secrets. ' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-798: Use of Hard-coded Credentials' - cwe2021-top25: true - cwe2022-top25: true - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A07:2021 - Identification and Authentication Failures - references: - - https://kubernetes.io/docs/concepts/configuration/secret/ - - https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/0/CTR_Kubernetes_Hardening_Guidance_1.1_20220315.PDF - - https://docs.gitlab.com/ee/user/clusters/agent/gitops/secrets_management.html - - https://www.cncf.io/blog/2021/04/22/revealing-the-secrets-of-kubernetes-secrets/ - - https://github.com/bitnami-labs/sealed-secrets - - https://www.cncf.io/blog/2022/01/25/secrets-management-essential-when-using-kubernetes/ - - https://blog.oddbit.com/post/2021-03-09-getting-started-with-ksops/ - subcategory: - - vuln - technology: - - kubernetes - patterns: - - pattern: | - $KEY: $VALUE - - pattern-inside: | - data: ... - - pattern-inside: | - kind: Secret - ... - - metavariable-regex: - metavariable: $VALUE - regex: (?i)^[aA-zZ0-9+/]+={0,2}$ - - metavariable-analysis: - analyzer: entropy - metavariable: $VALUE - severity: WARNING - - id: yaml.kubernetes.security.skip-tls-verify-cluster.skip-tls-verify-cluster - languages: - - yaml - message: 'Cluster is disabling TLS certificate verification when communicating with the server. This makes your HTTPS connections insecure. Remove the ''insecure-skip-tls-verify: true'' key to secure communication.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://kubernetes.io/docs/reference/config-api/client-authentication.v1beta1/#client-authentication-k8s-io-v1beta1-Cluster - subcategory: - - vuln - technology: - - kubernetes - pattern: | - cluster: - ... - insecure-skip-tls-verify: true - severity: WARNING - - id: yaml.kubernetes.security.skip-tls-verify-service.skip-tls-verify-service - languages: - - yaml - message: 'Service is disabling TLS certificate verification when communicating with the server. This makes your HTTPS connections insecure. Remove the ''insecureSkipTLSVerify: true'' key to secure communication.' - metadata: - category: security - confidence: MEDIUM - cwe: - - 'CWE-319: Cleartext Transmission of Sensitive Information' - impact: MEDIUM - likelihood: MEDIUM - owasp: - - A03:2017 - Sensitive Data Exposure - - A02:2021 - Cryptographic Failures - references: - - https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#apiservice-v1-apiregistration-k8s-io - subcategory: - - vuln - technology: - - kubernetes - pattern: | - spec: - ... - insecureSkipTLSVerify: true - severity: WARNING - - id: yaml.kubernetes.security.writable-filesystem-container.writable-filesystem-container - languages: - - yaml - message: 'Container $CONTAINER is running with a writable root filesystem. This may allow malicious applications to download and run additional payloads, or modify container files. If an application inside a container has to save something temporarily consider using a tmpfs. Add ''readOnlyRootFilesystem: true'' to this container to prevent this.' - metadata: - category: security - confidence: LOW - cwe: - - 'CWE-732: Incorrect Permission Assignment for Critical Resource' - cwe2021-top25: true - impact: MEDIUM - likelihood: LOW - owasp: - - A05:2021 - Security Misconfiguration - - A06:2017 - Security Misconfiguration - references: - - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#volumes-and-file-systems - - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - - https://blog.atomist.com/security-of-docker-kubernetes/ - - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-8-set-filesystem-and-volumes-to-read-only - subcategory: - - audit - technology: - - kubernetes - patterns: - - pattern-inside: | - containers: - ... - - pattern-inside: | - - name: $CONTAINER - ... - - pattern: | - image: ... - ... - - pattern-not: | - image: ... - ... - securityContext: - ... - readOnlyRootFilesystem: true - - focus-metavariable: $CONTAINER - severity: WARNING - - id: yaml.openapi.security.api-key-in-query-parameter.api-key-in-query-parameter - languages: - - yaml - message: The $SECURITY_SCHEME security scheme passes an API key in a query parameter. API keys should not be passed as query parameters in security schemes. Pass the API key in the header or body. If using a query parameter is necessary, ensure that the API key is tightly scoped and short lived. - metadata: - category: security - confidence: LOW - cwe: 'CWE-598: Use of GET Request Method With Sensitive Query Strings' - impact: HIGH - likelihood: MEDIUM - owasp: - - A04:2021 Insecure Design - - A07:2021 Identification and Authentication Failures - references: - - https://datatracker.ietf.org/doc/html/rfc6749 - - https://cwe.mitre.org/data/definitions/598.html - - https://owasp.org/Top10/A04_2021-Insecure_Design/ - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ - subcategory: - - vuln - technology: - - openapi - patterns: - - pattern-inside: | - openapi: $VERSION - ... - components: - ... - securitySchemes: - ... - - metavariable-regex: - metavariable: $VERSION - regex: 3.* - - pattern: "$SECURITY_SCHEME:\n ...\n type: apiKey\n ...\n in: query\n \n" - severity: WARNING - - id: yaml.openapi.security.use-of-basic-authentication.use-of-basic-authentication - languages: - - yaml - message: Basic authentication is considered weak and should be avoided. Use a different authentication scheme, such of OAuth2, OpenID Connect, or mTLS. - metadata: - category: security - confidence: HIGH - cwe: 'CWE-287: Improper Authentication' - impact: HIGH - likelihood: MEDIUM - owasp: - - A04:2021 Insecure Design - - A07:2021 Identification and Authentication Failures - references: - - https://cwe.mitre.org/data/definitions/287.html - - https://owasp.org/Top10/A04_2021-Insecure_Design/ - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ - subcategory: - - vuln - technology: - - openapi - patterns: - - pattern-inside: | - openapi: $VERSION - ... - components: - ... - securitySchemes: - ... - $SCHEME: - ... - - metavariable-regex: - metavariable: $VERSION - regex: 3.* - - pattern: | - type: http - ... - scheme: basic - severity: ERROR - - id: yaml.semgrep.duplicate-id.duplicate-id - languages: - - yaml - message: The 'id' field $X was used multiple times. The 'id' field needs to be unique. - metadata: - category: correctness - technology: - - semgrep - patterns: - - pattern-inside: 'rules: [..., $RULE, ...]' - - pattern-inside: | - ... - - id: $X - ... - ... - - id: $X - ... - ... - - pattern: | - id: $X - severity: ERROR - - id: yaml.semgrep.duplicate-pattern.duplicate-pattern - languages: - - yaml - message: Two identical pattern clauses were detected. This will cause Semgrep to run the same pattern twice. Remove one of the duplicate pattern clauses. - metadata: - category: correctness - technology: - - semgrep - patterns: - - pattern-inside: 'rules: [..., $RULE, ...]' - - pattern-inside: | - - pattern: $X - ... - - pattern: $X - ... - - pattern: | - pattern: $X - severity: ERROR - - id: yaml.semgrep.empty-message.empty-message - languages: - - yaml - message: This rule has an empty message field. Consider adding a message field that communicates why this rule is an issue and how to fix it. This will increase the chance that the finding gets addressed. - metadata: - category: correctness - technology: - - semgrep - patterns: - - pattern-inside: 'rules: [..., $RULE, ...]' - - pattern: | - message: "" - severity: WARNING - - fix: | - options: - interfile: true - metadata - id: yaml.semgrep.interfile-true-under-metadata-and-no-options.interfile-true-under-metadata-and-no-options - languages: - - yaml - message: '`interfile: true` should be under the `options` field, not the `metadata` field.' - patterns: - - pattern: | - rules: - - id: $ID - ... - $METADATA: - ... - $INTERFILE: true - ... - ... - - pattern-not-inside: | - rules: - - id: $ID - ... - options: - ... - ... - - metavariable-regex: - metavariable: $INTERFILE - regex: interfile - - metavariable-regex: - metavariable: $METADATA - regex: metadata - - focus-metavariable: $METADATA - severity: WARNING - - fix: | - interfile: true - $FIRST_OPT - id: yaml.semgrep.interfile-true-under-metadata-and-options-already-present.interfile-true-under-metadata-and-options-already-present - languages: - - yaml - message: '`interfile: true` should be under the `options` field, not the `metadata` field.' - patterns: - - pattern: | - rules: - - id: $ID - ... - $METADATA: - ... - $INTERFILE: true - ... - ... - - pattern-inside: | - rules: - - id: $ID - ... - $OPTIONS: - $FIRST_OPT: $VAL - ... - ... - - pattern-not-inside: | - rules: - - id: $ID - ... - $OPTIONS: - ... - interfile: true - ... - ... - - metavariable-regex: - metavariable: $INTERFILE - regex: interfile - - metavariable-regex: - metavariable: $METADATA - regex: metadata - - metavariable-regex: - metavariable: $OPTIONS - regex: options - - focus-metavariable: $FIRST_OPT - severity: WARNING - - id: yaml.semgrep.key-indentation.yaml-key-indentation-check - languages: - - yaml - message: 'It looks like you have an YAML indentation issue -- instead of writing `$KEY`, put a space between the hyphen and what comes after! Otherwise, it reads as a single string. ' - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository - technology: - - semgrep - pattern-either: - - patterns: - - pattern-inside: | - rules: ... - - pattern: | - $KEY: >- - $VALUE - - focus-metavariable: $KEY - - metavariable-regex: - metavariable: $KEY - regex: ^-(\w*)$ - severity: WARNING - - fix-regex: - regex: (?<=\S)\s(\s{1,}) - replacement: ' ' - id: yaml.semgrep.message-whitespace.message-whitespace-check - languages: - - yaml - message: It looks like you have an additional space in your rule message, this can look awkward in the finding output, please remove the additional whitespace! - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository - technology: - - semgrep - patterns: - - pattern-inside: | - rules: ... - - pattern: | - message: >- - $VALUE - - focus-metavariable: - - $VALUE - - pattern-regex: \w.* - - pattern-regex: \s{2,} - severity: WARNING - - id: yaml.semgrep.metadata-category.metadata-category - languages: - - yaml - message: This Semgrep rule is missing a valid 'category' field in the 'metadata'. 'category' must be one of 'security', 'correctness', 'best-practice', 'performance', 'maintainability', or 'portability'. - metadata: - category: best-practice - technology: - - semgrep - patterns: - - pattern-inside: 'rules: [..., $RULE, ...]' - - pattern: 'id: $RULEID' - - pattern-not-inside: | - - ... - metadata: - ... - category: $CATEGORY - severity: INFO - - id: yaml.semgrep.metadata-confidence-incorrect-value.metadata-confidence-incorrect-value - languages: - - yaml - message: 'Semgrep rule confidence: $VALUE detected, but the value must be LOW, MEDIUM, or HIGH. For more information visit: https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/' - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ - technology: - - semgrep - patterns: - - pattern-inside: "rules: \n ...\n" - - pattern-inside: "metadata: \n ...\n category: security\n ...\n" - - pattern: | - confidence: $VALUE - - pattern-not: | - confidence: LOW - - pattern-not: | - confidence: MEDIUM - - pattern-not: | - confidence: HIGH - severity: WARNING - - id: yaml.semgrep.metadata-confidence.metadata-confidence - languages: - - yaml - message: This Semgrep rule is missing a valid 'confidence' field in the 'metadata'. which should be either LOW, MEDIUM, or HIGH. For more information visit https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository - technology: - - semgrep - patterns: - - pattern-inside: "rules: \n ...\n" - - pattern-inside: "metadata: \n ...\n category: security\n ...\n" - - pattern-not-inside: "metadata: \n ...\n confidence: $VALUE\n" - severity: WARNING - - id: yaml.semgrep.metadata-cwe.metadata-cwe - languages: - - yaml - message: '$...CWE The cwe tag in rule metadata should always be in the format "CWE-000: Title".' - metadata: - category: best-practice - technology: - - semgrep - patterns: - - pattern-inside: 'rules: ...' - - pattern-inside: 'metadata: ...' - - pattern: 'cwe: ...' - - pattern-not-regex: CWE-[\d]+:\s+\w - severity: ERROR - - fix-regex: - regex: deepsemgrep - replacement: interfile - id: yaml.semgrep.metadata-deepsemgrep.metadata-deepsemgrep - languages: - - yaml - message: 'We no longer support `deepsemgrep: true`, please use `interfile:true`' - metadata: - category: correctness - references: - - https://semgrep.dev/ - technology: - - semgrep - patterns: - - pattern-inside: "rules: \n ...\n" - - pattern-inside: "metadata: \n ...\n $DEEPSEMGREP: true\n ...\n" - - focus-metavariable: $DEEPSEMGREP - - metavariable-regex: - metavariable: $DEEPSEMGREP - regex: ^(deepsemgrep)$ - severity: WARNING - - id: yaml.semgrep.metadata-impact-incorrect-value.metadata-impact-incorrect-value - languages: - - yaml - message: 'Semgrep rule impact: $VALUE detected, but the value must be LOW, MEDIUM, or HIGH. For more information visit: https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/' - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ - technology: - - semgrep - patterns: - - pattern-inside: "rules: \n ...\n" - - pattern-inside: "metadata: \n ...\n category: security\n ...\n" - - pattern: | - impact: $VALUE - - pattern-not: | - impact: LOW - - pattern-not: | - impact: MEDIUM - - pattern-not: | - impact: HIGH - severity: WARNING - - id: yaml.semgrep.metadata-impact.metadata-impact - languages: - - yaml - message: This Semgrep rule is missing a valid 'impact' field in the 'metadata'. which should be either LOW, MEDIUM, or HIGH. For more information visit https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ - metadata: - category: correctness - references: - - https://semgrep.dev/docs/writing-rules/rule-syntax/#TODO - technology: - - semgrep - patterns: - - pattern-inside: "rules: \n ...\n" - - pattern-inside: "metadata: \n ...\n category: security\n ...\n" - - pattern-not-inside: "metadata: \n ...\n impact: $VALUE\n" - severity: WARNING - - id: yaml.semgrep.metadata-incorrect-option.metadata-incorrect-option - languages: - - yaml - message: It looks like $KEY is not in the default list of expected options, if this is a new key update this rule - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository - technology: - - semgrep - patterns: - - pattern-inside: | - rules: ... - - pattern-inside: | - options: - $A - - focus-metavariable: $A - - pattern: | - $KEY: $VALUE - - metavariable-regex: - metavariable: $KEY - regex: (?!options|constant_propagation|symbolic_propagation|taint_unify_mvars|taint_assume_safe_functions|taint_assume_safe_indexes|taint_assume_safe_comparisons|taint_assume_safe_booleans|taint_assume_safe_numbers|ac_matching|commutative_boolop|flddef_assign|arrow_is_function|let_is_var|go_deeper_expr|go_deeper_stmt|implicit_deep_exprstmt|implicit_ellipsis|xml_singleton_loose_matching|xml_attrs_implicit_ellipsis|xml_children_ordered|generic_engine|generic_multiline|generic_braces|generic_extra_braces|generic_extra_word_characters|generic_caseless|generic_ellipsis_max_span|generic_comment_style|interfile|generic_engine|commutative_compop|taint_focus_on) - severity: INFO - - id: yaml.semgrep.metadata-likelihood-incorrect-value.metadata-likelihood-incorrect-value - languages: - - yaml - message: 'Semgrep rule likelihood: $VALUE detected, but the value must be LOW, MEDIUM, or HIGH. For more information visit: https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/' - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ - technology: - - semgrep - patterns: - - pattern-inside: "rules: \n ...\n" - - pattern-inside: "metadata: \n ...\n category: security\n ...\n" - - pattern: | - likelihood: $VALUE - - pattern-not: | - likelihood: LOW - - pattern-not: | - likelihood: MEDIUM - - pattern-not: | - likelihood: HIGH - severity: WARNING - - id: yaml.semgrep.metadata-likelihood.metadata-likelihood - languages: - - yaml - message: This Semgrep rule is missing a valid 'likelihood' field in the 'metadata'. which should be either LOW, MEDIUM, or HIGH. For more information visit https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ - technology: - - semgrep - patterns: - - pattern-inside: "rules: \n ...\n" - - pattern-inside: "metadata: \n ...\n category: security\n ...\n" - - pattern-not-inside: "metadata: \n ...\n likelihood: $VALUE\n" - severity: WARNING - - id: yaml.semgrep.metadata-owasp.metadata-owasp - languages: - - json - - yaml - message: The `owasp` tag in Semgrep rule metadata should start with the format "A00:YYYY", where A00 is the OWASP top ten number and YYYY is the OWASP top ten year. - metadata: - category: best-practice - technology: - - semgrep - patterns: - - pattern-inside: 'rules: ...' - - pattern-inside: 'metadata: ...' - - pattern-either: - - patterns: - - pattern: 'owasp: "..."' - - pattern-not: 'owasp: "=~/^A(0?[1-9]|10):\s+.+$/"' - - pattern-not: 'owasp: "=~/^A(0[1-9]|10):([0-9]{4})?\s+.+$/"' - - patterns: - - pattern-inside: 'owasp: [...]' - - pattern: '"$ANYTHING"' - - pattern-not-regex: .*A(0[1-9]|10):[0-9]{4}\s+.* - - pattern-not-regex: 'owasp:' - severity: ERROR - - id: yaml.semgrep.metadata-references.metadata-references - languages: - - json - - yaml - message: The references in rule metadata should always be a list, even if there's only one. - metadata: - category: correctness - technology: - - semgrep - patterns: - - pattern-inside: | - rules: ... - - pattern-inside: | - metadata: ... - - pattern: | - references: ... - - pattern-not: | - references: [...] - severity: ERROR - - id: yaml.semgrep.metadata-subcategory-incorrect-value.metadata-subcategory-incorrect-value - languages: - - yaml - message: 'Semgrep rule likelihood: $VALUE detected, but the value must be vuln, audit, or guardrail. For more information visit: https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/' - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ - technology: - - semgrep - patterns: - - pattern-inside: "rules: \n ...\n" - - pattern-inside: "metadata: \n ...\n category: security\n ...\n" - - pattern: "subcategory: \n - $VALUE\n" - - pattern-not: "subcategory: \n - vuln\n" - - pattern-not: "subcategory: \n - audit\n" - - pattern-not: "subcategory: \n - guardrail\n" - severity: WARNING - - id: yaml.semgrep.metadata-subcategory.metadata-subcategory - languages: - - yaml - message: This Semgrep rule is missing a valid 'subcategory' field in the 'metadata'. which should be either audit, vuln, or guardrail. For more information visit https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/ - technology: - - semgrep - patterns: - - pattern-inside: "rules: \n ...\n" - - pattern-inside: "metadata: \n ...\n category: security\n ...\n" - - pattern-not-inside: "metadata: \n ...\n subcategory: $VALUE\n" - severity: WARNING - - id: yaml.semgrep.metadata-technology.metadata-technology - languages: - - yaml - message: This Semgrep rule is missing a 'technology' field in the 'metadata'. Consider adding a list of technologies based on the rule's associated library or framework, or another piece of relevant information. - metadata: - category: best-practice - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository/#technology - technology: - - semgrep - pattern-either: - - patterns: - - pattern-not-inside: | - - ... - mode: join - - pattern-inside: 'rules: [..., $RULE, ...]' - - pattern: $RULE - - pattern: | - id: ... - ... - - pattern-not: | - id: ... - ... - metadata: - ... - technology: - - ... - - patterns: - - pattern-inside: | - id: $OUTER_RULEID - mode: join - join: - rules: [ ..., $INNER_RULE, ...] - ... - ... - - pattern-not: | - id: $OUTER_RULEID - ... - metadata: - ... - technology: - - ... - severity: INFO - - id: yaml.semgrep.missing-language-field.missing-language-field - languages: - - yaml - message: Please include a 'languages' field for your rule $RULEID! - metadata: - category: correctness - references: - - https://semgrep.dev/docs/writing-rules/rule-syntax/#required - technology: - - semgrep - pattern-either: - - patterns: - - pattern-inside: 'rules: [..., $RULE, ...]' - - pattern: 'id: $RULEID' - - pattern-not-inside: | - - ... - languages: ... - - pattern-not-inside: | - - ... - mode: join - - patterns: - - pattern-inside: | - rules: [ ..., $OUTER_RULE, ...] - - pattern-inside: $OUTER_RULE - - pattern-inside: | - id: $OUTER_RULEID - mode: join - join: - rules: [ ..., $INNER_RULE, ...] - ... - ... - - pattern-inside: $INNER_RULE - - pattern-not-inside: | - - languages: ... - ... - - pattern: | - id: $RULEID - severity: WARNING - - id: yaml.semgrep.missing-message-field.missing-message-field - languages: - - yaml - message: This rule does not have a message. Semgrep requires that rules have a message. Include a message to explain what the rule does. Consider writing a message that explains why this is an issue and how to fix it. - metadata: - category: correctness - references: - - https://semgrep.dev/docs/writing-rules/rule-syntax/ - technology: - - semgrep - patterns: - - pattern-inside: 'rules: [..., $RULE, ...]' - - pattern: 'id: $RULEID' - - pattern-not-inside: | - - ... - message: ... - - pattern-not-inside: | - - ... - mode: extract - severity: WARNING - - id: yaml.semgrep.multi-line-message.multi-line-message - languages: - - yaml - message: 'This rule has a multi-line message field, which may display poorly in a terminal. Consider ensuring it is on one line. For example, use `message: >-`, not `message: |`.' - metadata: - category: correctness - references: - - https://github.com/returntocorp/semgrep-rules/issues/1431 - technology: - - semgrep - patterns: - - pattern-inside: 'rules: [..., $RULE, ...]' - - pattern: | - message: "=~/[\\n\\r]/" - severity: WARNING - - id: yaml.semgrep.rule-missing-deconstructed-value.missing-deconstructed-value - languages: - - yaml - message: Looks like this value is deconstructing a const/var/let you need to use all three `const {...} =` `var {...} =` and `let {...} =` to provide accurate coverage consider adding the missing patterns in a `pattern-inside` for better coverage. - metadata: - category: correctness - references: - - https://semgrep.dev/docs/contributing/contributing-to-semgrep-rules-repository - technology: - - semgrep - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - rules: ... - - pattern-not-inside: | - - pattern-either: - ... - - pattern: | - - pattern-inside: - $VALUE - - pattern-either: - - pattern-regex: const {.*}.*= - - pattern-regex: let {.*}.*= - - pattern-regex: var {.*}.*= - - patterns: - - patterns: - - pattern-inside: | - rules: ... - - pattern-inside: | - - pattern-either: - $VALUE - - focus-metavariable: - - $VALUE - - pattern-inside: "- pattern-inside: \n $A\n" - - metavariable-regex: - metavariable: $A - regex: .*\s.*(var|const|let)\s{.*}\s= - - pattern-not: - patterns: - - pattern-inside: "...\n- pattern-inside: \n $Z\n...\n- pattern-inside: \n $B\n... \n- pattern-inside: \n $C\n...\n" - - metavariable-regex: - metavariable: $Z - regex: .*\s.*(var|const|let).*{.*} - - metavariable-regex: - metavariable: $B - regex: .*\s.*(var|const|let).*{.*} - - metavariable-regex: - metavariable: $C - regex: .*\s.*(var|const|let).*{.*} - severity: WARNING - - id: yaml.semgrep.slow-pattern-general-function.slow-pattern-general-func - languages: - - yaml - message: Using patterns like `function (...) {...}` is too general it will probably slow down the rule performance. - metadata: - category: performance - technology: - - semgrep - patterns: - - pattern-either: - - pattern-inside: | - pattern-inside: $X - - pattern-inside: | - pattern-not-inside: $X - - pattern-inside: | - pattern: $X - - pattern-inside: | - pattern-not: $X - - pattern-regex: function[^{]*{[\s\n]*\.\.\.[\s\n]*} - - pattern-either: - - pattern-inside: | - languages: [...,"javascript",...] - ... - - pattern-inside: | - languages: [...,"typescript",...] - ... - severity: WARNING - - id: yaml.semgrep.slow-pattern-general-property.slow-pattern-general-property - languages: - - yaml - message: Using patterns like `$X.$Y` may be too general and may slow down the rule performance. - metadata: - category: performance - technology: - - semgrep - patterns: - - pattern-either: - - pattern-inside: | - pattern-inside: $X - - pattern-inside: | - pattern-not-inside: $X - - pattern-inside: | - pattern: $X - - pattern-inside: | - pattern-not: $X - - pattern-regex: \$[A-Z]*\.\$[A-Z]* - severity: WARNING - - id: yaml.semgrep.slow-pattern-single-metavariable.slow-pattern-single-metavariable - languages: - - yaml - message: Using a single metavariable as a pattern drastically slows down the rule performance because it will match every expression in a file. Instead, try to match something specific such as a function name, or anchor on a statement that may occur above or below the pattern. The more specific you can be, the faster the pattern will run. - metadata: - category: performance - technology: - - semgrep - patterns: - - pattern-either: - - pattern-inside: | - pattern-inside: $PATTERN - - pattern-inside: | - pattern-not-inside: $PATTERN - - pattern-inside: | - pattern: $PATTERN - - pattern-inside: | - pattern-not: $PATTERN - - metavariable-regex: - metavariable: $PATTERN - regex: \$[A-Z_]* - severity: WARNING - - id: yaml.semgrep.slow-pattern-top-ellipsis.slow-pattern-top-ellipsis - languages: - - yaml - message: Using the ellipsis operator `...` at the top of the pattern drastically slows down the rule performance. - metadata: - category: performance - technology: - - semgrep - patterns: - - pattern-either: - - pattern-inside: | - pattern-inside: $X - - pattern-inside: | - pattern-not-inside: $X - - pattern-inside: | - pattern: $X - - pattern-inside: | - pattern-not: $X - - pattern-regex: \|\s*\n\s*\.\.\.\s*\n[^\n]*\n\s*\.\.\. - severity: WARNING - - id: yaml.semgrep.unnecessary-parent.unnecessary-parent-operator - languages: - - yaml - message: Unnecessary parent operator. Remove one to fix. - metadata: - category: best-practice - technology: - - semgrep - patterns: - - pattern-inside: 'rules: [..., $RULE, ...]' - - pattern-either: - - patterns: - - pattern: | - pattern-either: - - $THING1 - - ... - - pattern-not: | - pattern-either: - - $THING1 - - $THING2 - - ... - - patterns: - - pattern: | - patterns: - - $THING1 - - ... - - pattern-not: | - patterns: - - $THING1 - - $THING2 - - ... - - pattern: | - pattern-either: - - ... - - pattern-either: - - ... - severity: WARNING - - id: yaml.semgrep.unsatisfiable.unsatisfiable-rule - languages: - - yaml - message: You can not use 'pattern' $A and 'pattern-not' $A together; this will always be empty. - metadata: - category: correctness - technology: - - semgrep - patterns: - - pattern-inside: 'patterns: [...]' - - pattern-either: - - patterns: - - pattern-inside: | - - pattern: $A - ... - - pattern: | - - pattern-not: $A - - patterns: - - pattern-inside: | - - pattern-not: $A - ... - - pattern: | - - pattern: $A - severity: ERROR - - id: c_access_rule-RpcImpersonateClient-ImpersonateLoggedOnUser - languages: - - c - - cpp - - cpp - message: | - These functions may be used to either drop or change account privileges. If the calls - fail, the process will continue to run with the privileges assigned to it on start. Depending - on - the logic of the application, this may allow attackers to abuse the system due to privileges - never - being changed to a different access level. - - Always ensure return values of this function are checked to determine if the application should - continue to operate. - metadata: - category: security - cwe: CWE-250 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: High - shortDescription: Ensure return values are checked when attempting to drop privileges - pattern-either: - - pattern: RpcImpersonateClient(...) - - pattern: ImpersonateLoggedOnUser(...) - - pattern: CoImpersonateClient(...) - - pattern: ImpersonateNamedPipeClient(...) - - pattern: ImpersonateDdeClientWindow(...) - - pattern: ImpersonateSecurityContext(...) - - pattern: SetThreadToken(...) - severity: ERROR - - id: c_access_rule-umask - languages: - - c - - cpp - - cpp - message: | - The umask function call sets the process's file mode creation mask. umask values determine - what permissions a file should be created with and who can read or write to these files. - Ensure that umask is given most restrictive possible setting depending on the context, - usually 066 or 077, for more information please see: - https://en.wikipedia.org/wiki/Umask#Mask_effect. - metadata: - category: security - cwe: CWE-732 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: High - shortDescription: Ensure restrictive umask values - pattern: umask(...) - severity: INFO - - id: c_buffer_rule-MultiByteToWideChar - languages: - - c - - cpp - - cpp - message: | - The input buffer is the number of bytes in the string, but the size - of the output buffer is the number of characters. To avoid overflows, the - application must determine the correct buffer size which depends on the data type - the buffer receives. - - For more information see: - https://learn.microsoft.com/en-us/windows/win32/intl/security-considerations--international-features - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Easily misused function may lead to buffer overflows - pattern: MultiByteToWideChar(...) - severity: INFO - - id: c_buffer_rule-StrCat-StrCatA - languages: - - c - - cpp - - cpp - message: | - The `StrCat` family of functions do not guarantee the final string to be null terminated. - Consider using one of the following alternatives: `StringCbCat`, `StringCbCatEx`, - `StringCbCatN`, `StringCbCatNEx`, `StringCchCat`, `StringCchCatEx`, `StringCchCatN`, or - `StringCchCatNEx`. - - For more information please see: https://learn.microsoft.com/en-us/windows/win32/api/strsafe/ - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure string processing function - pattern-either: - - pattern: strcat(...) - - pattern: strcatA(...) - - pattern: StrcatW(...) - - pattern: lstrcatA(...) - - pattern: lstrcatW(...) - - pattern: strCatBuff(...) - - pattern: StrCatBuffA(...) - - pattern: StrCatBuffW(...) - - pattern: StrCatChainW(...) - - pattern: _tccat(...) - - pattern: _mbccat(...) - - pattern: _ftcscat(...) - - pattern: StrCatN(...) - - pattern: StrCatNA(...) - - pattern: StrCatNW(...) - - pattern: StrNCat(...) - - pattern: StrNCatA(...) - - pattern: StrNCatW(...) - - pattern: lstrncat(...) - - pattern: lstrcatnA(...) - - pattern: lstrcatnW(...) - severity: ERROR - - id: c_buffer_rule-fscanf-sscanf - languages: - - c - - cpp - - cpp - message: | - Format specifiers can take optional field widths, which should be - used to limit how many characters are copied into the target buffer. - - Example: - ``` - const char str[20] = "AAAAAAAAAAAAAAAAAAA"; - char buf[11] = {0}; - sscanf(str, "%10s", &buf); // buf = AAAAAAAAAA\0 - ``` - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: sscanf() functions may allow format string based overflows - pattern-either: - - pattern: fscanf(...) - - pattern: sscanf(...) - - pattern: vsscanf(...) - - pattern: vfscanf(...) - - pattern: _ftscanf(...) - - pattern: fwscanf(...) - - pattern: vfwscanf(...) - - pattern: vswscanf(...) - severity: ERROR - - id: c_buffer_rule-g-get-home-dir - languages: - - c - - cpp - - cpp - message: | - This function is synonymous with `getenv("HOME")` and should be treated - as untrusted input as it could be modified by an attacker. Possible risks - include: - - - The value being too large and causing buffer overflows - - Files under the attacker's control being used maliciously - - Files outside of an attacker's control becoming accessible, depending on - access privileges. - metadata: - category: security - cwe: CWE-807 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Reliance on untrusted inputs in a security decision - pattern: g_get_home_dir(...) - severity: WARNING - - id: c_buffer_rule-g-get-tmp-dir - languages: - - c - - cpp - - cpp - message: | - This function is synonymous with `getenv("TMP")` and should be treated - as untrusted input as it could be modified by an attacker. Possible risks - include: - - - The value being too large and causing buffer overflows - - Files under the attacker's control being used maliciously - - Files outside of an attacker's control becoming accessible, depending on - access privileges. - metadata: - category: security - cwe: CWE-807 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Reliance on untrusted inputs in a security decision - pattern: g_get_tmp_dir(...) - severity: WARNING - - id: c_buffer_rule-getenv-curl-getenv - languages: - - c - - cpp - - cpp - message: | - This function's return value should be treated as untrusted input as it could be - modified by an attacker. Possible risks include: - - - The value being too large and causing buffer overflows - - Files under the attacker's control being used maliciously - - Files outside of an attacker's control becoming accessible, depending on - access privileges. - metadata: - category: security - cwe: CWE-807 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Reliance on untrusted inputs in a security decision - pattern-either: - - pattern: getenv(...) - - pattern: curl_getenv(...) - severity: WARNING - - id: c_buffer_rule-gets--getts - languages: - - c - - cpp - - cpp - message: | - The gets() function reads a line from stdin into the provided buffer - until either a terminating newline or EOF. This terminating newline or - EOF is replaced with a null byte `'\0'`. No check for buffer overruns are - performed so it is recommended to use `fgets()` instead. Do note - that some platforms will continue reading data after a `'\0'` is encountered. - - Usage of `fgets()` is not recommended for reading binary based files or inputs, - instead the `read` or `fread` functions should be used. - - For more information please see: https://linux.die.net/man/3/fgets - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Use of deprecated function (gets) - pattern-either: - - pattern: gets(...) - - pattern: _getts(...) - - pattern: _getws(...) - severity: ERROR - - id: c_buffer_rule-getwd - languages: - - c - - cpp - - cpp - message: | - `getwd` does not contain a parameter to limit how many characters can be copied into the - destination buffer. For portability and security reasons `getwd` has been deprecated in - favor of `getcwd`. - - For more information please see: https://linux.die.net/man/3/getcwd - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insufficient protection against buffer overflow (getwd) - pattern: getwd(...) - severity: WARNING - - id: c_buffer_rule-lstrcat-wcscat - languages: - - c - - cpp - - cpp - message: | - The `strcat` family of functions are unable to limit how many bytes are copied - to the destination buffer. It is recommended to use more secure alternatives such as - `snprintf`. - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strcat-s-wcscat-s-mbscat-s?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure functions unable to limit / check buffer sizes - pattern-either: - - pattern: lstrcat(...) - - pattern: wcscat(...) - - pattern: _tcscat(...) - - pattern: _mbscat(...) - severity: ERROR - - id: c_buffer_rule-lstrcatn-wcsncat - languages: - - c - - cpp - - cpp - message: | - Consider using more secure alternatives such as `snprintf`, instead of the - `wcsncat` family of functions. - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncat-strncat-l-wcsncat-wcsncat-l-mbsncat-mbsncat-l?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Easily misused string processing functions - pattern-either: - - pattern: lstrcatn(...) - - pattern: wcsncat(...) - - pattern: _tcsncat(...) - - pattern: _mbsnbcat(...) - severity: INFO - - id: c_buffer_rule-lstrcpy-wcscpy - languages: - - c - - cpp - - cpp - message: | - The `lstrcpy` family of functions do not provide the ability to limit or check buffer - sizes before copying to a destination buffer. This can lead to buffer overflows. Consider - using more secure alternatives such as `strncpy_s`. - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-s-strncpy-s-l-wcsncpy-s-wcsncpy-s-l-mbsncpy-s-mbsncpy-s-l?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure functions unable to limit / check buffer sizes - pattern-either: - - pattern: lstrcpy(...) - - pattern: wcscpy(...) - - pattern: _tcscpy(...) - - pattern: _mbscpy(...) - severity: ERROR - - id: c_buffer_rule-lstrcpyn-wcsncpy - languages: - - c - - cpp - - cpp - message: | - The `lstrcpyn` family of functions do not always check for invalid pointers or check if there - is sufficient space prior to copying. The count argument limits the number of characters copied - but does validate if the count will fit within the size of the destination buffer, leading to - potential overflows. - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-s-strncpy-s-l-wcsncpy-s-wcsncpy-s-l-mbsncpy-s-mbsncpy-s-l?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure functions do not always null terminate or check invalid pointers - pattern-either: - - pattern: lstrcpyn(...) - - pattern: wcsncpy(...) - - pattern: _tcsncpy(...) - - pattern: _mbsnbcpy(...) - severity: INFO - - id: c_buffer_rule-memcpy-CopyMemory - languages: - - c - - cpp - - cpp - message: | - The `memcpy` family of functions require the developer to validate that the destination buffer - is the same size or larger than the source buffer. Buffer overflows could be introduced if care - is not taken to validate buffer sizes. - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/memcpy-s-wmemcpy-s?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Function does not check for buffer overflows when copying - pattern-either: - - pattern: memcpy(...) - - pattern: CopyMemory(...) - - pattern: bcopy(...) - severity: INFO - - id: c_buffer_rule-realpath - languages: - - c - - cpp - - cpp - message: | - The `realpath` function should not be called with a destination buffer as it could - lead to overflowing if the path is greater than PATH_LEN. It is instead recommended - to call `realpath` with the destination buffer set to NULL and use the return value - as the resolved path. Be sure to free the returned pointer as realpath will allocate - the buffer internally using `malloc`. - - For more information see: https://linux.die.net/man/3/realpath - - Example: - - ``` - char const *symlink_path = "/tmp/symlink"; - char *resolved_path = NULL; - - resolved_path = realpath(symlink_path, NULL); - if (errno == 0) { - // ... use resolved_path... - free(resolved_path); - } - ``` - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Function does not ensure destination buffer length is sufficient before copying - pattern: realpath(...) - severity: WARNING - - id: c_buffer_rule-scanf-vscanf - languages: - - c - - cpp - - cpp - message: | - Format specifiers can take optional field widths, which should be - used to limit how many characters are copied into the target buffer. - - For more information please see: https://linux.die.net/man/3/scanf - - Example: - ``` - char buf[11] = {0}; - scanf("%10s", &buf); // buf = AAAAAAAAAA\0 - ``` - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/scanf-s-scanf-s-l-wscanf-s-wscanf-s-l?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: scanf() functions may allow format string based overflows - pattern-either: - - patterns: - - pattern: scanf($FMT, ...) - - pattern-not: scanf("...", ...) - - patterns: - - pattern: vscanf($FMT, ...) - - pattern-not: vscanf("...", ...) - - patterns: - - pattern: wscanf($FMT, ...) - - pattern-not: wscanf("...", ...) - - patterns: - - pattern: _tscanf($FMT, ...) - - pattern-not: _tscanf(_T("..."), ...) - - patterns: - - pattern: vwscanf(FMT, ...) - - pattern-not: vwscanf("...", ...) - severity: ERROR - - id: c_buffer_rule-sprintf-vsprintf - languages: - - c - - cpp - - cpp - message: | - Use sprintf_s, snprintf, or vsnprintf instead. The `sprintf` family of functions do not allow - callers to set limits on how many bytes the destination buffer can hold. Consider using more - secure alternatives such as `snprintf`. - - For more information please see: https://linux.die.net/man/3/snprintf - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/sprintf-s-sprintf-s-l-swprintf-s-swprintf-s-l?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure function unable to limit / check buffer sizes - pattern-either: - - pattern: sprintf(...) - - pattern: vsprintf(...) - - pattern: swprintf(...) - - pattern: vswprintf(...) - - pattern: _stprintf(...) - - pattern: _vstprintf(...) - severity: ERROR - - id: c_buffer_rule-strcat - languages: - - c - - cpp - - cpp - message: | - The `strcat` family of functions are unable to limit how many bytes are copied - to the destination buffer. It is recommended to use more secure alternatives such as - `snprintf`. - - For more information please see: https://linux.die.net/man/3/snprintf - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strcat-s-wcscat-s-mbscat-s?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure string processing function - pattern: strcat(...) - severity: ERROR - - id: c_buffer_rule-strccpy-strcadd - languages: - - c - - cpp - - cpp - message: | - The `strccpy` and `strcadd` functions do not allow the caller to check that the destination - size - of the buffer will fit the input buffer prior to copying. - - For more information please see: - https://docs.oracle.com/cd/E18752_01/html/816-5172/streadd-3gen.html - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure string processing functions - pattern-either: - - pattern: strccpy(...) - - pattern: strcadd(...) - severity: INFO - - id: c_buffer_rule-strcpy - languages: - - c - - cpp - - cpp - message: | - The `strcpy` family of functions do not provide the ability to limit or check buffer - sizes before copying to a destination buffer. This can lead to buffer overflows. Consider - using more secure alternatives such as `strncpy` and provide the correct limit to the - destination buffer and ensure the string is null terminated. - - For more information please see: https://linux.die.net/man/3/strncpy - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-s-strncpy-s-l-wcsncpy-s-wcsncpy-s-l-mbsncpy-s-mbsncpy-s-l?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure string processing function (strcpy) - pattern: strcpy(...) - severity: ERROR - - id: c_buffer_rule-strcpyA-strcpyW - languages: - - c - - cpp - - cpp - message: | - The `StrCpy` family of functions do not guarantee the final string to be null terminated. - Consider - using one of the following alternatives `StringCbCopy`, `StringCbCopyEx`, `StringCbCopyN`, - `StringCbCopyNEx`, `StringCchCopy`, `StringCchCopyEx`, `StringCchCopyN`, or `StringCchCopyNEx`. - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-s-strncpy-s-l-wcsncpy-s-wcsncpy-s-l-mbsncpy-s-mbsncpy-s-l?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure string processing function - pattern-either: - - pattern: strcpyA(...) - - pattern: strcpyW(...) - - pattern: StrCpy(...) - - pattern: StrCpyA(...) - - pattern: lstrcpyA(...) - - pattern: lstrcpyW(...) - - pattern: _tccpy(...) - - pattern: _mbccpy(...) - - pattern: _ftcscpy(...) - - pattern: _mbsncpy(...) - - pattern: StrCpyN(...) - - pattern: StrCpyNA(...) - - pattern: StrCpyNW(...) - - pattern: StrNCpy(...) - - pattern: strcpynA(...) - - pattern: StrNCpyA(...) - - pattern: StrNCpyW(...) - - pattern: lstrcpynA(...) - - pattern: lstrcpynW(...) - severity: ERROR - - id: c_buffer_rule-streadd-strecpy - languages: - - c - - cpp - - cpp - message: | - The `strecpy` and `streadd` functions require that the destination buffer size be at least - four - times the size of the source due to each character potentially becoming a `\` and 3 digits. - - For more information please see: - https://docs.oracle.com/cd/E18752_01/html/816-5172/streadd-3gen.html - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure string processing functions - pattern-either: - - pattern: streadd(...) - - pattern: strecpy(...) - severity: ERROR - - id: c_buffer_rule-strlen-wcslen - languages: - - c - - cpp - - cpp - message: | - The `strlen` family of functions does not handle strings that are not null - terminated. This can lead to buffer over reads and cause the application to - crash by accessing unintended memory locations. It is recommended that `strnlen` - be used instead as a `maxlen` value can be provided. - - For more information please see: https://linux.die.net/man/3/strnlen - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strnlen-strnlen-s?view=msvc-170 - metadata: - category: security - cwe: CWE-126 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Function does not handle null terminated strings properly - pattern-either: - - pattern: strlen(...) - - pattern: wcslen(...) - - pattern: _tcslen(...) - - pattern: _mbslen(...) - severity: INFO - - id: c_buffer_rule-strncat - languages: - - c - - cpp - - cpp - message: | - The `strncat` family of functions are easy to use incorrectly when calculating destination - buffer - sizes. It is recommended to use more secure alternatives such as `snprintf`. - - For more information please see: https://linux.die.net/man/3/snprintf - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncat-s-strncat-s-l-wcsncat-s-wcsncat-s-l-mbsncat-s-mbsncat-s-l?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Function does not handle null terminated strings or invalid pointers properly - pattern: strncat(...) - severity: INFO - - id: c_buffer_rule-strncpy - languages: - - c - - cpp - - cpp - message: | - The `strncpy` family of functions do not properly handle strings that are not null terminated. - It is recommended to use more secure alternatives such as `snprintf`. - - For more information please see: https://linux.die.net/man/3/snprintf - - If developing for C Runtime Library (CRT), more secure versions of these functions should be - used, see: - https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-s-strncpy-s-l-wcsncpy-s-wcsncpy-s-l-mbsncpy-s-mbsncpy-s-l?view=msvc-170 - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Function does not handle null terminated strings or invalid pointers properly - pattern: strncpy(...) - severity: INFO - - id: c_buffer_rule-strtrns - languages: - - c - - cpp - - cpp - message: | - This function is easy to misuse by not accounting for the space necessary when transforming - strings. Ensure that the destination buffer is large enough to fit the transformed output. - - For more information please see: - https://docs.oracle.com/cd/E36784_01/html/E36877/strtrns-3gen.html - metadata: - category: security - cwe: CWE-120 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Insecure string processing function - pattern: strtrns(...) - severity: WARNING - - id: c_crypto_rule-EVP-des-ecb-EVP-des-cbc - languages: - - c - - cpp - - cpp - message: | - The DES algorithm has not been recommended for over 15 years and was withdrawn from NIST (FIPS - 46-3) in 2005. - - Consider using libsodium's `crypto_secretbox_easy` authenticated encryption functions instead. - - For more information please see: - https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox. - - If you must be FIPS compliant, consider using OpenSSLs AES or 3DES ciphers. - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Insecure encryption algorithm (DES) - pattern-either: - - pattern: EVP_des_ecb(...) - - pattern: EVP_des_cbc(...) - - pattern: EVP_des_cfb(...) - - pattern: EVP_des_ofb(...) - - pattern: EVP_desx_cbc(...) - severity: ERROR - - id: c_crypto_rule-EVP-rc4-40-EVP-rc2-40-cbc - languages: - - c - - cpp - - cpp - message: | - The RC4 algorithm is vulnerable to many attacks and should no longer be used for encrypting - data streams. - - Consider using libsodium's `crypto_secretstream_xchacha20poly1305` stream cipher encryption - functions instead. For more information please see: - https://libsodium.gitbook.io/doc/secret-key_cryptography/secretstream - - If you must be FIPS compliant, consider using OpenSSLs AES or 3DES ciphers. - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Insecure stream cipher (RC4) - pattern-either: - - pattern: EVP_rc4_40(...) - - pattern: EVP_rc2_40_cbc(...) - - pattern: EVP_rc2_64_cbc(...) - severity: ERROR - - id: c_crypto_rule-crypt-crypt-r - languages: - - c - - cpp - - cpp - message: | - The crypt functions are not recommended due to the significantly small - key space. Modern hardware can crack crypt produced passwords relatively quickly. - - Consider using the Argon2id password hashing algorithm provided by libsodium. - For more information please see: https://libsodium.gitbook.io/doc/password_hashing. - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Insecure hashing algorithm - pattern-either: - - pattern: crypt(...) - - pattern: crypt_r(...) - severity: ERROR - - id: c_format_rule-fprintf-vfprintf - languages: - - c - - cpp - - cpp - message: | - Format string vulnerabilities allow an attacker to read or in some cases, - potentially write data to - and from locations in the processes' memory. To prevent against format - string attacks, do not allow - users or un-validated input to provide the format specification. - Consider using a constant for the format specification, or only allow specific - characters to be provided to the format argument for the `fprintf` family of functions. - - For more information please see: https://linux.die.net/man/3/fprintf - - For more information on format string attacks please see OWASP's attack - guide: https://owasp.org/www-community/attacks/Format_string_attack - metadata: - category: security - cwe: CWE-134 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Potential format string vulnerability - pattern-either: - - patterns: - - pattern: fprintf($FD, $FMT, ...) - - pattern-not: fprintf($FD, "...", ...) - - patterns: - - pattern: vfprintf($FMT, $ARGS, ...) - - pattern-not: vfprintf("...", $ARGS, ...) - - patterns: - - pattern: _ftprintf($FD, $FMT, ...) - - pattern-not: _ftprintf($FD, "...", ...) - - patterns: - - pattern: fwprintf($FD, $FMT, ...) - - pattern-not: fwprintf($FD, "...", ...) - - patterns: - - pattern: fvwprintf($FD, $FMT, ...) - - pattern-not: fvwprintf($FD, "...", ...) - severity: ERROR - - id: c_format_rule-printf-vprintf - languages: - - c - - cpp - - cpp - message: | - Format string vulnerabilities allow an attacker to read or in some cases, potentially write - data to - and from locations in the processes' memory. To prevent against format string attacks, do not - allow - users or un-validated input to provide the format specification. - Consider using a constant for the format specification, or only allow specific - characters to be provided to the format argument for the `printf` family of functions. - - For more information please see: https://linux.die.net/man/3/fprintf - - For more information on format string attacks please see OWASP's attack guide: - https://owasp.org/www-community/attacks/Format_string_attack - metadata: - category: security - cwe: CWE-134 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Potential format string vulnerability - pattern-either: - - patterns: - - pattern: printf(...) - - pattern-not: printf("...",...) - - patterns: - - pattern: vprintf($FMT, ...) - - pattern-not: vprintf("...", ...) - - patterns: - - pattern: vwprintf($FMT, ...) - - pattern-not: vwprintf("...", ...) - - patterns: - - pattern: vfwprintf($FILE, $FMT, ...) - - pattern-not: vfwprintf($FILE, "...", ...) - - patterns: - - pattern: _vtprintf($FILE, $FMT, ...) - - pattern-not: _vtprintf($FILE, "...", ...) - - patterns: - - pattern: wprintf($FMT, ...) - - pattern-not: wprintf("...", ...) - severity: ERROR - - id: c_format_rule-snprintf-vsnprintf - languages: - - c - - cpp - - cpp - message: | - Format string vulnerabilities allow an attacker to read or in some cases, potentially write - data to - and from locations in the processes' memory. To prevent against format string attacks, do not - allow - users or un-validated input to provide the format specification. - Consider using a constant for the format specification, or strip all format - specifiers from the input prior to calling the `snprintf` family of functions. - - Note that some variations of this function do not always null terminate the strings. - - For more information on using snprintf please see: https://linux.die.net/man/3/snprintf - - For more information on format string attacks please see OWASP's attack guide: - https://owasp.org/www-community/attacks/Format_string_attack - metadata: - category: security - cwe: CWE-134 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Potential format string vulnerability - pattern-either: - - patterns: - - pattern: snprintf($BUF,$SIZE,$FMT,...) - - pattern-not: snprintf($BUF,$SIZE,"...",...) - - patterns: - - pattern: vsnprintf($BUF,$SIZE,$FMT) - - pattern-not: vsnprintf($BUF,$SIZE,"...",...) - - patterns: - - pattern: _snprintf($BUF,$SIZE,$FMT,...) - - pattern-not: _snprintf($BUF,$SIZE,$FMT,"...",...) - - patterns: - - pattern: _sntprintf($VAR,$FMT,...) - - pattern-not: sntprintf($VAR,"...",...) - - patterns: - - pattern: _vsntprintf($VAR,$FMT,...) - - pattern-not: _vsntprintf($VAR,"...",...) - severity: ERROR - - id: c_format_rule-syslog - languages: - - c - - cpp - - cpp - message: | - Format string vulnerabilities allow an attacker to read or in some cases, potentially write - data to - and from locations in the processes' memory. To prevent against format string attacks, do not - allow - users or un-validated input to provide the format specification. - Consider using a constant for the format specification, or strip all format - specifiers from the input prior to calling the `syslog` function. - - For more information please see: https://capec.mitre.org/data/definitions/67.html - metadata: - category: security - cwe: CWE-134 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Potential format string vulnerability in syslog call - pattern-either: - - patterns: - - pattern: syslog($FUNC,...) - - pattern-not: syslog($FUNC,"...",...) - severity: ERROR - - id: c_free_rule-memalign - languages: - - c - - cpp - - cpp - message: | - The `memalign` function may not check that the alignment argument is correct. Calling - free (on non Linux-based systems) may fail and in certain circumstances this failure - may be exploitable. This function has been deprecated in favor of `posix_memalign`. - - For more information please see: https://linux.die.net/man/3/memalign - metadata: - category: security - cwe: CWE-676 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Use of deprecated function (memalign) - pattern-either: - - pattern: memalign(...) - - pattern-regex: (void)\s\*(\s|)(memalign)\; - severity: INFO - - id: c_integer_rule-atoi-atol - languages: - - c - - cpp - - cpp - message: | - The `atoi` family of functions can potentially overflow or underflow integer values. Consider - using `stroul` instead. - - For more information please see: - https://wiki.sei.cmu.edu/confluence/display/c/ERR34-C.+Detect+errors+when+converting+a+string+to+a+number - metadata: - category: security - cwe: CWE-190 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Possible integer overflow or underflow - pattern-either: - - pattern: atoi(...) - - pattern: atol(...) - - pattern: _wtoi(...) - - pattern: _wtoi64(...) - severity: INFO - - id: c_misc_rule-AddAccessAllowedAce - languages: - - c - - cpp - - cpp - message: | - Make sure that you set inheritance by hand if you wish it to inherit. - metadata: - category: security - cwe: CWE-732 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: High - shortDescription: This doesn't set the inheritance bits in the access control entry (ACE) header (CWE-732) - pattern: AddAccessAllowedAce(...) - severity: WARNING - - id: c_misc_rule-LoadLibrary - languages: - - c - - cpp - - cpp - message: | - The `LoadLibrary` function is used to load DLLs dynamically. Depending on the filepath - parameter, - the OS version, and the modes set for the process prior to calling LoadLibrary, DLL hijacking - may - be possible. Attackers can exploit this by placing DLL files with the same name in directories - that - are searched before the legitimate DLL is. - - To assist in preventing against this class of vulnerability consider: - - Specifying a fully qualified path when using LoadLibraryEx. - - Use the `LOAD_LIBRARY_SEARCH` flags with LoadLibraryEx or with SetDefaultDllDirectories. - - If you use SetDefaultDllDirectories, be sure to use the AddDllDirectory or SetDllDirectory - functions to modify the list of directories. - - Only use `SearchPath` if the `SetSearchPathMode` function is called with - `BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE`. (Note: this only moves the current directory to - the end of the SearchPath search list.) - - For more information see the security remarks section of the MSDN documentation: - https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya#security-remarks - - For general information securely loading dynamic link libraries, see the MSDN documentation: - https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-security - metadata: - category: security - cwe: CWE-427 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Uncontrolled search path element - pattern: LoadLibrary(...) - severity: WARNING - - id: c_misc_rule-LoadLibraryEx - languages: - - c - - cpp - - cpp - message: | - The `LoadLibraryEx` function is used to load DLLs dynamically. Depending on the filepath - parameter, - the OS version, and the modes set for the process prior to calling LoadLibrary, DLL hijacking - may - be possible. Attackers can exploit this by placing DLL files with the same name in directories - that - are searched before the legitimate DLL is. - - To assist in preventing against this class of vulnerability consider: - - Specifying a fully qualified path when using LoadLibraryEx. - - Use the `LOAD_LIBRARY_SEARCH` flags with LoadLibraryEx or with SetDefaultDllDirectories. - - If you use SetDefaultDllDirectories, be sure to use the AddDllDirectory or SetDllDirectory - functions to modify the list of directories. - - Only use `SearchPath` if the `SetSearchPathMode` function is called with - `BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE`. (Note: this only moves the current directory to - the end of the SearchPath search list.) - - For more information see the security remarks section of the MSDN documentation: - https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya#security-remarks - - For general information securely loading dynamic link libraries, see the MSDN documentation: - https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-security - metadata: - category: security - cwe: CWE-427 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Uncontrolled search path element - pattern: LoadLibraryEx(...) - severity: WARNING - - id: c_misc_rule-SetSecurityDescriptorDacl - languages: - - c - - cpp - - cpp - message: | - When `SetSecurityDescriptorDacl` is called with a null `pDacl` parameter and the - `bDaclPresent` flag is `TRUE`, all access to the object is allowed. An attacker - could set the object to Deny all, which would include even the Administrator user(s). - - Either call `SetSecurityDescriptorDacl` with bDaclPresent as `FALSE`, or supply a valid - non-null `pDacl` parameter value. - - For more information please see: - https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-setsecuritydescriptordacl#remarks - metadata: - category: security - cwe: CWE-732 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Null ACL when calling SetSecurityDescriptorDacl may allow all access to objects - pattern: SetSecurityDescriptorDacl(...) - severity: ERROR - - id: c_misc_rule-cuserid - languages: - - c - - cpp - - cpp - message: | - `cuserid()` is poorly defined (e.g., some systems use the effective - UID, like Linux, while others like System V use the real UID). Therefore, you can't trust - what it does. The cuserid function was included in the 1988 version of POSIX, but removed - from the 1990 version. Also, if passed a non-null parameter, there's a risk of a buffer - overflow if the passed-in buffer is not at least `L_cuserid` characters long. - - Use `getpwuid(geteuid())` and extract the desired information instead. - - For more information please see: https://linux.die.net/man/3/getpwuid - metadata: - category: security - cwe: CWE-120 - owasp: - - A9:2017-Using Components with Known Vulnerabilities - - A06:2021-Vulnerable and Outdated Components - security-severity: Low - shortDescription: Usage of deprecated function (cuserid) - pattern: cuserid(...) - severity: ERROR - - id: c_misc_rule-fopen-open - languages: - - c - - cpp - - cpp - message: | - Usage of the `open` family of functions may hint at a potential Time Of Check Time Of Use - (TOCTOU) - vulnerability. An attacker may be able to modify the file being specified by the `open` - function prior to the `open` function being called. - - Prior to calling `open`, use `lstat` to open the file and confirm the attributes - are correct. Then use `open` to get a file descriptor to this file. Call `fstat` on the - `open` file descriptor to confirm that `st_dev` and `st_ino` are equal between the two. - If they are, it is safe to read and operate on the file's contents. - - For more information please see: - https://wiki.sei.cmu.edu/confluence/display/c/FIO45-C.+Avoid+TOCTOU+race+conditions+while+accessing+files - metadata: - category: security - cwe: CWE-362 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Potential time of check time of use vulnerability (open/fopen) - pattern-either: - - pattern: fopen(...) - - pattern: open(...) - severity: INFO - - id: c_misc_rule-getlogin - languages: - - c - - cpp - - cpp - message: | - The `getlogin` function suffers from many bugs or unknown behaviors depending on the - system. Often, it gives only the first 8 characters of the login name. The user - currently logged in on the controlling TTY of our program does not necessarily mean - it is the user who started the process. - - Use getpwuid(geteuid()) and extract the desired information instead. - - For more information please see: https://linux.die.net/man/3/getpwuid - metadata: - category: security - cwe: CWE-807 - owasp: - - A9:2017-Using Components with Known Vulnerabilities - - A06:2021-Vulnerable and Outdated Components - security-severity: Low - shortDescription: Usage of deprecated function (getlogin) - pattern: getlogin(...) - severity: ERROR - - id: c_misc_rule-getpass - languages: - - c - - cpp - - cpp - message: | - This function is obsolete and not portable. It was in SUSv2 but removed by POSIX.2. What - it does exactly varies considerably between systems, particularly in where its prompt is - displayed and where it gets its data. Some systems will write to stderr instead of stdout. - Some will read from stdin if it can not be read from /dev/tty. In some systems the - buffer is static and limited to 127 characters, meaning the full password may not be returned - properly. - - If you want to read input without terminal echoing enabled, see the description of the ECHO - flag - in the termios manual pager. If you ever read passwords from a terminal, be sure to zero the - password as soon as possible, to avoid leaving the cleartext password visible in the - process' address space. - metadata: - category: security - cwe: CWE-477 - owasp: - - A9:2017-Using Components with Known Vulnerabilities - - A06:2021-Vulnerable and Outdated Components - security-severity: Low - shortDescription: Use of obsolete function - pattern: getpass(...) - severity: ERROR - - id: c_obsolete_rule-gsignal-ssignal - languages: - - c - - cpp - - cpp - message: | - The `gsignal` and `ssignal` functions are obsolete and no longer recommended. Consider - using the `raise` or `sigaction` functions instead for process signaling. - - For more information please see: https://linux.die.net/man/3/sigaction - metadata: - category: security - cwe: CWE-676 - owasp: - - A9:2017-Using Components with Known Vulnerabilities - - A06:2021-Vulnerable and Outdated Components - security-severity: Info - shortDescription: Deprecated function calls (ssignal/gsignal) - pattern-either: - - pattern: gsignal(...) - - pattern: ssignal(...) - severity: INFO - - id: c_obsolete_rule-ulimit - languages: - - c - - cpp - - cpp - message: | - The ulimit function is obsolete and no longer recommended. Use `getrlimit(2)`, - `setrlimit`, or `sysconf` instead. - - For more information please see: https://linux.die.net/man/3/setrlimit - metadata: - category: security - cwe: CWE-676 - owasp: - - A9:2017-Using Components with Known Vulnerabilities - - A06:2021-Vulnerable and Outdated Components - security-severity: Info - shortDescription: Usage of deprecated function (ulimit) - pattern: ulimit(...) - severity: INFO - - id: c_obsolete_rule-usleep - languages: - - c - - cpp - - cpp - message: | - The `usleep` function has been deprecated, use `nanosleep` or `setitimer` instead. - - For more information please see: https://linux.die.net/man/3/setitimer - metadata: - category: security - cwe: CWE-676 - owasp: - - A9:2017-Using Components with Known Vulnerabilities - - A06:2021-Vulnerable and Outdated Components - security-severity: Info - shortDescription: Usage of deprecated function (usleep) - pattern: usleep(...) - severity: INFO - - id: c_race_rule-access - languages: - - c - - cpp - - cpp - message: | - Usage of the `access` function call hints at a potential Time Of Check Time Of Use (TOCTOU) - vulnerability. Using the `access` function to check if a file exists and is readable before - opening it, an attacker can create a race condition between the `access` call and - opening the file. The attacker could replace the file with a different one or modify its - content between the time the `access` function is called and the file is opened, thus - bypassing the permission check. - - Call `setuid` to drop privileges on the process prior to opening any files. Instead of using - `access`, use `lstat` prior to opening the file and confirm the attributes are correct. Then - use `open` to get a file descriptor to this file. Call `fstat` on the `open` file descriptor - to confirm that `st_dev` and `st_ino` are equal between the two. If they are, it is safe to - read and operate on the file's contents. - - For more information please see: - https://wiki.sei.cmu.edu/confluence/display/c/FIO45-C.+Avoid+TOCTOU+race+conditions+while+accessing+files - metadata: - category: security - cwe: CWE-362 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Potential time of check time of use vulnerability (access) - pattern: access(...) - severity: ERROR - - id: c_race_rule-chmod - languages: - - c - - cpp - - cpp - message: | - Usage of the `chmod` function call hints at a potential Time Of Check Time Of Use (TOCTOU) - vulnerability. An attacker may be able to modify the file being specified by the `chmod` - function prior to the `chmod` function being called. Since `chmod` will resolve symbolic links, - an attacker may be able to exploit this fact to have files outside of their control modified. - - It is recommended that the `fchmod` function be used instead since this function takes - a file descriptor instead of a file. Ensure the opened file descriptor is pointing to - the correct file or directory prior to executing `fchmod` or any other file based operations. - - For more information please see: - https://wiki.sei.cmu.edu/confluence/display/c/FIO01-C.+Be+careful+using+functions+that+use+file+names+for+identification - metadata: - category: security - cwe: CWE-362 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Potential time of check time of use vulnerability (chmod) - pattern: chmod(...) - severity: ERROR - - id: c_race_rule-chown - languages: - - c - - cpp - - cpp - message: | - Usage of the `chown` function call hints at a potential Time Of Check Time Of Use (TOCTOU) - vulnerability. An attacker may be able to modify the file being specified by the `chmod` - function prior to the `chown` function being called. Since `chown` will resolve symbolic links, - an attacker may be able to exploit this fact to have files outside of their control modified. - - It is recommended that the `fchown` or the `lchown` functions be used instead. The `fchown` - function takes a file descriptor instead of a file. The `lchown` function does not follow - symbolic links. Ensure the opened file descriptor is pointing to the correct file or - directory prior to executing `fchown` or any other file based operations. - - For more information please see: - https://wiki.sei.cmu.edu/confluence/display/c/FIO01-C.+Be+careful+using+functions+that+use+file+names+for+identification - metadata: - category: security - cwe: CWE-362 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Potential time of check time of use vulnerability (chown) - pattern: chown(...) - severity: ERROR - - id: c_race_rule-readlink - languages: - - c - - cpp - - cpp - message: | - Usage of the `readlink` function call hints at a potential Time Of Check Time Of Use (TOCTOU) - vulnerability. An attacker may be able to modify the file being specified by the `readlink` - function prior to the `readlink` function being called. Additionally, care must be taken - that the buffer provided is large enough to hold the contents of the file. - - Instead of using `readlink`, use `lstat` prior to opening the file and confirm the attributes - are correct. Then use `open` to get a file descriptor to this file. Call `fstat` on the - `open` file descriptor to confirm that `st_dev` and `st_ino` are equal between the two. - If they are, it is safe to read and operate on the file's contents. - - For more information please see: - https://wiki.sei.cmu.edu/confluence/display/c/FIO45-C.+Avoid+TOCTOU+race+conditions+while+accessing+files - metadata: - category: security - cwe: CWE-367 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Time-of-check time-of-use (TOCTOU) race condition - pattern: readlink(...) - severity: ERROR - - id: c_race_rule-vfork - languages: - - c - - cpp - - cpp - message: | - The `vfork` function is suffers from portability issues and is not recommended. In - some Linux systems `vfork` is vulnerable to a race condition while the child process - is running as the user's UID but hasn't executed `execve`. The user may be able to send - signals to this process, which in `vfork` would not be sent to the parent process. As - a result a user may be able to cause a denial of service against the privileged process. - - Use `fork` instead and be aware of other potential Time Of Check Time Of Use (TOCTOU) - vulnerabilities. - - For more information please see: - https://wiki.sei.cmu.edu/confluence/display/c/POS38-C.+Beware+of+race+conditions+when+using+fork+and+file+descriptors - metadata: - category: security - cwe: CWE-362 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Potential time of check time of use vulnerability (vfork) - pattern: vfork(...) - severity: INFO - - id: c_random_rule-drand48-erand48 - languages: - - c - - cpp - - cpp - message: | - The detected function is not sufficient at generating security-related random numbers, - such as those used in key and nonce creation. Consider using the libsodium library's - `randombytes_random` function instead. More information on libsodium's random number - generators can be found here: https://libsodium.gitbook.io/doc/generating_random_data. - - If FIPS validation is required, consider using OpenSSLs `RAND_bytes` family of functions after - enabling the `FIPS_mode_set`. - - For more information on OpenSSL random numbers please see: - https://wiki.openssl.org/index.php/Random_Numbers - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Usage of insufficient random number generators - pattern-either: - - pattern: drand48(...) - - pattern: erand48(...) - - pattern: jrand48(...) - - pattern: lcong48(...) - - pattern: lrand48(...) - - pattern: mrand48(...) - - pattern: nrand48(...) - - pattern: random(...) - - pattern: seed48(...) - - pattern: setstate(...) - - pattern: srand(...) - - pattern: strfry(...) - - pattern: srandom(...) - - pattern: g_rand_boolean(...) - - pattern: g_rand_int(...) - - pattern: g_rand_int_range(...) - - pattern: g_rand_double(...) - - pattern: g_rand_double_range(...) - - pattern: g_random_boolean(...) - - pattern: g_random_int(...) - - pattern: g_random_int_range(...) - - pattern: g_random_double(...) - - pattern: g_random_double_range(...) - - pattern-regex: (long|short|double|int|float|void)\s(\*|)(\s|)(seed48|lcong48)(\(.*\))\; - severity: WARNING - - id: c_shell_rule-CreateProcess - languages: - - c - - cpp - - cpp - message: | - Due to how `CreateProcess` parses spaces, an attacker may be able to exploit this function - by creating a binary with the same name that is loaded first, depending on the search path - order. - - Ensure that quotation marks around the executable path are used, such as: - ``` - CreateProcessA(NULL, "\"C:\\Program Files\\MyApp.exe\"", ...) - ``` - For more information, please see MSDNs documentation at: - https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa#security-remarks - metadata: - category: security - cwe: CWE-78 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Possible executable path hijacking (CreateProcess) - pattern: CreateProcess(...) - severity: WARNING - - id: c_shell_rule-CreateProcessAsUser-CreateProcessWithLogon - languages: - - c - - cpp - - cpp - message: | - Due to how `CreateProcess` parses spaces, an attacker may be able to exploit this function - by creating a binary with the same name that is loaded first, depending on the search path - order. - - Ensure that quotation marks around the executable path are used, such as: - ``` - CreateProcessAsUser(hToken, NULL, "\"C:\\Program Files\\MyApp.exe\"", ...) - ``` - For more information, please see MSDNs documentation at: - https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasusera#security-remarks - metadata: - category: security - cwe: CWE-78 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Possible executable path hijacking (CreateProcessAsUser/CreateProcessWithLogon) - pattern-either: - - pattern: CreateProcessAsUser(...) - - pattern: CreateProcessWithLogon(...) - severity: WARNING - - id: c_shell_rule-execl-execlp - languages: - - c - - cpp - - cpp - message: | - It is generally not recommended to call out to the operating system to execute commands. - When the application is executing file system based commands, user input should never be used - in - constructing commands or command arguments. If possible, determine if a library can be used - instead to provide the same functionality. Otherwise, consider hard coding both the command - and arguments to be used, or at the very least restricting which arguments can be passed - to the command execution function. - - Please see the compliant solutions in the following page: - https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152177 - metadata: - category: security - cwe: CWE-78 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Potential for OS command injection - pattern-either: - - pattern: execl(...) - - pattern: execlp(...) - - pattern: execle(...) - - pattern: execv(...) - - pattern: execvp(...) - - pattern: popen(...) - - pattern: WinExec(...) - - pattern: ShellExecute(...) - severity: ERROR - - id: c_shell_rule-system - languages: - - c - - cpp - - cpp - message: | - It is generally not recommended to call out to the operating system to execute commands. - When the application is executing file system based commands, user input should never be used - in - constructing commands or command arguments. If possible, determine if a library can be used - instead to provide the same functionality. Otherwise, consider hard coding both the command - and arguments to be used, or at the very least restricting which arguments can be passed - to the command execution function. - - For more information please see: - https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152177 - metadata: - category: security - cwe: CWE-78 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Potential for OS command injection - pattern: system(...) - severity: ERROR - - id: c_tmpfile_rule-GetTempFileName - languages: - - c - - cpp - - cpp - message: | - The `GetTempFileName` function works by generating a randomly named file, creating the file - (if it does not exist) and then closing it. An application wishing to use this temporary file - will need to reopen this file to begin working with it. This leads to a potential - Time Of Check Time Of Use (TOCTOU) vulnerability, as an attacker could replace or modify - the contents of the file prior to it being used by the application. - - Consider generating a random filename and opening the file directly in a single `CreateFile` - or `OpenFile` call. - metadata: - category: security - cwe: CWE-377 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Potential time of check time of use vulnerability (GetTempFileName) - pattern: GetTempFileName(...) - severity: WARNING - - id: c_tmpfile_rule-mkstemp - languages: - - c - - cpp - - cpp - message: | - Some older Unix-like systems, `mkstemp` would create temp files with 0666 permissions, - meaning the file created would be read/write access for all users. - - Ensure the process has called the `umask` function with restricted permissions prior - to calling `mkstemp` and validate the permissions prior to using the file descriptor. - - For more information on temporary files please see: - https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152425 - metadata: - category: security - cwe: CWE-377 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Potential file permissions issue (mkstemp) - pattern: mkstemp(...) - severity: INFO - - id: c_tmpfile_rule-mktemp - languages: - - c - - cpp - - cpp - message: | - The `mktemp` function should no longer be used due to multiple flaws. Some implementations - created random files by using known information like the process ID and a single letter. This - allows for possible race conditions where an attacker could guess or manipulate these files - prior to them being used. - - Consider using the `mkstemp` function instead, but be aware it also contains possible - risks. Ensure the process has called the `umask` function with restricted permissions prior - to calling `mkstemp` and validate the permissions prior to using the file descriptor. - - For more information on temporary files please see: - https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152425 - metadata: - category: security - cwe: CWE-377 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Use of deprecated function (mktemp) - pattern: mktemp(...) - severity: ERROR - - id: c_tmpfile_rule-tmpfile - languages: - - c - - cpp - - cpp - message: | - There exists a possible race condition in between the time that `tmpfile` returns - a pathname, and the time that the program opens it, another program might create - that pathname using `open`, or create it as a symbolic link. - - Consider using the `mkstemp` function instead, but be aware it also contains possible - risks. Ensure the process has called the `umask` function with restricted permissions prior - to calling `mkstemp` and validate the permissions prior to using the file descriptor. - - For more information on temporary files please see: - https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152425 - metadata: - category: security - cwe: CWE-377 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Potential time of check time of use vulnerability (tmpfile) - pattern: tmpfile(...) - severity: INFO - - id: c_tmpfile_rule-tmpnam-tempnam - languages: - - c - - cpp - - cpp - message: | - There exists a possible race condition in between the time that `tempnam` or `tmpnam` - returns a pathname, and the time that the program opens it, another program might create - that pathname using `open`, or create it as a symbolic link. - - Consider using the `mkstemp` function instead, but be aware it also contains possible - risks. Ensure the process has called the `umask` function with restricted permissions prior - to calling `mkstemp` and validate the permissions prior to using the file descriptor. - - For more information on temporary files please see: - https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152425 - metadata: - category: security - cwe: CWE-377 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Potential time of check time of use vulnerability (tmpnam/tempnam) - pattern-either: - - pattern: tmpnam(...) - - pattern: tempnam(...) - severity: WARNING - - id: csharp_cookies_rule-CookieWithoutHttpOnlyFlag - languages: - - csharp - message: | - The `HttpOnly` attribute when set to `true` protects the cookie value from being accessed by - client side JavaScript such - as reading the `document.cookie` values. By enabling this protection, a website that is - vulnerable to - Cross-Site Scripting (XSS) will be able to block malicious scripts from accessing the cookie - value from JavaScript. - - Example of protecting an HttpCookie: - ``` - // Create an HttpOnly cookie. - HttpCookie someCookie = new HttpCookie("SomeCookieName", "SomeValue"); - someCookie.HttpOnly = true; - ``` - - For more information see: - https://learn.microsoft.com/en-us/dotnet/api/system.web.httpcookie.httponly - - Session cookies should be configured with the following security directives: - - - [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - - [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - - [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) - metadata: - category: security - cwe: CWE-1004 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Low - shortDescription: Sensitive cookie without 'HttpOnly' flag - mode: taint - pattern-sanitizers: - - pattern: $COOKIE.HttpOnly = true; - pattern-sinks: - - pattern: $COOKIE - pattern-sources: - - pattern: | - var $COOKIE = new HttpCookie(...); - severity: WARNING - - id: csharp_cookies_rule-CookieWithoutSSLFlag - languages: - - csharp - message: | - The `Secure` attribute when set to `true` protects the cookie value from being being - transmitted over clear text - communication paths such as HTTP. By enabling this protection, the cookie will only be sent - over HTTPS. - - Example of protecting an HttpCookie: - ``` - // Create an HttpOnly cookie. - HttpCookie someCookie = new HttpCookie("SomeCookieName", "SomeValue"); - someCookie.Secure = true; - ``` - - For more information see: - https://learn.microsoft.com/en-us/dotnet/api/system.web.httpcookie.secure - - Session cookies should be configured with the following security directives: - - - [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - - [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) - - [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - metadata: - category: security - cwe: CWE-614 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Low - shortDescription: Sensitive cookie in HTTPS session without 'Secure' attribute - mode: taint - pattern-sanitizers: - - pattern: $COOKIE.Secure = true; - pattern-sinks: - - pattern: $COOKIE - pattern-sources: - - pattern: | - var $COOKIE = new HttpCookie(...); - severity: WARNING - - id: csharp_crypto_rule-CertificateValidationDisabled - languages: - - csharp - message: | - The `ServicePointManager.ServerCertificateValidationCallback` event has been set - to always return `true`, which effectively disables the validation of server - certificates. - - This allows for an adversary who is in between the application and the target host to intercept - potentially sensitive information or transmit malicious data. - - Remove the callback function that is returning true to allow normal certificate validation to - proceed. - When no callback is provided, the client will validate that the certificate name matches the - hostname - that was used when creating the request. - - For more information on the `ServerCertificateValidationCallback` property see: - https://learn.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.servercertificatevalidationcallback - metadata: - category: security - cwe: CWE-295 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: Medium - shortDescription: Certificate validation disabled - patterns: - - pattern-inside: | - using System.Net; - ... - - pattern: ServicePointManager.ServerCertificateValidationCallback += $CALLBACK; - - metavariable-pattern: - metavariable: $CALLBACK - patterns: - - pattern-either: - - pattern: $RETURNTYPE $FUNC(...) { return true; } - - pattern: (...) => true; - severity: WARNING - - id: csharp_crypto_rule-WeakCipherAlgorithm - languages: - - csharp - message: | - DES, TripleDES and RC2 are all considered broken or insecure cryptographic algorithms. - If using .NET Framework greater than version 6.0 consider using `ChaCha20Poly1305` - instead as it is easier and faster than the alternatives such as `AES-256-GCM`. - - For older applications, `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Example using `ChaCha20Poly1305`: - ``` - // Generate a random key - byte[] key = new byte[32]; - RandomNumberGenerator.Fill(key); - - // Note nonce values _must_ be regenerated every time they are used. - byte[] nonce = new byte[12]; - RandomNumberGenerator.Fill(nonce); - - byte[] authTag = new byte[16]; - byte[] cipherText; - - using (ChaCha20Poly1305 encryptor = new ChaCha20Poly1305(key)) - { - byte[] plainText = System.Text.Encoding.UTF8.GetBytes("Secret text to encrypt"); - cipherText = new byte[plainText.Length]; - encryptor.Encrypt(nonce, plainText, cipherText, authTag); - } - - using (ChaCha20Poly1305 decryptor = new ChaCha20Poly1305(key)) - { - byte[] output = new byte[cipherText.Length]; - decryptor.Decrypt(nonce, cipherText, authTag, output); - Console.WriteLine("Output: {0}", System.Text.Encoding.UTF8.GetString(output)); - } - ``` - - Example using `AES-256-GCM`: - ``` - // Generate a random key - byte[] key = new byte[32]; - RandomNumberGenerator.Fill(key); - - // Note nonce values _must_ be regenerated every time they are used. - byte[] nonce = new byte[AesGcm.NonceByteSizes.MaxSize]; - RandomNumberGenerator.Fill(nonce); - - byte[] authTag = new byte[AesGcm.TagByteSizes.MaxSize]; - byte[] cipherText; - - using (AesGcm encryptor = new AesGcm(key)) - { - byte[] plainText = Encoding.UTF8.GetBytes("Secret text to encrypt"); - cipherText = new byte[plainText.Length]; - encryptor.Encrypt(nonce, plainText, cipherText, authTag); - } - - using (AesGcm decryptor = new AesGcm(key)) - { - byte[] output = new byte[cipherText.Length]; - decryptor.Decrypt(nonce, cipherText, authTag, output); - Console.WriteLine("Output: {0}", Encoding.UTF8.GetString(output)); - } - ``` - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-inside: | - using System.Security.Cryptography; - ... - - pattern-either: - - pattern-regex: .*DES\.Create\(\); - - pattern: new DESCryptoServiceProvider(); - - pattern-regex: .*TripleDES\.Create\(\); - - pattern: new TripleDESCryptoServiceProvider(); - - pattern-regex: .*RC2\.Create\(\); - - pattern: new RC2CryptoServiceProvider(); - severity: WARNING - - id: csharp_crypto_rule-WeakCipherMode - languages: - - csharp - message: | - Cryptographic algorithms provide many different modes of operation, only some of which provide - message integrity. Without message integrity it could be possible for an adversary to attempt - to tamper with the ciphertext which could lead to compromising the encryption key. Newer - algorithms - apply message integrity to validate ciphertext has not been tampered with. - - Instead of using an algorithm that requires configuring a `CipherMode`, an algorithm - that has built-in message integrity should be used. If using .NET Framework greater - than version 6.0 consider using `ChaCha20Poly1305` or `AES-256-GCM`. - - For older applications, `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are re-used. - - Example using `ChaCha20Poly1305`: - ``` - // Generate a random key - byte[] key = new byte[32]; - RandomNumberGenerator.Fill(key); - - ChaCha20Poly1305 encryptor = new ChaCha20Poly1305(key); - - // Note nonce values _must_ be regenerated every time they are used. - var nonce = new byte[12]; - RandomNumberGenerator.Fill(nonce); - - byte[] plainText = System.Text.Encoding.UTF8.GetBytes("Secret text to encrypt"); - byte[] cipherText = new byte[plainText.Length]; - var authTag = new byte[16]; - - encryptor.Encrypt(nonce, plainText, cipherText, authTag); - byte[] output = new byte[cipherText.Length]; - encryptor.Decrypt(nonce, cipherText, authTag, output); - Console.WriteLine("Output: {0}", System.Text.Encoding.UTF8.GetString(output)); - ``` - - Example using `AES-256-GCM`: - ``` - var plaintextBytes = Encoding.UTF8.GetBytes("Secret text to encrypt"); - var key = new byte[32]; - RandomNumberGenerator.Fill(key); - - using var aes = new AesGcm(key); - var nonce = new byte[AesGcm.NonceByteSizes.MaxSize]; - RandomNumberGenerator.Fill(nonce); - - var cipherText = new byte[plaintextBytes.Length]; - var tag = new byte[AesGcm.TagByteSizes.MaxSize]; - - aes.Encrypt(nonce, plaintextBytes, cipherText, tag); - - // Decrypt - using (var decrypt = new AesGcm(key)) - { - var decryptedBytes = new byte[cipherText.Length]; - - decrypt.Decrypt(nonce, cipherText, tag, decryptedBytes); - - Console.WriteLine("Decrypted: {0}", Encoding.UTF8.GetString(decryptedBytes)); - } - ``` - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-inside: | - using System.Security.Cryptography; - ... - - metavariable-regex: - metavariable: $CIPHER - regex: ^(ECB|CBC|OFB|CFB|CTS)$ - - pattern: CipherMode.$CIPHER - severity: WARNING - - id: csharp_crypto_rule-WeakHashingFunction - languages: - - csharp - message: | - Both MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. Currently there is no vetted Argon2id implementation for - C# so - it is recommended that PBKDF2 be used until one is available. - - Example using PBKDF2 to generate and compare passwords: - ``` - const int SaltSize = 24; - const int HashSize = 24; - // number of pbkdf2 iterations, Rfc2898DeriveBytes uses hmac-sha1 - // so set a high iteration count - const int Iterations = 1_300_000; - byte[] salt = new byte[SaltSize]; - RandomNumberGenerator.Fill(salt); - - Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes("some password", salt, Iterations); - byte[] hashBytes = pbkdf2.GetBytes(HashSize); - // Store salt and hashedBytes in a data store such as database for authentication - Console.WriteLine("Hash {0}", BitConverter.ToString(hashBytes).Replace("-", "")); - // Do a constant time comparison as to not leak data based on timing - if (CryptographicOperations.FixedTimeEquals(hashBytes, hashBytes)) { - Console.WriteLine("hashes are equal"); - } - ``` - For more information on PBKDF2 see: - https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.rfc2898derivebytes - - For more information on secure password storage see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm (SHA1/MD5) - patterns: - - pattern-either: - - patterns: - - metavariable-regex: - metavariable: $HASH_PROVIDER - regex: ^(SHA1CryptoServiceProvider|MD5CryptoServiceProvider)$ - - pattern: new $HASH_PROVIDER - - patterns: - - metavariable-regex: - metavariable: $HASH_CLASS - regex: ^System.Security.Cryptography.(SHA1|MD5)$ - - pattern: $HASH_CLASS.$METHOD(); - severity: WARNING - - id: csharp_crypto_rule-WeakRNG - languages: - - csharp - message: | - Depending on the context, generating weak random numbers may expose cryptographic functions - which rely on these numbers to be exploitable. When generating numbers for sensitive values - such as tokens, nonces, and cryptographic keys, it is recommended that the - `RandomNumberGenerator` class be used. - - Example `RandomNumberGenerator` usage: - ``` - Int32 randInt = RandomNumberGenerator.GetInt32(32000); - byte[] randomBytes = new byte[64]; - RandomNumberGenerator.Fill(randomBytes); - Console.WriteLine("Random Int32: {0}", randInt); - Console.WriteLine("Random Bytes: {0}", BitConverter.ToString(randomBytes).Replace("-", "")); - ``` - - For more information see: - https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator - metadata: - category: security - cwe: CWE-338 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of cryptographically weak Pseudo-Random Number Generator (PRNG) - patterns: - - pattern: (Random $RNG).$METHOD(...); - - focus-metavariable: $RNG - severity: WARNING - - id: csharp_csrf_rule-Csrf - languages: - - csharp - message: | - The application failed to protect against Cross-Site Request Forgery (CSRF) - due to not including the `[ValidateAntiForgeryToken]` attribute on an - HTTP method handler that could change user state (usually in the form of POST or PUT - methods). - - The vulnerability can be exploited by an adversary creating a link or form on a third - party site and tricking an authenticated victim to access them. - - Add the `[ValidateAntiForgeryToken]` to all methods which take in user data and change - user state (such as updating a database with a new value). This is especially true for - functionality such as updating passwords or other security sensitive functions. - - Alternatively, applications can enable a global - [AutoValidateAntiforgeryTokenAttribute](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.autovalidateantiforgerytokenattribute) - filter. - - For more information on ValidateAntiForgeryToken and other CSRF protections in .NET - see the following URL: - https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery - - Additionally, consider setting all session cookies to have the `SameSite=Strict` attribute. - It should be noted that this may impact usability when sharing links across other mediums. - It is recommended that a two cookie based approach is taken, as outlined in the - [Top level - navigations](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-08#section-8.8.2) - section - of the SameSite RFC. - - For more information on CSRF see OWASP's guide: - https://owasp.org/www-community/attacks/csrf - metadata: - category: security - cwe: CWE-352 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Potential Cross-Site Request Forgery (CSRF) - patterns: - - pattern: | - [$HTTPMETHOD] - public $RET $FOO(...) { - ... - } - - pattern-not: | - [ValidateAntiForgeryToken] - public $RET $FOO(...) { - ... - } - - pattern-not-inside: | - [AutoValidateAntiforgeryToken] - class $CLASS{ - ... - } - - pattern-not-inside: | - [ValidateAntiForgeryToken] - class $CLASS{ - ... - } - - metavariable-regex: - metavariable: $HTTPMETHOD - regex: Http(Post|Delete|Patch|Put) - severity: WARNING - - id: csharp_deserialization_rule-InsecureDeserialization - languages: - - csharp - message: | - Deserialization attacks exploit the process of reading serialized data and turning it back into an - object. By constructing malicious objects and serializing them, an adversary may attempt to: - - - Inject code that is executed upon object construction, which occurs during the deserialization process. - - Exploit mass assignment by including fields that are not normally a part of the serialized data but are - read in during deserialization. - - Microsoft recommends no longer using the following serialization formats: - - - BinaryFormatter - - SoapFormatter - - NetDataContractSerializer - - LosFormatter - - ObjectStateFormatter - - Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows - the application to specify exactly which object types are allowed to be deserialized. Additionally, when - deserializing, never deserialize to base object types like `Object` and only cast to the exact object - type that is expected. - - To protect against mass assignment, only allow deserialization of the specific fields that are required. - If this is not easily done, consider creating an intermediary type that can be serialized with only the - necessary fields exposed. - - For more information see Microsoft's deserialization security guide: - https://learn.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide - - For more details on deserialization attacks in general, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html - - It should be noted that [tools exist](https://github.com/pwntester/ysoserial.net) to automatically create - exploit code for these vulnerabilities. - metadata: - category: security - cwe: CWE-502 - owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: High - shortDescription: Deserialization of potentially untrusted data - mode: taint - pattern-sinks: - - pattern: (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter $OBJ).Deserialize(...) - - pattern: (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter $OBJ).UnsafeDeserialize(...) - - pattern: (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter $OBJ).UnsafeDeserializeMethod(...) - - pattern: (System.Runtime.Serialization.Formatters.Soap.SoapFormatter $OBJ).Deserialize(...) - - pattern: (System.Runtime.Serialization.NetDataContractSerializer $OBJ).Deserialize(...) - - pattern: (System.Web.UI.LosFormatter $OBJ).Deserialize(...) - pattern-sources: - - pattern: Request.Cookies[...] - - pattern: Request.Cookies.Get(...) - - pattern: Request.Form[...] - - pattern: Request.Form.Get(...) - - pattern: Request.Headers[...] - - pattern: Request.Headers.Get(...) - - pattern: Request.QueryString[...] - - pattern: Request.QueryString.Get(...) - - pattern: Request.Body - - pattern: $CTX.Request.Cookies[...] - - pattern: $CTX.Request.Cookies.Get(...) - - pattern: $CTX.Request.Form[...] - - pattern: $CTX.Request.Form.Get(...) - - pattern: $CTX.Request.Headers[...] - - pattern: $CTX.Request.Headers.Get(...) - - pattern: $CTX.Request.QueryString[...] - - pattern: $CTX.Request.QueryString.Get(...) - - pattern: $CTX.Request.Body - - pattern: System.IO.File.ReadAllText(...) - - pattern: System.IO.File.ReadAllTextAsync(...) - - pattern: System.IO.File.ReadAllLines(...) - - pattern: System.IO.File.ReadAllLinesAsync(...) - - pattern: System.IO.File.ReadAllBytes(...) - - pattern: System.IO.File.ReadAllBytesAsync(...) - - pattern: System.IO.File.ReadLines(...) - - pattern: System.IO.File.ReadLinesAsync(...) - - pattern: System.Environment.GetEnvironmentVariable(...) - severity: WARNING - - id: csharp_endpoint_rule-UnvalidatedRedirect - languages: - - csharp - message: | - The application may allow open redirects if created using user supplied input. Open redirects - are - commonly - abused in phishing attacks where the original domain or URL looks like a legitimate link, but - then - redirects a user to a malicious site. An example would be - `https://example.com/redirect?url=https://%62%61%64%2e%63%6f%6d%2f%66%61%6b%65%6c%6f%67%69%6e` - which, - when decoded, turns into `bad.com/fakelogin`. - - Never redirect a client based on user input. It is recommended that the list of target links - to - redirect a user to are contained server side, and retrieved using a numerical value - as an index to return the link to be redirected to. For example, `/redirect?id=1` would cause - the - application to look up the `1` index and return a URL such as `https://example.com`. This URL - would - then be used to redirect the user, using the 301 response code and `Location` header. - - For more information on open redirects see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-601 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Info - shortDescription: URL redirection to untrusted site 'open redirect' - mode: taint - pattern-sanitizers: - - pattern: Url.Action(...) - - pattern: Url.HttpRouteUrl(...) - - pattern: Url.RouteUrl(...) - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: return $METHOD(...) - - pattern: return new $METHOD(...) - - pattern: | - if (!Url.IsLocalUrl(...)) { - ... - return $METHOD(...) - } - - patterns: - - pattern-not-inside: | - if (Url.IsLocalUrl(...)) { - ... - } - - pattern-not-inside: | - if (!Url.IsLocalUrl(...)) { - return $X - } - ... - - pattern-either: - - pattern: $METHOD(...) - - pattern: new $METHOD(...) - - metavariable-pattern: - metavariable: $METHOD - pattern-either: - - pattern: Redirect - - pattern: RedirectPermanent - - pattern: RedirectToRoute - - pattern: RedirectToRoutePermanent - - pattern: RedirectResult - pattern-sources: - - patterns: - - pattern: $SRC - - pattern-inside: | - public $RET $FUNC(...,$SRC,...){...} - - patterns: - - pattern: $SRC - - pattern-inside: | - if (Uri.TryCreate(..., ..., $SRC)){ - ... - } - severity: WARNING - - id: csharp_injection_rule-CommandInjection - languages: - - csharp - message: | - OS command injection is a critical vulnerability that can lead to a full system - compromise as it may allow an adversary to pass in arbitrary commands or arguments - to be executed. - - User input should never be used in constructing commands or command arguments - to functions which execute OS commands. This includes filenames supplied by - user uploads or downloads. - - Ensure your application does not: - - - Use user-supplied information in the process name to execute. - - Use user-supplied information in an OS command execution function which does - not escape shell meta-characters. - - Use user-supplied information in arguments to OS commands. - - The application should have a hardcoded set of arguments that are to be passed - to OS commands. If filenames are being passed to these functions, it is - recommended that a hash of the filename be used instead, or some other unique - identifier. It is strongly recommended that a native library that implements - the same functionality be used instead of using OS system commands, due to the - risk of unknown attacks against third party commands. - - When specifying the OS command, ensure the application uses the full path - information, otherwise the OS may attempt to look up which process to execute - and could be vulnerable to untrusted search path vulnerabilities (CWE-426). - - Example of safely executing an OS command: - ``` - public void ExecuteCommand(string userFileData) { - // generate a random filename, do not using user input - string fileName = "C:\\Temp\\" + Guid.NewGuid(); - File.WriteAllText(fileName, userFileData); - - using (Process process = new Process()) - { - // hardcode the full process path - ProcessStartInfo processInfo = new ProcessStartInfo("C:\\App\\FileReader.exe"); - // only pass in trust arguments, and never direct user input. - processInfo.Arguments = fileName; - processInfo.UseShellExecute = false; - process.StartInfo = processInfo; - process.Start(); - } - } - ``` - - For more information on OS command injection, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-78 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - ... - (System.Diagnostics.Process $PROC).Start(...); - - pattern-either: - - patterns: - - pattern: (System.Diagnostics.Process $PROC).StartInfo.FileName = <...$ARG...>; - - pattern-not: (System.Diagnostics.Process $PROC).StartInfo.FileName = "..."; - - patterns: - - pattern: (System.Diagnostics.Process $PROC).StartInfo.Arguments = <...$ARG...>; - - pattern-not: (System.Diagnostics.Process $PROC).StartInfo.Arguments = "..."; - - patterns: - - pattern: System.Diagnostics.Process.Start($ARG); - - pattern-not: System.Diagnostics.Process.Start("..."); - - patterns: - - pattern-not: $PSINFO.Arguments = "..."; - - pattern-not: $PSINFO.FileName = "..."; - - pattern-not: new System.Diagnostics.ProcessStartInfo("..."); - - pattern-not: new System.Diagnostics.ProcessStartInfo(); - - pattern-either: - - pattern: new System.Diagnostics.ProcessStartInfo(...); - - pattern: $PSINFO.Arguments = <...$ARG...>; - - pattern: $PSINFO.FileName = <...$ARG...>; - - patterns: - - pattern-inside: | - new System.Diagnostics.ProcessStartInfo{ - ... - } - - pattern-not: Arguments = "..." - - pattern-not: FileName = "..." - - pattern-either: - - pattern: Arguments = ... - - pattern: FileName = ... - severity: ERROR - - id: csharp_injection_rule-LdapInjection - languages: - - csharp - message: | - LDAP injection attacks exploit LDAP queries to influence how data is returned by - the LDAP, or in this case an Active Directory server. - - It is recommended that newer applications use the `System.DirectoryServices.AccountManagement` - API instead of `DirectorySearcher` API as it hides the complexity of querying LDAP directly. - However, - the `AccountManagement` API is still susceptible to LDAP injection if a user inputs LDAP - queries, - including LDAP filter characters such as `*`. - - It is recommended that all input passed to LDAP querying systems encode the following values: - - - Any occurrence of the null character must be escaped as “\00”. - - Any occurrence of the open parenthesis character must be escaped as “\28”. - - Any occurrence of the close parenthesis character must be escaped as “\29”. - - Any occurrence of the asterisk character must be escaped as “\2a”. - - Any occurrence of the backslash character must be escaped as “\5c”. - - Example code that safely encodes input for use in an LDAP query using the `AccountManagement` - API: - ``` - using System.DirectoryServices.AccountManagement; - - string EncodeLDAPString(string input) { - // Note the \ character is replaced first - char[] chars = new char[] { '\\', '\0', '(', ')', '*' }; - string[] encoded = new string[] { "\\5c", "\\00", "\\28", "\\29", "\\2a" }; - - for (int i = 0; i < chars.Length; i++) - { - input = input.Replace(chars[i].ToString(), encoded[i]); - } - - return input; - } - - // unsafe, do not use without encoding first - string userInput = "Administrator"; - PrincipalContext AD = new PrincipalContext(ContextType.Domain, "ad.example.dev"); - - UserPrincipal u = new UserPrincipal(AD); - string encodedUserName = EncodeLDAPString(userInput); - - // The AD search term, encoded prior to calling search - u.SamAccountName = encodedUserName; - - // Search for user - PrincipalSearcher search = new PrincipalSearcher(u); - - // Use FindOne to only return a single result - UserPrincipal result = (UserPrincipal)search.FindOne(); - search.Dispose(); - - // show some details - if (result != null) { - Console.WriteLine("User: {0}", result.DisplayName); - } else { - Console.WriteLine("user not found"); - } - ``` - - The same encoding method shown in `EncodeLDAPString` can also be used when using the - older `DirectorySearcher` API. - - For more information see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-90 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of special elements used in an LDAP query ('LDAP Injection') - mode: taint - pattern-sinks: - - pattern: System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(...) - - pattern: new System.DirectoryServices.DirectoryEntry(...) - - pattern: new System.DirectoryServices.DirectorySearcher(...) - - pattern: new System.DirectoryServices.Protocols.SearchRequest(...) - - patterns: - - focus-metavariable: $TAINTED - - pattern-either: - - pattern: (System.DirectoryServices.DirectoryEntry $SOURCE).Path = $TAINTED - - pattern: (System.DirectoryServices.DirectorySearcher $SEARCHER).Filter = $TAINTED - - pattern: (System.DirectoryServices.Protocols.SearchRequest $SEARCHREQ).Filter = $TAINTED - - pattern: (System.DirectoryServices.Protocols.SearchRequest $SEARCHREQ).DistinguishedName = $TAINTED - - pattern: (System.DirectoryServices.AccountManagement.UserPrincipal $SEARCHREQ).$PROP = $TAINTED - pattern-sources: - - patterns: - - pattern-inside: | - $RET $METHOD(...,$VAR,...){...} - - pattern: $VAR - severity: WARNING - - id: csharp_injection_rule-SQLInjection - languages: - - csharp - message: | - SQL Injection is a critical vulnerability that can lead to data or system compromise. By - dynamically generating SQL query strings, user input may be able to influence the logic of - the SQL statement. This could lead to an adversary accessing information they should - not have access to, or in some circumstances, being able to execute OS functionality or code. - - Replace all dynamically generated SQL queries with parameterized queries. In situations where - dynamic queries must be created, never use direct user input, but instead use a map or - dictionary of valid values and resolve them using a user supplied key. - - For example, some database drivers do not allow parameterized queries for `>` or `<` comparison - operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the - user - supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` - values to be used in the construction of the dynamic query. The same goes for other queries - where - column or table names are required but cannot be parameterized. - - Example using parameterized queries with `SqlCommand`: - ``` - string userInput = "someUserInput"; - string connectionString = ...; - using (SqlConnection connection = new SqlConnection(connectionString)) - { - connection.Open(); - String sql = "SELECT name, value FROM table where name=@Name"; - - using (SqlCommand command = new SqlCommand(sql, connection)) - { - command.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar); - command.Parameters["@Name"].Value = userInput; - using (SqlDataReader reader = command.ExecuteReader()) - { - while (reader.Read()) - { - Console.WriteLine("{0} {1}", reader.GetString(0), reader.GetString(1)); - } - } - } - } - ``` - - For more information on SQL Injection see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-89 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') - patterns: - - pattern-either: - - patterns: - - metavariable-pattern: - metavariable: $FUNC - pattern-either: - - pattern: SqlQuery - - pattern: ExecuteSqlCommand - - pattern: ExecuteSqlCommandAsync - - pattern: ExecuteSqlRaw - - pattern: ExecuteSqlRawAsync - - pattern: FromSqlRaw - - pattern: FromSql - - pattern: GetSqlStringCommand - - pattern: ExecuteDataSet - - pattern: ExecuteReader - - pattern: ExecuteNonQuery - - pattern: ExecuteScalar - - pattern: CreateSQLQuery - - pattern-either: - - pattern: $DB.$FUNC($ARG, ...) - - pattern: $DB.$FUNC<$CC>($ARG, ...) - - pattern-not: $DB.$FUNC("...", ...) - - pattern-not: $DB.$FUNC<$CC>("...", ...) - - patterns: - - pattern-inside: | - using System.Data.Linq; - ... - - pattern-either: - - patterns: - - pattern: (DataContext $CTX).ExecuteQuery<$TRESULT>($ARG, ...) - - pattern-not: (DataContext $CTX).ExecuteQuery<$TRESULT>("...", ...) - - patterns: - - pattern: (DataContext $CTX).ExecuteQuery($TYPE, $ARG, ...) - - pattern-not: (DataContext $CTX).ExecuteQuery($TYPE, "...", ...) - - patterns: - - pattern: (DataContext $CTX).ExecuteCommand($ARG, ...) - - pattern-not: (DataContext $CTX).ExecuteCommand("...", ...) - - patterns: - - metavariable-pattern: - metavariable: $IMPL - pattern-either: - - pattern: SqlCommand - - pattern: OracleCommand - - pattern: NpgsqlCommand - - pattern: MySqlCommand - - pattern: EntityCommand - - pattern: OdbcCommand - - pattern: OleDbCommand - - pattern: SqliteCommand - - pattern-either: - - patterns: - - pattern: new $IMPL($ARG, ...); - - pattern-not: new $IMPL("...", ...); - - patterns: - - pattern: ($IMPL $CMD).CommandText = <...$ARG...>; - - pattern-not: ($IMPL $CMD).CommandText = "..."; - - patterns: - - metavariable-pattern: - metavariable: $FUNC - pattern-either: - - pattern: ExecuteDataRow - - pattern: ExecuteDataRowAsync - - pattern: ExecuteDataset - - pattern: ExecuteDatasetAsync - - pattern: ExecuteNonQuery - - pattern: ExecuteNonQueryAsync - - pattern: ExecuteReader - - pattern: ExecuteReaderAsync - - pattern: ExecuteScalar - - pattern: ExecuteScalarAsync - - pattern: UpdateDataSet - - pattern: UpdateDataSetAsync - - pattern-inside: | - using MySql.Data.MySqlClient; - ... - - pattern: MySqlHelper.$FUNC($CONN, $ARG, ...) - - pattern-not: MySqlHelper.$FUNC($CONN, "...", ...) - - patterns: - - pattern-inside: | - using Cassandra; - ... - - pattern-not: $SESS.Execute("...", ...) - - pattern-either: - - pattern: (Session $SESS).Execute($ARG, ...) - - patterns: - - pattern-inside: | - var $SESS = $CLUSTER.Connect(...); - ... - - pattern: $SESS.Execute($ARG, ...) - severity: WARNING - - id: csharp_injection_rule-XPathInjection - languages: - - csharp - message: | - XPath injection is a vulnerability that can allow an adversary to inject or modify how an XML - query - is structured. Depending on the logic of the original query, this could lead to adversaries - extracting unauthorized information or in rare cases bypassing authorization checks. - - It is recommended that LINQ to XML is used instead of XPath for querying XML documents. Care - must be taken to **not** call these LINQ functions with user input as they can still lead to - XPath - injection: - - - `XPathEvaluate` - - `XPathSelectElement` - - `XPathSelectElements` - - Example using LINQ to XML to safely extract the first user from a list of users: - ``` - // XDocument is safe from XXE attacks as the resolver is disabled by default - XDocument doc = XDocument.Load("users.xml"); - XNamespace ns = "urn:users-schema"; - - string userInput = "LastName"; - - // Get all the users. - var user = doc.Descendants(ns + "user") - .Select(u => new { - FirstName = (string)u.Element(ns + "first-name"), - LastName = (string)u.Element(ns + "last-name") - }).Where(u => u.LastName == userInput).FirstOrDefault(); - - Console.WriteLine(user.FirstName + " " + user.LastName); - ``` - - For more information on LINQ to XML security see: - https://learn.microsoft.com/en-us/dotnet/standard/linq/linq-xml-security - - For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#net - metadata: - category: security - cwe: CWE-643 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of data within XPath expressions ('XPath Injection') - patterns: - - pattern-inside: | - using System.Xml; - ... - - pattern-either: - - patterns: - - metavariable-regex: - metavariable: $FUNC - regex: ^(SelectNodes|SelectSingleNode|Compile|Evaluate|Matches|Select|SelectAncestors|SelectChildren|SelectDescendants)$ - - metavariable-regex: - metavariable: $TY - regex: ^(XPathNavigator|XmlDocument|XmlNode|XmlDocumentXPathExtensions)$ - - pattern: ($TY $VAR).$FUNC(<...$ARG...>, ...) - - pattern-not: ($TY $VAR).$FUNC("...", ...) - - patterns: - - pattern-inside: | - using System.Xml.Linq; - ... - - metavariable-regex: - metavariable: $FUNC - regex: ^(XPathEvaluate|XPathSelectElement|XPathSelectElements)$ - - pattern: $VAR.$FUNC(<...$ARG...>, ...) - - pattern-not: $VAR.$FUNC("...", ...) - - patterns: - - pattern-inside: | - using System.Xml.Schema; - ... - - pattern-either: - - patterns: - - pattern: $VAR.XPath = <...$ARG...>; - - pattern-not: $VAR.XPath = "..." - - patterns: - - pattern: new XmlSchemaXPath { XPath = <...$ARG...> }; - - focus-metavariable: $ARG - severity: INFO - - id: csharp_injection_rule-XmlDocumentXXEInjection - languages: - - csharp - message: | - External XML entities are a feature of XML parsers that allow documents to contain references - to - other documents or data. This feature can be abused to read files, communicate with external - hosts, - exfiltrate data, or cause a Denial of Service (DoS). - - XML parsers and document loaders must be configured to not resolve entities. This can be done - by: - - Ensuring you are running a version of .NET Framework greater than 4.5.2 (released in 2014). - - Using `XDocument` which disables entity resolution and is generally safe from DoS. - - Setting `XmlDocument`'s `XmlResolver` to null. - - Example of safely loading an XML file using `XmlDocument`: - ``` - XmlDocument document = new XmlDocument(); - document.XmlResolver = null; - document.Load("users.xml"); - ``` - - For more information on XML security, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#net - metadata: - category: security - cwe: CWE-611 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper restriction of XML external entity reference ('XXE') - mode: taint - pattern-sinks: - - patterns: - - pattern-not-inside: | - (XmlDocument $DOC).XmlResolver = null; - ... - - pattern-either: - - pattern: (XmlDocument $DOC).Load(...); - - pattern: (XmlDocument $DOC).LoadXml(...); - pattern-sources: - - pattern: var $DOC = new System.Xml.XmlDocument(...); - - patterns: - - pattern: var $DOC = new System.Xml.XmlDocument {...}; - - pattern-not: var $DOC = new System.Xml.XmlDocument {...,XmlResolver = null,...}; - severity: WARNING - - id: csharp_injection_rule-XmlReaderXXEInjection - languages: - - csharp - message: | - External XML entities are a feature of XML parsers that allow documents to contain references - to - other documents or data. This feature can be abused to read files, communicate with external - hosts, - exfiltrate data, or cause a Denial of Service (DoS). - - XML parsers and document loaders must be configured to not resolve entities. This can be done - by: - - Ensuring you are running a version of .NET Framework greater than 4.5.2 (released in 2014). - - Setting `XmlTextReader`'s `ProhibitDtd` to `true` - - Setting `XmlReaderSettings` `DtdProcessing` to `DtdProcessing.Prohibit` - - Example of safely loading an XML file using `XmlDocument`: - ``` - var settings = new XmlReaderSettings(); - settings.DtdProcessing = DtdProcessing.Prohibit; - XmlReader reader = XmlReader.Create(path, settings); - ``` - - For more information on XML security, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#net - metadata: - category: security - cwe: CWE-611 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference ('XXE') - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $SETTINGS.ProhibitDtd = false; - ... - - pattern-inside: | - $SETTINGS.DtdProcessing = DtdProcessing.Parse; - ... - - pattern: System.Xml.XmlReader.Create(..., $SETTINGS); - pattern-sources: - - pattern: var $SETTINGS = new XmlReaderSettings(); - severity: WARNING - - id: csharp_other_rule-UnsafeXSLTSettingUsed - languages: - - csharp - message: | - By setting `XsltSettings.EnableScript` to true, an adversary who is able to influence the - loaded - XSL document could directly inject code to compromise the system. It is strongly - recommended that an alternative approach is used to work with XML data. - - For increased security: - - - Never process user-supplied XSL style sheets - - Ensure `XsltSettings.EnableScript` is set to false - - Ensure `XsltSettings.EnableDocumentFunction` is set to false - - If the application must calculate values from XML input, instead of using XSL scripts to - execute functions, modify the XML document prior to running the - `XslCompiledTransform.Transform` method. - - Example of modifying the XML prior to running `Transform`: - ``` - const String filename = "number.xml"; - const String stylesheet = "calc.xsl"; - - // Compile the style sheet. - XsltSettings xslt_settings = new XsltSettings(); - xslt_settings.EnableScript = false; // disable script - xslt_settings.EnableDocumentFunction = false; // disable document() function - XslCompiledTransform xslt = new XslCompiledTransform(); - XmlResolver resolver = null; // set a null entity resolver - xslt.Load(stylesheet, xslt_settings, resolver); - - // Load the XML source file, using XDocument for safety - XDocument doc = XDocument.Load(filename); - - // do our modifications to the document before the transformation - // instead of inside of a script. - doc.Element("data").Add(new XElement("circle", new XElement("radius", 12))); - - // Create an XmlWriter. - XmlWriterSettings settings = new XmlWriterSettings(); - settings.OmitXmlDeclaration = true; - settings.Indent = true; - XmlWriter writer = XmlWriter.Create("output.xml", settings); - // Finally, execute the transformation. - xslt.Transform(doc.CreateReader(), writer); - writer.Close(); - ``` - - For more information on security considerations when using XSL see the following URLs: - - https://learn.microsoft.com/en-us/dotnet/standard/data/xml/xslt-security-considerations - - https://learn.microsoft.com/en-us/dotnet/api/system.xml.xsl.xslcompiledtransform?view=net-7.0#security-considerations - metadata: - category: security - cwe: CWE-91 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: XML injection (aka Blind XPath injection) - patterns: - - pattern-either: - - patterns: - - pattern: new XsltSettings() {...,$OPTIONS,...}; - - metavariable-pattern: - metavariable: $OPTIONS - pattern-either: - - pattern: EnableDocumentFunction = true - - pattern: EnableScript = true - - patterns: - - pattern: $SETTINGS.$OPT = true; - - pattern: | - var $SETTINGS = new XsltSettings(); - ... - $SETTINGS.$OPT = true; - - metavariable-pattern: - metavariable: $OPT - pattern-either: - - pattern: EnableDocumentFunction - - pattern: EnableScript - severity: WARNING - - id: csharp_password_rule-PasswordComplexity - languages: - - csharp - message: | - The application's `PasswordValidator.RequiredLength` property allows passwords - to be less than 8 characters. Consider requiring a length of at least 8 or more - characters to reduce the chance of passwords being brute forced. - - Example of setting the RequiredLength to 8 in ASP.NET Core Identity: - ``` - builder.Services.Configure(options => - { - // Default Password settings. - options.Password.RequireDigit = true; - options.Password.RequireLowercase = true; - options.Password.RequireNonAlphanumeric = true; - options.Password.RequireUppercase = true; - options.Password.RequiredLength = 8; - options.Password.RequiredUniqueChars = 1; - }); - ``` - - For more information on configuring ASP.NET Core Identity see: - https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-configuration - metadata: - category: security - cwe: CWE-521 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: Info - shortDescription: Weak password requirements - pattern-either: - - pattern: $OPT.Password.RequireDigit = false; - - pattern: $OPT.Password.RequireLowercase = false; - - pattern: $OPT.Password.RequireNonAlphanumeric = false; - - pattern: $OPT.Password.RequireUppercase = false; - - patterns: - - pattern: $OPT.Password.RequiredLength = $LEN; - - metavariable-comparison: - comparison: $LEN < 8 - metavariable: $LEN - - patterns: - - pattern: $OPT.Password.RequiredUniqueChars = $LEN; - - metavariable-comparison: - comparison: $LEN < 1 - metavariable: $LEN - severity: WARNING - - id: csharp_path_rule-PathTraversal - languages: - - csharp - message: | - The application dynamically constructs file or path information. If the path - information comes from user input, it could be abused to read sensitive files, - access other users data, or aid in exploitation to gain further system access. - - User input should never be used in constructing paths or files for interacting - with the filesystem. This includes filenames supplied by user uploads or downloads. - If possible consider hashing user input or replacing it with unique values and - use `System.IO.Path.GetFullPath` to resolve and validate the path information - prior to processing any file functionality. - - Example using `Path.GetFullPath` and not allowing direct user input: - ``` - // store user input alongside an ID we control - struct userData - { - public string userFilename; - public Guid id; - } - - class Program - { - public static void Main() - { - userData data = new userData(); - // user input, saved only as a reference - data.userFilename = "..\\test.txt"; - - // random id as the filename - data.id = Guid.NewGuid(); - - // restrict all file processing to this directory only - string basePath = "C:\\Restricted\\"; - - // resolve the full path, but only use our random generated id - string fullPath = Path.GetFullPath(basePath + data.id); - - // verify the path is contained within our basePath - if (!fullPath.StartsWith(basePath)) { - Console.WriteLine("Invalid path specified!"); - return; - } - // process / work with file - } - } - ``` - - For more information on path traversal issues see OWASP: - https://owasp.org/www-community/attacks/Path_Traversal - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - mode: taint - pattern-sanitizers: - - pattern-either: - - pattern: (Microsoft.Extensions.FileProviders.PhysicalFileProvider $E).GetFileInfo(...) - - pattern: (System.Web.HttpServerUtility $E).MapPath(...) - - pattern: (System.Web.HttpServerUtilityBase $E).MapPath(...) - - pattern: (System.Web.HttpRequest $E).MapPath(...) - pattern-sinks: - - pattern-either: - - pattern: System.IO.Directory.Delete(...) - - pattern: System.IO.Directory.GetFiles(...) - - pattern: System.IO.Directory.Move(...) - - pattern: System.IO.File.AppendAllLines(...) - - pattern: System.IO.File.AppendAllLinesAsync(...) - - pattern: System.IO.File.AppendAllText(...) - - pattern: System.IO.File.AppendAllTextAsync(...) - - pattern: System.IO.File.AppendText(...) - - pattern: System.IO.File.Copy(...) - - pattern: System.IO.File.Create(...) - - pattern: System.IO.File.CreateText(...) - - pattern: System.IO.File.Delete(...) - - pattern: System.IO.File.Move(...) - - pattern: System.IO.File.Open(...) - - pattern: System.IO.File.OpenRead(...) - - pattern: System.IO.File.OpenText(...) - - pattern: System.IO.File.OpenWrite(...) - - pattern: System.IO.File.ReadAllBytes(...) - - pattern: System.IO.File.ReadAllBytesAsync(...) - - pattern: System.IO.File.ReadAllLines(...) - - pattern: System.IO.File.ReadAllLinesAsync(...) - - pattern: System.IO.File.ReadAllText(...) - - pattern: System.IO.File.ReadAllTextAsync(...) - - pattern: System.IO.File.ReadLines(...) - - pattern: System.IO.File.Replace(...) - - pattern: System.IO.File.SetAccessControl(...) - - pattern: System.IO.File.WriteAllBytes(...) - - pattern: System.IO.File.WriteAllBytesAsync(...) - - pattern: System.IO.File.WriteAllLines(...) - - pattern: System.IO.File.WriteAllLinesAsync(...) - - pattern: System.IO.File.WriteAllText(...) - - pattern: System.IO.File.WriteAllTextAsync(...) - - pattern: new System.IO.FileInfo(...) - - pattern: (System.IO.FileInfo $E).CopyTo(...) - - pattern: (System.IO.FileInfo $E).MoveTo(...) - - pattern: (System.IO.FileInfo $E).Replace(...) - - pattern: System.Reflection.Assembly.LoadFile(...) - - pattern: System.Reflection.Assembly.LoadFrom(...) - - pattern: System.Reflection.Assembly.ReflectionOnlyLoadFrom(...) - - pattern: System.Reflection.Assembly.UnsafeLoadFrom(...) - - pattern: System.AppDomain.AppendPrivatePath(...) - - pattern: System.Xml.XmlReader.Create(...) - - pattern: new System.IO.StreamReader.ctor(...) - - pattern: new System.IO.StreamWriter.ctor(...) - - pattern: new System.IO.FileStream.ctor(...) - - pattern: new System.Web.Mvc.FilePathResult(...) - - pattern: new Microsoft.AspNetCore.Mvc.PhysicalFileResult(...) - - pattern: (Microsoft.AspNetCore.Mvc.RazorPages.PageModel $E).PhysicalFile(...) - - pattern: (System.Web.UI.WebControls.FileUpload $E).SaveAs(...) - - pattern: (System.Web.HttpResponse $E).TransmitFile(...) - - pattern: (System.Web.HttpResponse $E).WriteFile(...) - - pattern: (System.Web.HttpResponseBase $E).TransmitFile(...) - - pattern: (System.Web.HttpResponseBase $E).WriteFile(...) - - pattern: (System.IO.Compression.ZipFileExtensions $E).CreateEntryFromFile(...) - - pattern: (System.IO.Compression.ZipFileExtensions $E).ExtractToFile(...) - - pattern: (System.IO.Compression.ZipFileExtensions $E).ExtractToDirectory(...) - - pattern: (System.Net.WebClient $E).DownloadFile(...) - - pattern: (System.Net.WebClient $E).DownloadFileAsync(...) - - pattern: (System.Net.WebClient $E).DownloadFileTaskAsync(...) - pattern-sources: - - patterns: - - pattern-inside: | - public class $CLASS : Controller { - ... - } - - pattern: $PARAM - - pattern-either: - - patterns: - - metavariable-regex: - metavariable: $HTTP_ANNO - regex: ^(Http) - - pattern-inside: | - [$HTTP_ANNO] - public string $METHOD(...,$PARAM,...){...} - - pattern-inside: | - public IActionResult $METHOD(...,$PARAM,...){...} - severity: WARNING - - id: csharp_validation_rule-InputValidation - languages: - - csharp - message: | - By using the `[ValidateInput(false)]` attribute in a controller - class, the application will disable request validation for that - method. This disables ASP.NET from examining requests for injection - attacks such as Cross-Site-Scripting (XSS). - - If possible, re-enable validation by using `ValidateInput(true)`. - In some cases this may not be possible, in which case ensure how the - request data used is validated and this method does not - output user input directly into the view. - - For more information on protecting ASP.NET Core applications from XSS see: - https://learn.microsoft.com/en-us/aspnet/core/security/cross-site-scripting - - Example of enabling `ValidateInput` attribute: - ``` - class ControllerClass - { - [ValidateInput(true)] - public void SomeActionMethod() - { - } - } - ``` - - For more information on ASP.NET request validation see OWASP: - https://owasp.org/www-community/ASP-NET_Request_Validation - metadata: - category: security - cwe: CWE-554 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Info - shortDescription: ASP.NET input validation disabled - patterns: - - pattern: | - [ValidateInput(false)] - public $RET $FOO(...) - { - ... - } - severity: WARNING - - id: csharp_xss_rule-HtmlElementXss - languages: - - csharp - message: | - Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat - user input - as markup or script code. It is important to encode the data depending on the specific context - it - is used in. There are at least six context types: - - - Inside HTML tags `
    context 1
    ` - - Inside attributes: `
    ` - - Inside event attributes `` - - Inside script blocks: `` - - Unsafe element HTML assignment: `element.innerHTML = "context 5"` - - Inside URLs: `
    link` - User input that is displayed within the application must be encoded, sanitized or validated - to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be - taken - to not mix server-side templating with client-side templating, as the server-side templating - will - not encode things like {{ 7*7 }} which may execute client-side templating features. - - It is _NOT_ advised to encode user input prior to inserting into a data store. The data will - need to be - encoded depending on context of where it is output. It is much safer to force the displaying - system to - handle the encoding and not attempt to guess how it should be encoded. - - Consider using built-in framework capabilities for automatically encoding user input. - Depending - on output context, consider using the following `System.Text.Encodings.Web` encoders: - - - [HtmlEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.htmlencoder) - - [JavaScriptEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.javascriptencoder) - - [UrlEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.urlencoder) - - For more information on protecting ASP.NET Core applications from XSS see: - https://learn.microsoft.com/en-us/aspnet/core/security/cross-site-scripting#accessing-encoders-in-code - metadata: - category: security - cwe: CWE-79 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - mode: taint - pattern-sanitizers: - - patterns: - - metavariable-regex: - metavariable: $FUNC - regex: (SerializeObject|HtmlAttributeEncode|HtmlEncode|HtmlFormUrlEncode|UrlEncode|UrlPathEncode|XmlAttributeEncode|XmlEncode|Encode) - - pattern: $CLASS.$FUNC(...) - pattern-sinks: - - pattern: (System.Web.Mvc.HtmlHelper $E).Raw(...) - - pattern: (Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper $E).Raw(...) - - pattern: Response.Write(...) - - pattern: (System.Web.UI.HtmlTextWriter $E).AddAttribute(...) - - pattern: (System.Web.UI.HtmlTextWriter $E).AddStyleAttribute(...) - - pattern: (System.Web.UI.HtmlTextWriter $E).RenderBeginTag(...) - - pattern: (System.Web.UI.HtmlTextWriter $E).Write(...) - - pattern: (System.Web.UI.HtmlTextWriter $E).WriteAttribute(...) - - pattern: (System.Web.UI.HtmlTextWriter $E).WriteBeginTag(...) - - pattern: (System.Web.UI.HtmlTextWriter $E).WriteEndTag(...) - - pattern: (System.Web.UI.HtmlTextWriter $E).WriteFullBeginTag(...) - - pattern: (System.Web.UI.HtmlTextWriter $E).WriteStyleAttribute(...) - pattern-sources: - - patterns: - - pattern: $PARAM - - pattern-inside: | - $RET $METHOD(...,$PARAM,...){...} - - pattern: Request.Cookies[...] - - pattern: Request.Cookies.Get(...) - - pattern: Request.Form[...] - - pattern: Request.Form.Get(...) - - pattern: Request.Headers[...] - - pattern: Request.Headers.Get(...) - - pattern: Request.QueryString[...] - - pattern: Request.QueryString.Get(...) - - pattern: Request.Params[...] - - pattern: Request.RawUrl - - pattern: Request.Url - - pattern: Request.Path - - pattern: Request.Body - - pattern: $CTX.Request.Cookies[...] - - pattern: $CTX.Request.Cookies.Get(...) - - pattern: $CTX.Request.Form[...] - - pattern: $CTX.Request.Form.Get(...) - - pattern: $CTX.Request.Headers[...] - - pattern: $CTX.Request.Headers.Get(...) - - pattern: $CTX.Request.QueryString[...] - - pattern: $CTX.Request.QueryString.Get(...) - - pattern: $CTX.Request.Body - severity: WARNING - - id: csharp_xss_rule-ScriptXss - languages: - - csharp - message: | - Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat - user input - as markup or script code. It is important to encode the data depending on the specific context - it - is used in. - - User input that is used within the application scripts must be encoded, sanitized or validated - to ensure it cannot change the behavior of the Javascript code. - - It is _NOT_ advised to encode user input prior to inserting into a data store. The data will - need to be - encoded depending on context of where it is output. It is much safer to force the displaying - system to - handle the encoding and not attempt to guess how it should be encoded. - - Consider using built-in framework capabilities for automatically encoding user input. - Depending - on output context, consider using the following `System.Text.Encodings.Web` encoders: - - - [HtmlEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.htmlencoder) - - [JavaScriptEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.javascriptencoder) - - [UrlEncoder](https://learn.microsoft.com/en-us/dotnet/api/system.text.encodings.web.urlencoder) - - For more information on protecting ASP.NET Core applications from XSS see: - https://learn.microsoft.com/en-us/aspnet/core/security/cross-site-scripting#accessing-encoders-in-code - metadata: - category: security - cwe: CWE-79 - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - mode: taint - pattern-propagators: - - from: $IN - pattern: (StringBuilder $OUT).Append($IN) - to: $OUT - pattern-sanitizers: - - patterns: - - metavariable-regex: - metavariable: $FUNC - regex: (SerializeObject|HtmlAttributeEncode|HtmlEncode|HtmlFormUrlEncode|UrlEncode|UrlPathEncode|XmlAttributeEncode|XmlEncode|Encode) - - pattern: $CLASS.$FUNC(...) - pattern-sinks: - - pattern: $SCRIPTMANAGER.RegisterStartupScript(...) - - pattern: $SCRIPTMANAGER.RegisterClientScriptBlock(...) - - pattern: System.Web.UI.RegisterStartupScript(...) - - pattern: System.Web.UI.RegisterClientScriptBlock(...) - pattern-sources: - - patterns: - - pattern: $PARAM - - pattern-inside: | - $RET $METHOD(...,$PARAM,...){...} - - pattern: Request.Cookies[...] - - pattern: Request.Cookies.Get(...) - - pattern: Request.Form[...] - - pattern: Request.Form.Get(...) - - pattern: Request.Headers[...] - - pattern: Request.Headers.Get(...) - - pattern: Request.QueryString[...] - - pattern: Request.QueryString.Get(...) - - pattern: Request.Params[...] - - pattern: Request.RawUrl - - pattern: Request.Url - - pattern: Request.Path - - pattern: Request.Body - - pattern: $CTX.Request.Cookies[...] - - pattern: $CTX.Request.Cookies.Get(...) - - pattern: $CTX.Request.Form[...] - - pattern: $CTX.Request.Form.Get(...) - - pattern: $CTX.Request.Headers[...] - - pattern: $CTX.Request.Headers.Get(...) - - pattern: $CTX.Request.QueryString[...] - - pattern: $CTX.Request.QueryString.Get(...) - - pattern: $CTX.Request.Body - - pattern: $ELE.Text - severity: WARNING - - id: go_blocklist_rule-blocklist-des - languages: - - go - message: | - The DES algorithm has not been recommended for over 15 years and was withdrawn from NIST (FIPS - 46-3) in 2005. It is recommended that an algorithm that provides message integrity be used - instead. Consider using `XChaCha20Poly1305` or `AES-256-GCM`. - - For older applications, `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `XChaCha20Poly1305` - - Smaller nonce value size compared to `XChaCha20Poly1305` - - Catastrophic failure if nonce values are re-used - - Example using - [XChaCha20Poly1305](https://pkg.go.dev/golang.org/x/crypto/chacha20poly1305#NewX): - ``` - key := make([]byte, chacha20poly1305.KeySize) - if _, err := io.ReadFull(rand.Reader, key); err != nil { - log.Fatal(err) - } - - // NewX is a variant that uses longer nonce values for better security - aead, err := chacha20poly1305.NewX(key) - if err != nil { - log.Fatal(err) - } - - var encrypted = []byte{} - var nonce = []byte{} - - // Encryption routine - { - msg := []byte("Some secret message") - nonce = make([]byte, aead.NonceSize()) - if _, err := io.ReadFull(rand.Reader, nonce); err != nil { - log.Fatal("failed to generate nonce") - } - - encrypted = aead.Seal(nil, nonce, msg, nil) - } - - // Decryption routine - { - if len(encrypted) < aead.NonceSize() { - log.Fatal("incorrect ciphertext length") - } - - msg, err := aead.Open(nil, nonce, encrypted, nil) - if err != nil { - log.Fatal(err) - } - fmt.Printf("Decrypted: %s\n", msg) - } - ``` - - Example using [AES-256-GCM](https://pkg.go.dev/crypto/cipher#NewGCM): - ``` - // 32 byte keys will configure AES-256 - key := make([]byte, 32) - if _, err := io.ReadFull(rand.Reader, key); err != nil { - log.Fatal(err) - } - - blockCipher, err := aes.NewCipher(key) - if err != nil { - log.Fatal(err) - } - - aead, err := cipher.NewGCM(blockCipher) - if err != nil { - log.Fatal(err) - } - - var encrypted = []byte{} - var nonce = []byte{} - // Encryption routine - { - msg := []byte("Some secret message") - // note that the key must be rotated every 2^32 random nonces used otherwise - // cipher text could be repeated - nonce = make([]byte, 12) - if _, err := io.ReadFull(rand.Reader, nonce); err != nil { - log.Fatal(err) - } - encrypted = aead.Seal(nil, nonce, msg, nil) - } - - // Decryption routine - { - msg, err := aead.Open(nil, nonce, encrypted, nil) - if err != nil { - log.Fatal(err) - } - fmt.Printf("Decrypted: %s\n", msg) - } - ``` - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern: | - import "crypto/des" - severity: WARNING - - id: go_blocklist_rule-blocklist-md5 - languages: - - go - message: | - The MD5 message-digest algorithm has been cryptographically broken and is unsuitable for - further use. The MD5 hash algorithm has been found to be vulnerable to producing collisions. - This means that two different values, when hashed, can lead to the same hash value. It is - recommended that the SHA-3 or BLAKE2 family of algorithms be used for non-password based - cryptographic hashes instead. For password based cryptographic hashes, consider using the - bcrypt or Argon2id family of cryptographic hashes. - - Hashing values using [BLAKE2](https://pkg.go.dev/golang.org/x/crypto/blake2b): - ``` - fileContents := []byte("some file contents to create hash for") - blake2bHasher, err := blake2b.New512(nil) - if err != nil { - log.Fatal(err) - } - hashedValue := blake2bHasher.Sum(fileContents) - fmt.Printf("%s\n", hex.EncodeToString(hashedValue)) - ``` - - Hashing and securely comparing passwords using - [Argon2id](https://pkg.go.dev/golang.org/x/crypto/argon2#hdr-Argon2id): - ``` - type argonParameters struct { - variant string - version int - memory uint32 - iterations uint32 - parallelism uint8 - saltLength uint32 - keyLength uint32 - } - - func (a argonParameters) StringFormat(salt, derivedKey []byte) string { - encodedSalt := base64.RawStdEncoding.EncodeToString(salt) - encodedKey := base64.RawStdEncoding.EncodeToString(derivedKey) - - return fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", - argon2.Version, - a.memory, - a.iterations, - a.parallelism, - encodedSalt, - encodedKey, - ) - } - - func main() { - // Initialize Argon2id parameters - p := argonParameters{ - memory: 64 * 1024, - iterations: 3, - parallelism: 2, - saltLength: 16, - keyLength: 32, - } - - // Generate random salt (to be stored alongside derived hash key) - salt := make([]byte, p.saltLength) - if _, err := io.ReadFull(rand.Reader, salt); err != nil { - log.Fatal(err) - } - - usersPassword := []byte("User's Very S3cur3P4ss@rd@#$%") - - var derivedKey []byte - // Create key hash derived from user's password - { - derivedKey = argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, - p.keyLength) - // store p.StringFormat(...) result in a data store... - fmt.Printf("%s\n", p.StringFormat(salt, derivedKey)) - } - - // Verify a user's password against key - { - keyToCompare := argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, - p.keyLength) - - // Use subtle.ConstantTimeCompare(..., ...) to ensure no side channel leaks used in timing - attacks - if subtle.ConstantTimeCompare(derivedKey, keyToCompare) == 1 { - fmt.Printf("Passwords match\n") - } else { - fmt.Printf("Passwords do not match\n") - } - } - } - ``` - - For more information on password storage see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern: | - import "crypto/md5" - severity: WARNING - - id: go_blocklist_rule-blocklist-rc4 - languages: - - go - message: | - The RC4 stream-cipher has been cryptographically broken and is unsuitable - for use in production. It is recommended that ChaCha20 or Advanced Encryption - Standard (AES) be used instead. Consider using `XChaCha20Poly1305` or `AES-256-GCM`. - - For older applications, `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `XChaCha20Poly1305` - - Smaller nonce value size compared to `XChaCha20Poly1305` - - Catastrophic failure if nonce values are re-used - - Example using - [XChaCha20Poly1305](https://pkg.go.dev/golang.org/x/crypto/chacha20poly1305#NewX): - ``` - key := make([]byte, chacha20poly1305.KeySize) - if _, err := io.ReadFull(rand.Reader, key); err != nil { - log.Fatal(err) - } - - // NewX is a variant that uses longer nonce values for better security - aead, err := chacha20poly1305.NewX(key) - if err != nil { - log.Fatal(err) - } - - var encrypted = []byte{} - var nonce = []byte{} - - // Encryption routine - { - msg := []byte("Some secret message") - nonce = make([]byte, aead.NonceSize()) - if _, err := io.ReadFull(rand.Reader, nonce); err != nil { - log.Fatal("failed to generate nonce") - } - - encrypted = aead.Seal(nil, nonce, msg, nil) - } - - // Decryption routine - { - if len(encrypted) < aead.NonceSize() { - log.Fatal("incorrect ciphertext length") - } - - msg, err := aead.Open(nil, nonce, encrypted, nil) - if err != nil { - log.Fatal(err) - } - fmt.Printf("Decrypted: %s\n", msg) - } - ``` - - Example using [AES-256-GCM](https://pkg.go.dev/crypto/cipher#NewGCM): - ``` - // 32 byte keys will configure AES-256 - key := make([]byte, 32) - if _, err := io.ReadFull(rand.Reader, key); err != nil { - log.Fatal(err) - } - - blockCipher, err := aes.NewCipher(key) - if err != nil { - log.Fatal(err) - } - - aead, err := cipher.NewGCM(blockCipher) - if err != nil { - log.Fatal(err) - } - - var encrypted = []byte{} - var nonce = []byte{} - // Encryption routine - { - msg := []byte("Some secret message") - // note that the key must be rotated every 2^32 random nonces used otherwise - // cipher text could be repeated - nonce = make([]byte, 12) - if _, err := io.ReadFull(rand.Reader, nonce); err != nil { - log.Fatal(err) - } - encrypted = aead.Seal(nil, nonce, msg, nil) - } - - // Decryption routine - { - msg, err := aead.Open(nil, nonce, encrypted, nil) - if err != nil { - log.Fatal(err) - } - fmt.Printf("Decrypted: %s\n", msg) - } - ``` - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern: | - import "crypto/rc4" - severity: WARNING - - id: go_blocklist_rule-blocklist-sha1 - languages: - - go - message: | - The SHA-1 message-digest algorithm has been cryptographically broken and - is unsuitable for further use. It is - recommended that the SHA-3, or BLAKE2 family of algorithms be used for non-password based - cryptographic hashes instead. For password based cryptographic hashes, consider using the - bcrypt or Argon2id family of cryptographic hashes. - - Hashing values using [BLAKE2](https://pkg.go.dev/golang.org/x/crypto/blake2b): - ``` - fileContents := []byte("some file contents to create hash for") - blake2bHasher, err := blake2b.New512(nil) - if err != nil { - log.Fatal(err) - } - hashedValue := blake2bHasher.Sum(fileContents) - fmt.Printf("%s\n", hex.EncodeToString(hashedValue)) - ``` - - Hashing and securely comparing passwords using - [Argon2id](https://pkg.go.dev/golang.org/x/crypto/argon2#hdr-Argon2id): - ``` - type argonParameters struct { - variant string - version int - memory uint32 - iterations uint32 - parallelism uint8 - saltLength uint32 - keyLength uint32 - } - - func (a argonParameters) StringFormat(salt, derivedKey []byte) string { - encodedSalt := base64.RawStdEncoding.EncodeToString(salt) - encodedKey := base64.RawStdEncoding.EncodeToString(derivedKey) - - return fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", - argon2.Version, - a.memory, - a.iterations, - a.parallelism, - encodedSalt, - encodedKey, - ) - } - - func main() { - // Initialize Argon2id parameters - p := argonParameters{ - memory: 64 * 1024, - iterations: 3, - parallelism: 2, - saltLength: 16, - keyLength: 32, - } - - // Generate random salt (to be stored alongside derived hash key) - salt := make([]byte, p.saltLength) - if _, err := io.ReadFull(rand.Reader, salt); err != nil { - log.Fatal(err) - } - - usersPassword := []byte("User's Very S3cur3P4ss@rd@#$%") - - var derivedKey []byte - // Create key hash derived from user's password - { - derivedKey = argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, - p.keyLength) - // store p.StringFormat(...) result in a data store... - fmt.Printf("%s\n", p.StringFormat(salt, derivedKey)) - } - - // Verify a user's password against key - { - keyToCompare := argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, - p.keyLength) - - // Use subtle.ConstantTimeCompare(..., ...) to ensure no side channel leaks used in timing - attacks - if subtle.ConstantTimeCompare(derivedKey, keyToCompare) == 1 { - fmt.Printf("Passwords match\n") - } else { - fmt.Printf("Passwords do not match\n") - } - } - } - ``` - - For more information on password storage see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern: | - import "crypto/sha1" - severity: WARNING - - id: go_crypto_rule-badtlssettings - languages: - - go - message: | - Usage of a cryptographically insecure cipher suite has been detected. It is recommended that - alternative ciphers be used instead. It is strongly recommended that all TLS connections - use TLS 1.3 as Go will automatically choose the most secure cipher when negotiating the - TLS handshake with client or servers. TLS 1.3 cipher suites are configured to require Perfect - Forward Secrecy (PFS). - PFS is an important property as it will ensure that past encrypted transmissions could not be - decrypted - if the TLS certificate was compromised. - - Example using TLS 1.3 for a Go server: - ``` - cert, err := tls.LoadX509KeyPair("server.crt", "server.key") - if err != nil { - log.Fatal(err) - } - - cfg := &tls.Config{Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS13} - srv := &http.Server{ - Addr: ":8999", - TLSConfig: cfg, - ReadTimeout: time.Minute, - WriteTimeout: time.Minute, - } - log.Fatal(srv.ListenAndServeTLS("", "")) - ``` - - If TLS 1.0-1.2 must be used, then the following list of ciphers should be chosen as they - support - Perfect Forward Secrecy (PFS): - - - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 - - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 - - - Example `tls.Config` using the recommended cipher suites: - ``` - cfg := &tls.Config{ - MinVersion: tls.VersionTLS12, - CipherSuites: []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, - tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, - }, - } - ``` - - For more information on cipher suites in Go see: https://go.dev/blog/tls-cipher-suites - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: | - tls.Config{..., CipherSuites: []$SLICE{..., $CIPHERS, ...}, ...} - - pattern: | - tls.CipherSuite{..., ID: $CIPHERS, ...} - - metavariable-regex: - metavariable: $CIPHERS - regex: ((?!tls.TLS_AES_128_GCM_SHA256)|(?!tls.TLS_AES_256_GCM_SHA384)|(?!tls.TLS_CHACHA20_POLY1305_SHA256)| (?!tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)|(?!tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)| (?!tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)|(?!tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)| (?!tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305)|(?!tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)| (?!tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305)|(?!tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)| (?!tls.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)|(?!tls.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384)) - severity: WARNING - - id: go_crypto_rule-insecure-ignore-host-key - languages: - - go - message: | - The application was found to ignore host keys. Host keys are important as - they provide assurance that the client can prove that the host is trusted. - By ignoring these host keys, it is impossible for the client to validate the - connection is to a trusted host. - - For the `ssh.ClientConfig` `HostKeyCallback` property, consider using the - [knownhosts](https://pkg.go.dev/golang.org/x/crypto/ssh/knownhosts) package that - parses OpenSSH's `known_hosts` key database. - - Example configuration connecting to a known, trusted host: - ``` - knownHostCallback, err := knownhosts.New("/home/user/.ssh/known_hosts") - if err != nil { - log.Fatal(err) - } - - // Create client config using the knownHost callback function - config := &ssh.ClientConfig{ - ... - HostKeyCallback: knownHostCallback, - } - - // Connect to ssh server - conn, err := ssh.Dial("tcp", "localhost:22", config) - if err != nil { - log.Fatal("unable to connect: ", err) - } - defer conn.Close() - ``` - metadata: - category: security - cwe: CWE-322 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: Medium - shortDescription: Key exchange without entity authentication - patterns: - - pattern: ssh.InsecureIgnoreHostKey(...) - severity: WARNING - - id: go_crypto_rule-tlsversion - languages: - - go - message: "TLS versions 1.1 and 1.0 were deprecated by the IETF in June 2018 due to \na number of attacks against the vulnerable versions. Use of a deprecated \nTLS version may result in the unauthorized retrieval of sensitive \ninformation. It is strongly recommended that all TLS connections\nuse TLS 1.3 as Go will automatically choose the most secure cipher when \nnegotiating the TLS handshake with client or servers. TLS 1.3 cipher suites \nare configured to require Perfect Forward Secrecy (PFS). PFS is an important \nproperty as it will ensure that past encrypted transmissions could not be\ndecrypted if the TLS certificate was compromised.\n\nExample using TLS 1.3 for a Go server:\n```\ncert, err := tls.LoadX509KeyPair(\"server.crt\", \"server.key\")\nif err != nil {\n log.Fatal(err)\n}\n\ncfg := &tls.Config{Certificates: []tls.Certificate{cert}, \n MinVersion: tls.VersionTLS13}\n\nsrv := &http.Server{\n Addr: \":8999\",\n TLSConfig: cfg,\n ReadTimeout: time.Minute,\n WriteTimeout: time.Minute,\n}\nlog.Fatal(srv.ListenAndServeTLS(\"cert.pem\", \"key.pem\"))\n```\n" - metadata: - category: security - cwe: CWE-310 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of deprecated TLS version - pattern-either: - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - tls.Config{...} - - pattern: | - MinVersion: $VAL - - patterns: - - pattern-inside: | - $VAR = uint16($VAL) - ... - - pattern-inside: | - tls.Config{...} - - pattern: | - MinVersion: $VAR - - metavariable-pattern: - metavariable: $VAL - pattern-either: - - pattern: tls.VersionTLS11 - - pattern: tls.VersionTLS10 - - patterns: - - pattern-inside: | - tls.Config{...} - - pattern: | - MaxVersion: $ANYVAL - - pattern-not-inside: | - tls.Config{..., MinVersion: ..., ...} - severity: WARNING - - id: go_crypto_rule-weakkeystrength - languages: - - go - message: | - The application is generating an RSA key that is less than the recommended 2048 bits. - The National Institute of Standards and Technology (NIST) deprecated signing Digital - Certificates that contained RSA Public Keys of 1024 bits in December 2010. While - 1024-bit RSA keys have not been factored yet, advances in compute may make it possible - in the near future. - - To generate an RSA key of 2048 pass the number of bits as the second parameter to - the `rsa.GenerateKey` function: - ``` - import ( - "crypto/rand" - "crypto/rsa" - ) - - func generate() { - key, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - log.Fatal(err) - } - } - ``` - metadata: - category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Inadequate encryption strength - patterns: - - pattern-either: - - pattern: | - rsa.GenerateKey(..., $ARG) - - metavariable-comparison: - comparison: $ARG < 2048 - metavariable: $ARG - severity: WARNING - - id: go_crypto_rule-weakrandsource - languages: - - go - message: | - Go's `math/rand` is not meant for use in generating random numbers for any cryptographic or - security sensitive context. This includes generating random numbers that could be used in - user specific identifiers or where the random number that is generated is considered to - be secret. - - Replace all imports of `math/rand` with `crypto/rand`. - metadata: - category: security - cwe: CWE-338 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of cryptographically weak Pseudo-Random Number Generator (PRNG) - patterns: - - patterns: - - pattern-inside: | - import $IMPORT "math/rand" - ... - - pattern-not-inside: | - import "crypto/rand" - - pattern-either: - - pattern: $IMPORT.$METHOD(...) - - pattern: rand.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (Float32|Float64|Int31|Int31n|Int63|Int63n|NormalFloat64|Uint32|Uint64) - severity: WARNING - - id: go_file-permissions_rule-fileperm - languages: - - go - message: | - The application was found setting file permissions to overly permissive values. Consider - using the following values if the application user is the only process to access - the file: - - - 0400 - read only access to the file - - 0200 - write only access to the file - - 0600 - read/write access to the file - - Example creating a file with read/write permissions for the application user: - ``` - f, err := os.OpenFile("file.txt", os.O_CREATE, 0600) - if err != nil { - log.Fatal(err) - } - defer f.Close() - // continue to work with file here - ``` - - For all other values please see: - https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation - metadata: - category: security - cwe: CWE-732 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Incorrect permission assignment for critical resource - patterns: - - pattern-either: - - pattern: os.Chmod(...,$MASK) - - pattern: os.OpenFile(...,$MASK) - - pattern: os.WriteFile(...,$MASK) - - metavariable-comparison: - base: 8 - comparison: $MASK > 0o640 - metavariable: $MASK - severity: WARNING - - id: go_file-permissions_rule-mkdir - languages: - - go - message: | - The application was found setting directory permissions to overly permissive values. Consider - using the following values if the application user is the only process to access - files in the directory specified: - - 0700 - read/write access to the files in the directory - - Another common value is `0750` which allows the application user read/write access and group - users to read the files contained in the directory. - - Example creating a directory with read/write permissions for only the application user: - ``` - err := os.Mkdir("directory", 0700) - if err != nil { - log.Fatal(err) - } - ``` - - For all other values please see: - https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation - metadata: - category: security - cwe: CWE-732 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Incorrect permission assignment for critical resource - patterns: - - pattern-either: - - pattern: os.Mkdir(...,$MASK) - - pattern: os.MkdirAll(...,$MASK) - - metavariable-comparison: - base: 8 - comparison: $MASK > 0o750 - metavariable: $MASK - severity: WARNING - - id: go_filesystem_rule-decompression-bomb - languages: - - go - message: | - Directly decompressing files or buffers may lead to a potential Denial of Service (DoS) - due to a decompression bomb. Decompression bombs are maliciously compressed files - or data that decompresses to extremely large sizes. This can cause the process to run - out of memory, or the disk to fill up. - - To protect against decompression bombs, an - [io.LimitReader(...)](https://pkg.go.dev/io#LimitReader) - should be used to limit how much can be read during the decompression routine. - - Example using `io.LimitReader` to protect against a decompression bomb: - ``` - f, err := os.Open("some.gz") - if err != nil { - log.Fatal(err) - } - - r, err := gzip.NewReader(f) - if err != nil { - log.Fatal(err) - } - - const oneMegabyte = 1024 * 1024 - limitedReader := io.LimitReader(r, oneMegabyte) - - // use limitedReader to stop copying after 1 MB - if _, err := io.Copy(os.Stdout, limitedReader); err != nil { - log.Fatal(err) - } - ``` - metadata: - category: security - cwe: CWE-409 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper handling of highly compressed data - mode: taint - pattern-sanitizers: - - patterns: - - pattern: io.LimitReader($TAINTED, ...) - - focus-metavariable: $TAINTED - pattern-sinks: - - patterns: - - pattern: io.Copy($DST, $TAINTED) - - focus-metavariable: $TAINTED - - patterns: - - pattern: io.CopyBuffer($DST, $TAINTED, $BUF) - - focus-metavariable: $TAINTED - pattern-sources: - - pattern: gzip.NewReader(...) - - pattern: zlib.NewReader(...) - - pattern: bzip2.NewReader(...) - - pattern: flate.NewReader(...) - - pattern: lzw.NewReader(...) - - pattern: tar.NewReader(...) - - pattern: zip.NewReader(...) - - pattern: zlib.NewReaderDict(...) - - pattern: flate.NewReaderDict(...) - - pattern: zip.OpenReader(...) - severity: WARNING - - id: go_filesystem_rule-fileread - languages: - - go - message: | - The application dynamically constructs file or path information. If the path - information comes from user input, it could be abused to read sensitive files, - access other users data or aid in exploitation to gain further system access. - - User input should never be used in constructing paths or files for interacting - with the filesystem. This includes filenames supplied by user uploads or downloads. - If possible, consider hashing user input or replacing it with unique values. - Additionally, use `filepath.Base` to only use the filename and not path information. - Always validate the full path prior to opening or writing to any file. - - Example using `filepath.Base`, generating a unique filename without using - user input to construct filepath information: - ``` - type userData struct { - id string - userFilename string - } - - func newUserData(userFilename string) userData { - return userData{ - id: randomFileID(), // random id as the filename - userFilename: userFilename, - } - } - - // randomFileID generates a random id, to be used as a filename - func randomFileID() string { - id := make([]byte, 16) - if _, err := io.ReadFull(rand.Reader, id); err != nil { - log.Fatal(err) - } - return hex.EncodeToString(id) - } - - func main() { - - // user input, saved only as a reference - data := newUserData("../../possibly/malicious") - - // restrict all file access to this path - const basePath = "/tmp/" - - // resolve the full path, but only use our random generated id - resolvedPath, err := filepath.Join(basePath, filepath.Base(data.id)) - if err != nil { - log.Fatal(err) - } - - // verify the path is prefixed with our basePath - if !strings.HasPrefix(resolvedPath, basePath) { - log.Fatal("path does not start with basePath") - } - // process / work with file - } - ``` - - For more information on path traversal issues see OWASP: - https://owasp.org/www-community/attacks/Path_Traversal - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: | - $CLEAN := $PKG.Clean(...) - ... - if !strings.HasPrefix($CLEAN, "...") {...} - - pattern: | - $CLEAN := $PKG.Clean(...) - ... - if strings.HasPrefix($CLEAN, "...") {...} - - pattern: | - $CLEAN := $PKG.Clean(...) - ... - if strings.HasPrefix($CLEAN, "...") == false {...} - - metavariable-regex: - metavariable: $PKG - regex: ^((file)?path)$ - pattern-sinks: - - pattern: os.OpenFile(...) - - pattern: os.Open(...) - - pattern: os.ReadFile(...) - - pattern: ioutil.ReadFile(...) - pattern-sources: - - pattern: os.Getenv(...) - - pattern: fmt.Sprintf(...) - - pattern: filepath.Join(...) - - pattern: path.Join(...) - - patterns: - - pattern-either: - - pattern: '... + $TAINTED' - - pattern: '... + $TAINTED + ...' - - pattern: $TAINTED + ... - - pattern-not: '"..." + $TAINTED' - - pattern-not: '"..." + $TAINTED + "..."' - - pattern-not: $TAINTED + "..." - - pattern-not: fmt.Sprintf("...", "...") - - patterns: - - pattern-either: - - pattern: | - ($REQUEST : *http.Request).$SOURCE_METHOD - - pattern: | - ($REQUEST : http.Request).$SOURCE_METHOD - - metavariable-regex: - metavariable: $SOURCE_METHOD - regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$ - severity: WARNING - - id: go_filesystem_rule-httprootdir - languages: - - go - message: | - The application is potentially exposing the entire filesystem by mounting the root - directory `/` to an HTTP handler function. Anyone who is able to access this HTTP - server may be able to access any file that the HTTP server has access to. - - Restrict the `http.Dir` path to only a specific folder instead of the entire - filesystem. - - Example server only allowing directory listing on a public directory: - ``` - const path = "/var/www/html/public" - fs := http.FileServer(http.Dir(path)) - log.Fatal(http.ListenAndServe(":9000", fs)) - ``` - metadata: - category: security - cwe: CWE-552 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Files or directories accessible to external parties - patterns: - - pattern-either: + django.http.HttpResponseRedirect(..., $INTERM, ...) - pattern: | - import $NET "net/http" + $DATA = request.$W.get(...) ... - $NET.Dir("/") + django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) - pattern: | - import "net/http" + $DATA = request.$W.get(...) ... - http.Dir("/") - severity: WARNING - - id: go_filesystem_rule-poorwritepermissions - languages: - - go - message: | - The application was found setting file permissions to overly permissive values. Consider - using the following values if the application user is the only process to access - the file: - - - 0400 - read only access to the file - - 0200 - write only access to the file - - 0600 - read/write access to the file - - Example writing file contents with read/write permissions for the application user: - ``` - dat := []byte("sensitive data") - if err := os.WriteFile("file.txt", dat, 0600); err != nil { - log.Fatal(err) - } - ``` - - For all other values please see: - https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation - metadata: - category: security - cwe: CWE-276 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Incorrect default permissions - patterns: - - pattern-either: + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) - pattern: | - ioutil.WriteFile(..., ..., $ARG) - - metavariable-comparison: - base: 8 - comparison: $ARG > 0o600 - metavariable: $ARG - severity: WARNING - - id: go_filesystem_rule-tempfiles - languages: - - go - message: | - The application was found creating files in shared system temporary directories - (`/tmp` or `/var/tmp`) without using the `os.CreateTemp` function. Depending - on how the application uses this temporary file, an attacker may be able to create - symlinks that point to other files prior to the application creating or writing - to the target file, leading to unintended files being created or overwritten. - - Example using `os.CreateTemp` in an application restricted directory: - ``` - // assumes /opt/appdir/ is chown'd to the running application user - if err := os.MkdirAll("/opt/appdir/restricted", 0700); err != nil { - log.Fatal(err) - } - - // create a temporary file in the restricted directory in the form of temp-952569059.txt - f, err := os.CreateTemp("/opt/appdir/restricted", "temp-*.txt") - if err != nil { - log.Fatal(err) - } - - defer f.Close() - // clean up on exit - defer os.Remove(f.Name()) - // work with file - ``` - metadata: - category: security - cwe: CWE-378 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Creation of temporary file with insecure permissions - patterns: - - pattern-either: + $DATA = request.$W.get(...) + ... + django.http.HttpResponseRedirect(..., $STR % $DATA, ...) - pattern: | - os.WriteFile("$ARG", ...) + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) - pattern: | - ioutil.WriteFile("$ARG", ...) + $DATA = request.$W.get(...) + ... + django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) - pattern: | - os.OpenFile("$ARG", <... os.O_CREATE ...>, ...) + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) - pattern: | - os.Create("$ARG") - - metavariable-regex: - metavariable: $ARG - regex: (/tmp/.*|/var/tmp/.*) - severity: WARNING - - id: go_filesystem_rule-ziparchive - languages: - - go - message: | - The application may be vulnerable to a path traversal if it extracts untrusted archive files. - This vulnerability is colloquially known as 'Zip Slip'. Archive files may contain folders - which, - when extracted, may write outside of the intended directory. This is exploited by including - path traversal characters such as `../../other/directory` to overwrite or place files in system - or application directories. - - Extra care must be taken when extracting archive files as there are numerous concerns: - - - Limit the size of the zip archive as it may contain "Zip Bombs", files that extract to - extremely - large sizes. - - If possible, generate unique filenames instead of using the archives file names, as it may be - possible for users to overwrite files if the filenames are the same. - - Validate file paths are written with a prefixed, known trusted directory. - - Only process regular files and not symbolic links, as some applications may attempt to - read/follow - the symbolic link, leading to arbitrary file read / write vulnerabilities. - - - Example of securely processing an archive file: - ``` - r, err := zip.OpenReader("trusted.zip") - if err != nil { - log.Fatal(err) - } - - // Ensure archive contains only the expected number of files - const expectedFileCount = 10 - if len(r.File) > expectedFileCount { - log.Fatalf("too many files in archive: %d\n", len(r.File)) - } - - // One approach is to sum up all files before attempting to process - // them. - const totalAllowedSize = 1024 * 1024 * 10 // 10MB - var totalSize uint64 - for _, f := range r.File { - totalSize += f.UncompressedSize64 - } - - if totalSize > totalAllowedSize { - log.Fatalf("archive exceeds total allowed size: %d\n", totalSize) - } - - // configure a max size per file allowed - const maxFileSize = 1024 * 1024 // 1 MB - - // set restricted basePath - const basePath = "/var/restricted/" - - // iterate over the files in the archive - for _, f := range r.File { - - // Ensure uncompressed size does not exceed our allowed file size - if f.UncompressedSize64 > maxFileSize { - log.Printf("skipping file as it exceeds maxFileSize: %s\n", f.Name) - continue - } - - // Ensure file is a regular file and not a symbolic link or has other mode type - // bits set - if !f.Mode().IsRegular() { - log.Printf("skipping non regular file: %s\n", f.Name) - continue - } - - // if possible consider not using the name at all, but generating a random id instead. - // If the filename must be used, extract the base name and not folder path information - name := filepath.Base(f.Name) - - // Join the file name to the basePath. - resolvedPath := filepath.Join(basePath, name) - - // Application must still verify the path is prefixed by the basePath - if !strings.HasPrefix(resolvedPath, basePath) { - log.Fatal("path does not start with basePath") - } - - // process / work with file - } - ``` - - If the application must process directory names as well, use the following code: - ``` - // Join the cleaned name to the basePath, note if 'name' starts with `../../` it - // will still allow for traversal, so you _must_ verify the path prefix below - resolvedPath := filepath.Join(basePath, filepath.Clean(name)) - - // Application must still verify the path is prefixed by the basePath - if !strings.HasPrefix(resolvedPath, basePath) { - log.Fatal("path does not start with basePath") - } - - // process / work with file - ``` - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: | - $CLEAN := $PKG.Clean(...) - ... - if !strings.HasPrefix($CLEAN, "...") {...} - - pattern: | - $CLEAN := $PKG.Clean(...) - ... - if strings.HasPrefix($CLEAN, "...") {...} - - pattern: | - $CLEAN := $PKG.Clean(...) - ... - if strings.HasPrefix($CLEAN, "...") == false {...} - - metavariable-regex: - metavariable: $PKG - regex: ^((file)?path)$ - pattern-sinks: - - pattern: filepath.Join(...) - pattern-sources: - - pattern: zip.OpenReader(...) - - pattern: tar.OpenReader(...) - severity: WARNING - - id: go_http_rule-http-serve - languages: - - go - message: | - Go's `net/http` serve functions may be vulnerable to resource consumption attacks if timeouts - are not properly configured - prior to starting the HTTP server. An adversary may open up thousands of connections but never - complete sending all data, - or never terminate the connections. This may lead to the server no longer accepting new - connections. - - To protect against this style of resource consumption attack, timeouts should be set in the - `net/http` server prior to calling - the listen or serve functions. What this means is that the default `http.ListenAndServe` and - `http.Serve` functions should not - be used in a production setting as they are unable to have timeouts configured. Instead a - custom `http.Server` object must be - created with the timeouts configured. - - Example setting timeouts on a `net/http` server: - ``` - // All values chosen below are dependent on application logic and - // should be tailored per use-case - srv := &http.Server{ - Addr: "localhost:8000", - // ReadHeaderTimeout is the amount of time allowed to read - // request headers. The connection's read deadline is reset - // after reading the headers and the Handler can decide what - // is considered too slow for the body. If ReadHeaderTimeout - // is zero, the value of ReadTimeout is used. If both are - // zero, there is no timeout. - ReadHeaderTimeout: 15 * time.Second, - - // ReadTimeout is the maximum duration for reading the entire - // request, including the body. A zero or negative value means - // there will be no timeout. - // - // Because ReadTimeout does not let Handlers make per-request - // decisions on each request body's acceptable deadline or - // upload rate, most users will prefer to use - // ReadHeaderTimeout. It is valid to use them both. - ReadTimeout: 15 * time.Second, - - // WriteTimeout is the maximum duration before timing out - // writes of the response. It is reset whenever a new - // request's header is read. Like ReadTimeout, it does not - // let Handlers make decisions on a per-request basis. - // A zero or negative value means there will be no timeout. - WriteTimeout: 10 * time.Second, - - // IdleTimeout is the maximum amount of time to wait for the - // next request when keep-alives are enabled. If IdleTimeout - // is zero, the value of ReadTimeout is used. If both are - // zero, there is no timeout. - IdleTimeout: 30 * time.Second, - } - - // For per request timeouts applications can wrap all `http.HandlerFunc(...)` in - // `http.TimeoutHandler`` and specify a timeout, but note the TimeoutHandler does not - // start ticking until all headers have been read. - - // Listen with our custom server with timeouts configured - if err := srv.ListenAndServe(); err != nil { - log.Fatal(err) - } - ``` - For more information on the `http.Server` timeouts, see: https://pkg.go.dev/net/http#Server - - For information on setting request based timeouts, see: - https://pkg.go.dev/net/http#TimeoutHandler - - For more information on the Slowloris attack see: - https://en.wikipedia.org/wiki/Slowloris_(computer_security) - metadata: - category: security - cwe: CWE-770 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Low - shortDescription: Allocation of resources without limits or throttling - patterns: - - pattern-inside: | - import "net/http" - ... - - pattern-either: - - pattern: http.ListenAndServe(...) - - pattern: http.ListenAndServeTLS(...) - - pattern: http.Serve(...) - - pattern: http.ServeTLS(...) - - patterns: - - pattern-not-inside: | - &http.Server{ - ..., - ReadHeaderTimeout: ..., - ..., - } - - pattern-not-inside: | - &http.Server{ - ..., - ReadTimeout: ..., - ..., - } - - pattern-not-inside: | - $S = &http.Server{ - ..., - } - $S.ReadHeaderTimeout = ... - ... - - pattern-not-inside: | - $S = &http.Server{ - ..., - } - $S.ReadTimeout = ... - ... - - pattern: | - &http.Server{ - ..., - } - severity: WARNING - - id: go_injection_rule-ssrf - languages: - - go - message: | - Server-Side-Request-Forgery (SSRF) exploits backend systems that initiate requests to third - parties. - If user input is used in constructing or sending these requests, an attacker could supply - malicious - data to force the request to other systems or modify request data to cause unwanted actions. - - Ensure user input is not used directly in constructing URLs or URIs when initiating requests - to third party - systems from back end systems. Care must also be taken when constructing payloads using user - input. Where - possible restrict to known URIs or payloads. Consider using a server side map where key's are - used to return - URLs such as `https://site/goto?key=1` where `{key: 1, url: 'http://some.url/', key: 2, url: - 'http://...'}`. - - If you must use user supplied input for requesting URLs, it is strongly recommended that the - HTTP client - chosen allows you to customize and block certain IP ranges at the network level. By blocking - RFC 1918 - addresses or other network address ranges, you can limit the severity of a successful SSRF - attack. Care must - also be taken to block certain protocol or address formatting such as IPv6. - - If you can not block address ranges at the client level, you may want to run the HTTP client - as a protected - user, or in a protected network where you can apply IP Table or firewall rules to block access - to dangerous - addresses. Finally, if none of the above protections are available, you could also run a - custom HTTP proxy - and force all requests through it to handle blocking dangerous addresses. - - Example HTTP client that disallows access to loopback and RFC-1918 addresses - ``` - // IsDisallowedIP parses the ip to determine if we should allow the HTTP client to continue - func IsDisallowedIP(hostIP string) bool { - ip := net.ParseIP(hostIP) - return ip.IsMulticast() || ip.IsUnspecified() || ip.IsLoopback() || ip.IsPrivate() - } - - // SafeTransport uses the net.Dial to connect, then if successful check if the resolved - // ip address is disallowed. We do this due to hosts such as localhost.lol being resolvable to - // potentially malicious URLs. We allow connection only for resolution purposes. - func SafeTransport(timeout time.Duration) *http.Transport { - return &http.Transport{ - DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - c, err := net.DialTimeout(network, addr, timeout) - if err != nil { - return nil, err - } - ip, _, _ := net.SplitHostPort(c.RemoteAddr().String()) - if IsDisallowedIP(ip) { - return nil, errors.New("ip address is not allowed") - } - return c, err - }, - DialTLS: func(network, addr string) (net.Conn, error) { - dialer := &net.Dialer{Timeout: timeout} - c, err := tls.DialWithDialer(dialer, network, addr, &tls.Config{}) - if err != nil { - return nil, err - } - - ip, _, _ := net.SplitHostPort(c.RemoteAddr().String()) - if IsDisallowedIP(ip) { - return nil, errors.New("ip address is not allowed") - } - - err = c.Handshake() - if err != nil { - return c, err - } - - return c, c.Handshake() - }, - TLSHandshakeTimeout: timeout, - } - } - - func httpRequest(requestUrl string) { - const clientConnectTimeout = time.Second * 10 - httpClient := &http.Client{ - Transport: SafeTransport(clientConnectTimeout), - } - resp, err := httpClient.Get(requestUrl) - if err != nil { - log.Fatal(err) - } - defer resp.Body.Close() - // work with resp - } - ``` - - For more information on SSRF see OWASP: - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery - metadata: - category: security - cwe: CWE-918 - owasp: - - A1:2017-Injection - - A10:2021-Server-Side Request Forgery - security-severity: Medium - shortDescription: Server Side Request Forgery (SSRF) - mode: taint - pattern-propagators: - - from: $P - pattern: $R := $D.NewDecoder($P) - to: $R - - from: $S - pattern: $S.Decode(&$P) - to: $P - - from: $S - pattern: $S.Decode($P) - to: $P - - from: $B - pattern: $S.Unmarshal($B, &$P) - to: $P - - from: $B - pattern: $S.Unmarshal($B, $P) - to: $P - pattern-sinks: - - pattern: http.Head(...) - - pattern: http.Get(...) - - pattern: http.Post(...) - - pattern: http.PostForm(...) - - pattern: http.NewRequest($METHOD,...) - - pattern: http.DefaultClient.Head(...) - - pattern: http.DefaultClient.Get(...) - - pattern: http.DefaultClient.Post(...) - - pattern: http.DefaultClient.PostForm(...) - - pattern: http.NewRequestWithContext($CONTEXT, $METHOD, ...) - - pattern: ftp.Dial(...) - - pattern: ldap.DialURL(...) - - pattern: smtp.Dial(...) - - pattern: retryablehttp.NewRequest($METHOD, ..., $BODY) - - patterns: - - pattern-inside: | - $C := retryablehttp.NewClient() + $DATA = request.$W.get(...) ... - - pattern-either: - - pattern: $C.Get(...) - - pattern: $C.Post(..., $BODYTYPE, $BODY) - - pattern: $C.PostForm(..., $VALS) - - pattern: $C.Head(...) - pattern-sources: - - patterns: - - pattern-not-inside: | - import "testing" + django.http.HttpResponseRedirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) ... - - pattern-either: - - pattern: os.Stdin - - pattern: os.Getenv(...) - - pattern: | - ($REQ: *http.Request).$ANY - - pattern: | - ($REQ: http.Request).$ANY - - patterns: - - pattern: '($REQ : *http.Request)' - - pattern-inside: | - func $FUNC( $W http.ResponseWriter, $R *http.Request, ...) { - ... - } - severity: WARNING - - id: go_injection_rule-template-injection - languages: - - go - message: | - Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat - user input - as markup or script code. It is important to encode the data depending on the specific context - it - is used in. There are at least six context types: - - - Inside HTML tags `
    context 1
    ` - - Inside attributes: `
    ` - - Inside event attributes `` - - Inside script blocks: `` - - Unsafe element HTML assignment: `element.innerHTML = "context 5"` - - Inside URLs: `link` - - Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if - user input - is ever output inside of script tags. - - User input that is displayed within the application must be encoded, sanitized or validated - to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be - taken - to not mix server-side templating with client-side templating, as the server-side templating - will - not encode things like {{ 7*7 }} which may execute client-side templating features. - - It is _NOT_ advised to encode user input prior to inserting into a data store. The data will - need to be - encoded depending on context of where it is output. It is much safer to force the displaying - system to - handle the encoding and not attempt to guess how it should be encoded. - - Use of the following template types with user input denotes a security risk: - - - [template.HTML](https://pkg.go.dev/html/template#HTML) - - [template.JS](https://pkg.go.dev/html/template#JS) - - [template.URL](https://pkg.go.dev/html/template#URL) - - [template.HTMLAttr](https://pkg.go.dev/html/template#HTMLAttr) - - Either remove these types from the application or hardcode as const strings prior - to conversion: - ``` - testTemplate, err := template.New("testTemplate").Funcs(template.FuncMap{ - "SafeHTML": func() template.HTML { - const safeHTML = "
    hardcoded, safe html
    " - return template.HTML(safeHTML) - }, - }).Parse(`{{ SafeHTML }}`) - if err != nil { - log.Fatal(err) - } - - if err := testTemplate.Execute(os.Stdout, nil); err != nil { - log.Fatal(err) - } - ``` - metadata: - category: security - cwe: CWE-79 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - patterns: - - pattern-either: - - patterns: - - pattern: template.HTML($IN) - - pattern-not: template.HTML("...") - - patterns: - - pattern: template.JS($IN) - - pattern-not: template.JS("...") - - patterns: - - pattern: template.URL($IN) - - pattern-not: template.URL("...") - - patterns: - - pattern: template.HTMLAttr($IN) - - pattern-not: template.HTMLAttr("...") - severity: WARNING - - id: go_leak_rule-pprof-endpoint - languages: - - go - message: | - Go has a built in profiling service that is enabled by starting an HTTP server with - `net/http/pprof` imported. The `/debug/pprof` endpoint does not require any - authentication and can be accessed by anonymous users. This profiling endpoint - can leak sensitive information and should not be enabled in production. - - To remediate this, remove the `net/http/pprof` import from the file. - metadata: - category: security - cwe: CWE-489 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Medium - shortDescription: Active debug code (pprof enabled) - patterns: - - pattern-inside: | - import ( - "net/http/pprof" - ) - ... - - pattern-either: - - pattern: http.ListenAndServe(...) - - pattern: http.ListenAndServeTLS(...) - - pattern: http.Serve(...) - - pattern: http.ServeTLS(...) - severity: ERROR - - id: go_memory_rule-integer-overflow - languages: - - go - message: | - Golang's `int` type size depends on the architecture of where the application is running. For - 32-bit systems, `int` is - 32-bit, for 64-bit systems, `int` will be 64-bit. By calling `strconv.Atoi` with a large - number, the integer may overflow - if the `int` return value is type converted into a smaller type (`int32` or `int16`). This - could cause unexpected application - behavior depending on how the resultant value is used. - - Prior to running any type conversion, check that the value returned from `strconv.Atoi` will - fit in the resulting integer. - - Example of checking the return value before type conversion: - ``` - bigValue, _ := strconv.Atoi("32768") - if bigValue > math.MaxInt16 { - log.Fatal("value too large to fit in int16") - } - value := int16(bigValue) - fmt.Println(value) - ``` - - For more information on integer min/max constants see: https://pkg.go.dev/math#pkg-constants - metadata: - category: security - cwe: CWE-190 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Integer overflow or wraparound - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $X, ... := strconv.Atoi(...) - ... - - pattern-either: - - pattern: int32($X) - - pattern: int16($X) - severity: ERROR - - id: go_memory_rule-memoryaliasing - languages: - - go - message: | - Go's `for ... range` statements create an iteration variable for each iteration of the loop. - By taking the address of this iteration variable, the value of the address will be re-used - and always point to the same location in memory. This can have unexpected behavior if the - address is stored or re-used. - - This can be fixed by: - - Not referencing the address of the variable - - Re-assigning the iteration variable to a new variable - - Using the address of the indexed variable - - Example not referencing the address: - ``` - type someStruct struct { - x int - } - - for _, n := range []someStruct{{1}, {2}, {3}, {4}} { - fmt.Printf("%d\n", n.x) - } - ``` - - Example reassigning the iteration variable to a new variable: - ``` - type someStruct struct { - x int - } - - for _, n := range []someStruct{{1}, {2}, {3}, {4}} { - p := n - fmt.Printf("%p\n", &p) - } - ``` - - Example using the address of the indexed variable: - ``` - type someStruct struct { - x int - } - - structData := []someStruct{{1}, {2}, {3}, {4}} - for idx := range structData { - fmt.Printf("%p\n", &structData[idx]) - } - ``` - - For more information on how the `for ... range` statement works see: - https://go.dev/ref/spec#For_statements - metadata: - category: security - cwe: CWE-118 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Info - shortDescription: Incorrect access of indexable resource ('Range Error') - patterns: - - pattern-either: + $INTERM = $STR + $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., request.$W.get(...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: return django.http.HttpResponseRedirect(..., request.$W.get(...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W.get(...), ...) + - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W.get(...)}...", ...) + - pattern: django.http.HttpResponseRedirect(..., request.$W(...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) + - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) - pattern: | - for ..., $ARG := range $SLICE { - <... &($ARG) ...> - } + $DATA = request.$W(...) + ... + django.http.HttpResponseRedirect(..., $DATA, ...) - pattern: | - for ..., $ARG := range $SLICE { - <... func() { <... &$ARG ...> } ...> - } + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) - pattern: | - for ..., $ARG := range $SLICE { - <... $X(..., <... &$ARG ...>, ...) ...> - } - - pattern-not: | - for ..., $ARG := range $SLICE { - <... *$ARG ...> - } - - pattern-not-inside: for ..., $ARG := range $SLICE { return ... } - severity: WARNING - - id: go_network_rule-bind-to-all-interfaces - languages: - - go - message: | - Binding to all network interfaces can potentially open up a service to - traffic on unintended interfaces, that may not be properly documented or - secured. By passing "0.0.0.0" as the address to the `Listen` family of functions, - the application will bind to all interfaces. - - Consider passing in the interface ip address through an environment variable, - configuration file, or by determining the primary interface(s) IP address. - - Example getting the IP address from an environment variable `IP_ADDRESS`: - ``` - addr := os.Getenv("IP_ADDRESS") - listener, err := net.Listen("tcp", addr) - if err != nil { - log.Fatal(err) - } - ``` - metadata: - category: security - cwe: CWE-1327 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Low - shortDescription: Binding to an unrestricted IP address - patterns: - - pattern-either: - - pattern: net.Listen(..., "$ADDR") - - pattern: tls.Listen(..., "$ADDR", ...) - - metavariable-regex: - metavariable: $ADDR - regex: ^(0\.0\.0\.0|\[::\])?(:[0-9]*)?$ - severity: WARNING - - id: go_sql_rule-concat-sqli - languages: - - go - message: | - SQL Injection is a critical vulnerability that can lead to data or system compromise. By - dynamically generating SQL query strings, user input may be able to influence the logic of - the SQL statement. This could lead to an adversary accessing information they should - not have access to or in some circumstances, being able to execute OS functionality or code. - - Replace all dynamically generated SQL queries with parameterized queries. In situations where - dynamic queries must be created, never use direct user input, but instead use a map or - dictionary of valid values and resolve them using a user supplied key. - - For example, some database drivers do not allow parameterized queries for `>` or `<` comparison - operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the - user - supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` - values to be used in the construction of the dynamic query. The same goes for other queries - where - column or table names are required but cannot be parameterized. - - Example using parameterized queries with `sql.Query`: - ``` - rows, err := db.Query("SELECT * FROM users WHERE userName = ?", userName) - if err != nil { - return nil, err - } - defer rows.Close() - for rows.Next() { - // ... process rows - } - ``` - - For more information on SQL Injection see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-89 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an SQL command ('SQL Injection') - mode: taint - pattern-sinks: - - patterns: - - pattern: $DB.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Exec(Context)?|Query(Context)?|QueryRow(Context)?)$ - pattern-sources: - - patterns: - - pattern: fmt.Sprintf(...) - - pattern-not: | - fmt.Sprintf("...", "...") - - patterns: + $DATA = request.$W(...) + ... + django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) - pattern: | - "..." + $X - - pattern-not: | - "..." + "..." - - pattern: | - ($SB : strings.Builder).String() - severity: WARNING - - id: go_subproc_rule-subproc - languages: - - go - message: | - OS command injection is a critical vulnerability that can lead to a full system - compromise as it may allow an adversary to pass in arbitrary commands or arguments - to be executed. - - User input should never be used in constructing commands or command arguments - to functions which execute OS commands. This includes filenames supplied by - user uploads or downloads. - - Ensure your application does not: - - - Use user-supplied information in the process name to execute. - - Use user-supplied information in an OS command execution function which does - not escape shell meta-characters. - - Use user-supplied information in arguments to OS commands. - - The application should have a hardcoded set of arguments that are to be passed - to OS commands. If filenames are being passed to these functions, it is - recommended that a hash of the filename be used instead, or some other unique - identifier. It is strongly recommended that a native library that implements - the same functionality be used instead of using OS system commands, due to the - risk of unknown attacks against third party commands. - - If operating in Windows environments, when specifying the OS command, ensure - the application uses the full path - information, otherwise the OS may attempt to look up which process to execute - and could be vulnerable to untrusted search path vulnerabilities (CWE-426). - - Example of safely executing an OS command: - ``` - userData := []byte("user data") - // create a temporary file in the application specific directory - f, err := ioutil.TempFile("/var/app/restricted", "temp-*.dat") - if err != nil { - log.Fatal(err) - } - - if _, err := f.Write(userData); err != nil { - log.Fatal(err) - } - - if err := f.Close(); err != nil { - log.Fatal(err) - } - - // pass the full path to the binary and the name of the temporary file - // instead of any user supplied filename - out, err := exec.Command("/bin/cat", f.Name()).Output() - if err != nil { - log.Fatal(err) - } - ``` - - For more information on OS command injection, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-78 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') - patterns: - - pattern-either: - - patterns: - - pattern: exec.CommandContext($CTX, $EXE, ...) - - pattern-not: exec.CommandContext($CTX, "...", ...) - - patterns: - - pattern: exec.Command($EXE, ...) - - pattern-not: exec.Command("...", ...) - - patterns: - - pattern: syscall.ForkExec($EXE, ...) - - pattern-not: syscall.ForkExec("...", ...) - - patterns: - - pattern: syscall.StartProcess($EXE, ...) - - pattern-not: syscall.StartProcess("...", ...) - severity: WARNING - - id: go_unsafe_rule-unsafe - languages: - - go - message: | - The `unsafe` package in Go allows low-level access to memory management features. - This includes pointers and direct access to memory. The Go compiler will no longer - be able to enforce type safety when working with the `unsafe` pointer types. - - While powerful, access to these functions can lead to many security related issues - such as: - - - [Buffer overflows](https://owasp.org/www-community/vulnerabilities/Buffer_Overflow) which - can lead to code execution. - - [Use after free](https://owasp.org/www-community/vulnerabilities/Using_freed_memory) which - can lead to code execution. - - [Information/Memory leaks](https://owasp.org/www-community/vulnerabilities/Memory_leak) - which can leak sensitive information, including data which can - defeat other protection mechanisms or cause the system to run out of memory. - - Unless required, all calls to the `unsafe` package should be removed. - metadata: - category: security - cwe: CWE-242 - owasp: - - A9:2017-Using Components with Known Vulnerabilities - - A06:2021-Vulnerable and Outdated Components - security-severity: High - shortDescription: Use of inherently dangerous function (unsafe package) - patterns: - - pattern-either: - - pattern: unsafe.Alignof(...) - - pattern: unsafe.Offsetof(...) - - pattern: unsafe.Sizeof(...) - - pattern: unsafe.Pointer(...) - severity: INFO - - id: java_cookie_rule-CookieInsecure - languages: - - java - message: | - The `Secure` attribute when set to `true` protects the cookie value from being being - transmitted over clear text - communication paths such as HTTP. By enabling this protection, the cookie will only be sent - over HTTPS. - - Example of protecting a `Cookie`: - ``` - // Create an Secure cookie. - Cookie someCookie = new Cookie("SomeCookieName", "SomeValue"); - // Set Secure flag to true - someCookie.setSecure(true); - ``` - - For more information see: - https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/http/cookie#setSecure-boolean- - - Session cookies should be configured with the following security directives: - - - [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - - [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) - - [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - metadata: - category: security - cwe: CWE-614 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Low - shortDescription: Sensitive cookie in HTTPS session without 'Secure' attribute - technology: - - java - patterns: - - pattern: | - $X.servlet.http.Cookie $C = new $X.servlet.http.Cookie(..., ...); - ... - ($X.servlet.http.HttpServletResponse $RESP).addCookie($C); - - pattern-not-inside: | - $X.servlet.http.Cookie $C = new $X.servlet.http.Cookie(..., ...); - ... - $C.setSecure(true); - ... - ($X.servlet.http.HttpServletResponse $RESP).addCookie($C); - severity: WARNING - - id: java_cookie_rule-HttpResponseSplitting - languages: - - java - message: | - HTTP Response Splitting is a vulnerability where Carriage Return (CR `\r`) and Line Feed (LF - `\n`) - characters are introduced into an HTTP header from user-supplied input. By injecting the - `\r\n` - character sequence, an adversary could potentially modify how the response is interpreted by - the - client or any downstream caching services. This could allow an adversary to poison the cache - data or execute Cross-Site Scripting (XSS) attacks. - - Some Java application servers such as [Apache Tomcat](https://tomcat.apache.org/) as of version - 8.0, newer versions of Jetty and other servers that implement the [RFC 6265 Standard](https://datatracker.ietf.org/doc/html/rfc6265) will - disallow `\r' and '\n` characters characters from being set in cookies. If your application server does not - automatically provide this functionality, user-supplied input that is used in cookie keys or - values must be validated. - - Example of validating cookies to only allow valid characters: - ``` - // throws an IllegalArgumentException if the provided value contains invalid characters - public void validateRfc6265CookieValue(String value) throws IllegalArgumentException { - char[] chars = value.toCharArray(); - - // iterate over every character - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - - // check for any characters below 0x21 as well as: '"' ',' ';' '\' and 0x7f. - if (c < 0x21 || c == '"' || c == ',' || c == ';' || c == '\\' || c == 0x7f) { - throw new IllegalArgumentException("Invalid character in cookie detected: - {0}".format(Integer.toString(c))); - } - } - } - ``` - - Alternatively, you could use a string escape package such as - [Apache Commons Text](https://commons.apache.org/proper/commons-text/) to escape the input: - ``` - public String escapeValue(String value) { - return StringEscapeUtils.escapeJava(value); - } - ``` - - For more information on response splitting attacks see OWASP: - https://owasp.org/www-community/attacks/HTTP_Response_Splitting - metadata: - category: security - cwe: CWE-113 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') - technology: - - java - mode: taint - pattern-sanitizers: - - patterns: - - pattern-inside: | - $STR.replaceAll($REPLACER, "..."); + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseRedirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." ... - - pattern: $STR - - metavariable-regex: - metavariable: $REPLACER - regex: .*\[(?=.*\\r)(?=.*\\n).*\]\+ - - pattern: org.apache.commons.text.StringEscapeUtils.escapeJava($STR); - pattern-sinks: - - pattern: new javax.servlet.http.Cookie("$KEY", ...); - - patterns: - - pattern-inside: | - $C = new javax.servlet.http.Cookie("$KEY", ...); + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) ... - - pattern: $C.setValue(...); - pattern-sources: - - pattern: (javax.servlet.http.HttpServletRequest $REQ).getParameter(...); - - pattern: (javax.servlet.http.HttpServletRequest $REQ).getParameterNames(); - - pattern: (javax.servlet.http.HttpServletRequest $REQ).getParameterValues(...); - - pattern: (javax.servlet.http.HttpServletRequest $REQ).getParameterMap(); - - pattern: (javax.servlet.http.HttpServletRequest $REQ).getHeader(...); - - pattern: (javax.servlet.http.HttpServletRequest $REQ).getPathInfo(); - severity: WARNING - - id: java_cookie_rule-RequestParamToHeader - languages: - - java - message: | - HTTP Response Splitting is a vulnerability where Carriage Return (CR `\r`) and Line Feed (LF - `\n`) - characters are introduced into an HTTP header from user-supplied input. By injecting the - `\r\n` - character sequence, an adversary could potentially modify how the response is interpreted by - the - client or any down stream caching services. This could allow an adversary to poison the cache - data or execute Cross-Site Scripting (XSS) attacks. - - Some Java application servers such as [Apache Tomcat](https://tomcat.apache.org/) will - automatically encode - characters from being set in response headers as a space `0x20` character. If your application - server does - not automatically provide this functionality, user-supplied input that is used in header keys - or values must be - validated. - - Example of validating headers to only allow valid characters: - ``` - // throws an IllegalArgumentException if the provided value contains invalid characters - public void validateHeader(String value) throws IllegalArgumentException { - char[] chars = value.toCharArray(); - - // iterate over every character - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - - // check for any characters below 0x21 as well as: '"' ',' ';' '\' and 0x7f. - if (c < 0x21 || c == '"' || c == ',' || c == ';' || c == '\\' || c == 0x7f) { - throw new IllegalArgumentException("Invalid character in cookie detected: - {0}".format(Integer.toString(c))); - } - } - } - ``` - - Alternatively, you could use a string escape package such as - [Apache Commons Text](https://commons.apache.org/proper/commons-text/) to escape the input: - ``` - public String escapeValue(String value) { - return StringEscapeUtils.escapeJava(value); - } - ``` - - For more information on response splitting attacks see OWASP: - https://owasp.org/www-community/attacks/HTTP_Response_Splitting - metadata: - category: security - cwe: CWE-113 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') - technology: - - java - mode: taint - pattern-sanitizers: - - patterns: - - pattern-inside: | - $STR.replaceAll("$INPUT", "..."); + django.http.HttpResponseRedirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) ... - - pattern: $STR - - metavariable-regex: - metavariable: $INPUT - regex: .*\[(?=.*\\r)(?=.*\\n).*\]\+ - - pattern: org.apache.commons.text.StringEscapeUtils.unescapeJava(...); - pattern-sinks: - - pattern: ($X.servlet.http.HttpServletResponse $RES).setHeader("$KEY", ...); - - pattern: ($X.servlet.http.HttpServletResponse $RES).addHeader("$KEY", ...); - - pattern: ($X.servlet.http.HttpServletResponseWrapper $WRP).setHeader("$KEY", ...); - - pattern: ($X.servlet.http.HttpServletResponseWrapper $WRP).addHeader("$KEY", ...); - pattern-sources: - - pattern: ($X.servlet.http.HttpServletRequest $REQ).getParameter(...); - - pattern: ($X.servlet.http.HttpServletRequest $REQ).getParameterNames(); - - pattern: ($X.servlet.http.HttpServletRequest $REQ).getParameterValues(...); - - pattern: ($X.servlet.http.HttpServletRequest $REQ).getParameterMap(); - - pattern: ($X.servlet.http.HttpServletRequest $REQ).getHeader(...); - - pattern: ($X.servlet.http.HttpServletRequest $REQ).getPathInfo(); - severity: ERROR - - id: java_cors_rule-PermissiveCORSInjection - languages: - - java - message: | - This application potentially allows user-supplied input into the value of the - `Access-Control-Allow-Origin` response header. This header is part of the - [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) CORS - specification. By allowing user input to specify which domains can communicate with this - server, - an adversary could exploit a weakness in this server to force clients to send credentials (such - as session - identifiers) to the adversary's server. - - For the above attack to work, the application would need to suffer from an additional - vulnerability, - such as Cross-Site Scripting (XSS). - - To remediate this issue, do not use user-supplied information when calling - `HttpServletResponse.setHeader` or `HttpServletResponse.addHeader` - for the `Access-Control-Allow-Origin` header's value. Instead, hardcode the allowed domain(s) - and reference them in a lookup - table: - Example allowing dynamic but safe domains in `Access-Control-Allow-Origin`: - - ``` - // this data should be in the class constructor or taken from a trusted datasource - Map allowedDomains = new HashMap(); - allowedDomains.put("sub1", "sub1.example.com"); - allowedDomains.put("sub2", "sub2.example.com"); - - // extract the allowedDomain parameters value as a key to look up which domain to provide - via the allowedDomains map - // if not found, sets sub1 as the default - String headerValue = allowedDomains.getOrDefault(request.getParameter("allowedDomain"), - allowedDomains.get("sub1")); - - // add the header with our trusted sub1.example.com or sub2.example.com domains. - response.addHeader("Access-Control-Allow-Origin", headerValue); - } - ``` - - For more information on `Access-Control-Allow-Origin` see: - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin - metadata: - category: security - cwe: CWE-942 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Low - shortDescription: Permissive cross-domain policy with untrusted domains - technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: (HttpServletResponse $RES).setHeader("$HEADER", ...) - - pattern: (HttpServletResponse $RES).addHeader("$HEADER", ...) - - metavariable-regex: - metavariable: $HEADER - regex: (?i)(Access-Control-Allow-Origin) - pattern-sources: - - pattern: (HttpServletRequest $REQ).getParameter(...) - - pattern: (HttpServletRequest $REQ).getHeader(...) - - pattern: (HttpServletRequest $REQ).getPathInfo() - - pattern: (HttpServletRequest $REQ).getQueryString() - - pattern: (HttpServletRequest $REQ).getAttribute(...) - - pattern: (HttpServletRequest $REQ).getSession().getAttribute(...) - - pattern: (HttpServletRequest $REQ).getServletContext().getAttribute(...) - - pattern: (HttpServletRequest $REQ).getParameterValues(...) - - pattern: (HttpServletRequest $REQ).getParameterNames() - - pattern: (HttpServletRequest $REQ).getParameterMap() - severity: ERROR - - id: java_crypto_rule-BlowfishKeySize - languages: - - java - message: | - The Blowfish encryption algorithm was meant as a drop-in replacement for DES and was created in - 1993. Smaller key sizes may make the ciphertext vulnerable to [birthday - attacks](https://en.wikipedia.org/wiki/Birthday_attack). While no known attacks against - Blowfish - exist, it should never be used to encrypt files over 4GB in size. If possible consider - using AES as the instance of `KeyGenerator` instead of Blowfish. - - To remediate the small key size, pass a value such as 256 to the `KeyGenerator.init(keySize)` - method. - - Example setting a larger key size and changing to `KeyGenerator` to AES: - ``` - public static void aesKeyGenerator() throws java.security.NoSuchAlgorithmException { - // Use the AES algorithm for key generation - KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); - - // Set the key size here - keyGenerator.init(256); - - // get the raw bytes of the key - byte[] key = keyGenerator.generateKey().getEncoded(); - - // pass the key bytes to create a SecretKeySpec - SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); - } - ``` - - Example setting a larger key size for Blowfish: - ``` - public static void blowFishKeyGenerator() throws java.security.NoSuchAlgorithmException { - // Use the Blowfish algorithm for key generation - KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish"); - - // Set the key size here - keyGenerator.init(256); - - // get the raw bytes of the key - byte[] key = keyGenerator.generateKey().getEncoded(); - - // pass the key bytes to create a SecretKeySpec - SecretKeySpec secretKeySpec = new SecretKeySpec(key, "Blowfish"); - } - ``` - - For more information on Java Cryptography see: - https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html - metadata: - category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Inadequate encryption strength - technology: - - java - patterns: - - pattern-inside: | - $KEYGEN = javax.crypto.KeyGenerator.getInstance("Blowfish", ...); - ... - - pattern: $KEYGEN.init($KEY_SIZE) - - metavariable-comparison: - comparison: int($KEY_SIZE) < 128 - metavariable: $KEY_SIZE - severity: WARNING - - id: java_crypto_rule-CipherDESInsecure - languages: - - java - message: | - DES, TripleDES and RC2 are all considered broken or insecure cryptographic algorithms. - Newer algorithms apply message integrity to validate ciphertext has not been tampered - with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the - alternatives such as `AES-256-GCM`. - - For older applications that don't have support for `ChaCha20Poly1305`, - `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Example using `ChaCha20Poly1305`: - ``` - public encrypt() throws Exception { - chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); - } - - public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { - // Use DRBG according to - http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf - return SecureRandom.getInstance("DRBG", - // Security strength in bits (default is 128) - DrbgParameters.instantiation(256, - // Set prediction resistance and re-seeding - DrbgParameters.Capability.PR_AND_RESEED, - // Set the personalization string (optional, not necessary) - "some_personalization_string".getBytes() - ) - ); - } - - public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws - NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, - InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create a ChaCha20-Poly1305 cipher instance - Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); - // Create our parameterSpec using our ivKey - AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey); - // Create a SecretKeySpec using our secretKey - SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); - // Initialize and return the cipher for the provided mode - chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); - return chaChaCipher; - } - - public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, - NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create secretKey - byte[] secretKey = new byte[32]; - random.nextBytes(secretKey); - // Create an IV Key - byte[] ivKey = new byte[12]; - random.nextBytes(ivKey); - - // Create a chaCha encryption cipher instance - Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey); - - // Encrypt the text using ChaCha20Poly1305 - byte[] cipherText = null; - try { - cipherText = chaChaEncryptor.doFinal(plainText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to encrypt text"); - return; - } - System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); - - // Create a chaCha decryption cipher instance - Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey); - - // Decrypt the text - byte[] decryptedText = null; - try { - decryptedText = chaChaDecryptor.doFinal(cipherText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to decrypt text"); - return; - } - System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); - } - ``` - - For more information on Java Cryptography see: - https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html - metadata: - category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Inadequate encryption strength - technology: - - java - patterns: - - pattern-either: - - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) + $INTERM = $STR + $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., request.$W(...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) + - pattern: return django.http.HttpResponseRedirect(..., request.$W(...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W(...), ...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W(...), ...) + - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W(...)}...", ...) + - pattern: django.http.HttpResponseRedirect(..., request.$W[...], ...) + - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) + - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) - pattern: | - $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); + $DATA = request.$W[...] ... - javax.crypto.Cipher.getInstance($PROP, ...); - - metavariable-regex: - metavariable: $ALG - regex: ^DES(/|$) - severity: WARNING - - id: java_crypto_rule-CipherDESedeInsecure - languages: - - java - message: | - DES, TripleDES and RC2 are all considered broken or insecure cryptographic algorithms. - Newer algorithms apply message integrity to validate ciphertext has not been tampered - with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the - alternatives such as `AES-256-GCM`. - - For older applications that don't have support for `ChaCha20Poly1305`, - `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Example using `ChaCha20Poly1305`: - ``` - public encrypt() throws Exception { - chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); - } - - public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { - // Use DRBG according to - http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf - return SecureRandom.getInstance("DRBG", - // Security strength in bits (default is 128) - DrbgParameters.instantiation(256, - // Set prediction resistance and re-seeding - DrbgParameters.Capability.PR_AND_RESEED, - // Set the personalization string (optional, not necessary) - "some_personalization_string".getBytes() - ) - ); - } - - public Cipher getChaCha20Poly1305(int mode, byte[] nonceKey, byte[] secretKey) throws - NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, - InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create a ChaCha20-Poly1305 cipher instance - Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); - // Create our parameterSpec using our nonceKey - AlgorithmParameterSpec parameterSpec = new IvParameterSpec(nonceKey); - // Create a SecretKeySpec using our secretKey - SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); - // Initialize and return the cipher for the provided mode - chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); - return chaChaCipher; - } - - public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, - NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create secretKey - byte[] secretKey = new byte[32]; - random.nextBytes(secretKey); - // Create an IV nonceKey - byte[] nonceKey = new byte[12]; - random.nextBytes(nonceKey); - // Create a chaCha encryption cipher instance - Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, nonceKey, secretKey); - // Encrypt the text using ChaCha20Poly1305 - byte[] cipherText = null; - try { - cipherText = chaChaEncryptor.doFinal(plainText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to encrypt text"); - return; - } - System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); - // Create a chaCha decryption cipher instance - Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, nonceKey, secretKey); - // Decrypt the text - byte[] decryptedText = null; - try { - decryptedText = chaChaDecryptor.doFinal(cipherText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to decrypt text"); - return; - } - System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); - } - ``` - - For more information on Java Cryptography see: - https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - technology: - - java - patterns: - - pattern-either: - - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) + django.http.HttpResponseRedirect(..., $DATA, ...) - pattern: | - $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); + $DATA = request.$W[...] ... - javax.crypto.Cipher.getInstance($PROP, ...); - - metavariable-regex: - metavariable: $ALG - regex: DESede(/|$) - severity: WARNING - - id: java_crypto_rule-CipherECBMode - languages: - - java - message: | - Cryptographic algorithms provide many different modes of operation, only some of which provide - message integrity. Without message integrity it could be possible for an adversary to attempt - to tamper with the ciphertext which could lead to compromising the encryption key. Newer - algorithms - apply message integrity to validate ciphertext has not been tampered with. - - Instead of using an algorithm that requires configuring a cipher mode, an algorithm - that has built-in message integrity should be used. Consider using `ChaCha20Poly1305` or - `AES-256-GCM` instead. - - For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is - recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Example using `ChaCha20Poly1305`: - ``` - public encrypt() throws Exception { - chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); - } - - public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { - // Use DRBG according to - http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf - return SecureRandom.getInstance("DRBG", - // Security strength in bits (default is 128) - DrbgParameters.instantiation(256, - // Set prediction resistance and re-seeding - DrbgParameters.Capability.PR_AND_RESEED, - // Set the personalization string (optional, not necessary) - "some_personalization_string".getBytes() - ) - ); - } - - public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws - NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, - InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create a ChaCha20-Poly1305 cipher instance - Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); - // Create our parameterSpec using our ivKey - AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey); - // Create a SecretKeySpec using our secretKey - SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); - // Initialize and return the cipher for the provided mode - chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); - return chaChaCipher; - } - - public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, - NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create secretKey - byte[] secretKey = new byte[32]; - random.nextBytes(secretKey); - // Create an IV Key - byte[] ivKey = new byte[12]; - random.nextBytes(ivKey); - - // Create a chaCha encryption cipher instance - Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey); - - // Encrypt the text using ChaCha20Poly1305 - byte[] cipherText = null; - try { - cipherText = chaChaEncryptor.doFinal(plainText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to encrypt text"); - return; - } - System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); - - // Create a chaCha decryption cipher instance - Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey); - - // Decrypt the text - byte[] decryptedText = null; - try { - decryptedText = chaChaDecryptor.doFinal(cipherText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to decrypt text"); - return; - } - System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); - } - ``` - - For more information on Java Cryptography see: - https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - technology: - - java - patterns: - - pattern-either: - - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) + $INTERM = $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) - pattern: | - $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); + $DATA = request.$W[...] ... - javax.crypto.Cipher.getInstance($PROP, ...); - - metavariable-comparison: - comparison: | - $ALG in ( - "AES/ECB/NoPadding" "AES/ECB/PKCS5Padding" - "DES/ECB/NoPadding" "DES/ECB/PKCS5Padding" - "DESede/ECB/NoPadding" "DESede/ECB/PKCS5Padding" - "AES/ECB/PKCS7Padding" - ) - metavariable: $ALG - severity: ERROR - - id: java_crypto_rule-CipherIntegrity - languages: - - java - message: | - Cryptographic algorithms provide many different modes of operation, only some of which provide - message integrity. Without message integrity it could be possible for an adversary to attempt - to tamper with the ciphertext which could lead to compromising the encryption key. Newer - algorithms - apply message integrity to validate ciphertext has not been tampered with. - - Instead of using an algorithm that requires configuring a cipher mode, an algorithm - that has built-in message integrity should be used. Consider using `ChaCha20Poly1305` or - `AES-256-GCM` instead. - - For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is - recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Example using `ChaCha20Poly1305`: - ``` - public encrypt() throws Exception { - chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); - } - - public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { - // Use DRBG according to - http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf - return SecureRandom.getInstance("DRBG", - // Security strength in bits (default is 128) - DrbgParameters.instantiation(256, - // Set prediction resistance and re-seeding - DrbgParameters.Capability.PR_AND_RESEED, - // Set the personalization string (optional, not necessary) - "some_personalization_string".getBytes() - ) - ); - } - - public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws - NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, - InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create a ChaCha20-Poly1305 cipher instance - Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); - // Create our parameterSpec using our ivKey - AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey); - // Create a SecretKeySpec using our secretKey - SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); - // Initialize and return the cipher for the provided mode - chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); - return chaChaCipher; - } - - public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, - NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create secretKey - byte[] secretKey = new byte[32]; - random.nextBytes(secretKey); - // Create an IV Key - byte[] ivKey = new byte[12]; - random.nextBytes(ivKey); - - // Create a chaCha encryption cipher instance - Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey); - - // Encrypt the text using ChaCha20Poly1305 - byte[] cipherText = null; - try { - cipherText = chaChaEncryptor.doFinal(plainText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to encrypt text"); - return; - } - System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); - - // Create a chaCha decryption cipher instance - Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey); - - // Decrypt the text - byte[] decryptedText = null; - try { - decryptedText = chaChaDecryptor.doFinal(cipherText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to decrypt text"); - return; - } - System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); - } - ``` - - For more information on Java Cryptography see: - https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - technology: - - java - patterns: - - pattern-either: - - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) + django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) - pattern: | - $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); + $DATA = request.$W[...] ... - javax.crypto.Cipher.getInstance($PROP, ...); - - metavariable-comparison: - comparison: | - $ALG in ( - "AES" - "AES/CBC/NoPadding" "AES/CBC/PKCS5Padding" "AES/CBC/PKCS7Padding" - "AES/CFB/NoPadding" "AES/CFB/PKCS5Padding" "AES/CFB/PKCS7Padding" - "AES/CTR/NoPadding" - "AES/ECB/NoPadding" "AES/ECB/PKCS5Padding" "AES/ECB/PKCS7Padding" - "AES/OFB/NoPadding" "AES/OFB/PKCS5Padding" "AES/OFB/PKCS7Padding" - "ARCFOUR" - "DES" - "DES/CBC/NoPadding" "DES/CBC/PKCS5Padding" - "DES/ECB/NoPadding" "DES/ECB/PKCS5Padding" - "DESede" - "DESede/CBC/NoPadding" "DESede/CBC/PKCS5Padding" - "DESede/ECB/NoPadding" "DESede/ECB/PKCS5Padding" - "RC4" - ) - metavariable: $ALG - severity: ERROR - - id: java_crypto_rule-CipherPaddingOracle - languages: - - java - message: | - Cryptographic block ciphers can be configured to pad individual blocks if there is not enough - input data to match the size of the block. This specific mode of CBC used in combination with - PKCS5Padding is susceptible to padding oracle attacks. An adversary could potentially decrypt - the message if the system exposed the difference between plaintext with invalid padding or - valid padding. The distinction between valid and invalid padding is usually revealed through - distinct error messages being returned for each condition. - - Consider switching to a more secure cipher that doesn't require padding and builds in message - authentication integrity directly into the algorithm. - - Consider using `ChaCha20Poly1305` or - `AES-256-GCM` instead. - - For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is - recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Example using `ChaCha20Poly1305`: - ``` - public encrypt() throws Exception { - chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); - } - - public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { - // Use DRBG according to - http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf - return SecureRandom.getInstance("DRBG", - // Security strength in bits (default is 128) - DrbgParameters.instantiation(256, - // Set prediction resistance and re-seeding - DrbgParameters.Capability.PR_AND_RESEED, - // Set the personalization string (optional, not necessary) - "some_personalization_string".getBytes() - ) - ); - } - - public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws - NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, - InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create a ChaCha20-Poly1305 cipher instance - Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); - // Create our parameterSpec using our ivKey - AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey); - // Create a SecretKeySpec using our secretKey - SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); - // Initialize and return the cipher for the provided mode - chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); - return chaChaCipher; - } - - public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, - NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create secretKey - byte[] secretKey = new byte[32]; - random.nextBytes(secretKey); - // Create an IV Key - byte[] ivKey = new byte[12]; - random.nextBytes(ivKey); - - // Create a chaCha encryption cipher instance - Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey); - - // Encrypt the text using ChaCha20Poly1305 - byte[] cipherText = null; - try { - cipherText = chaChaEncryptor.doFinal(plainText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to encrypt text"); - return; - } - System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); - - // Create a chaCha decryption cipher instance - Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey); - - // Decrypt the text - byte[] decryptedText = null; - try { - decryptedText = chaChaDecryptor.doFinal(cipherText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to decrypt text"); - return; - } - System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); - } - ``` - - For more information on padding oracle attacks see: - https://en.wikipedia.org/wiki/Padding_oracle_attack - - For more information on Java Cryptography see: - https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - technology: - - java - patterns: - - pattern-either: - - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) - pattern: | - $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); + $DATA = request.$W[...] ... - javax.crypto.Cipher.getInstance($PROP, ...); - - metavariable-comparison: - comparison: | - $ALG in ( - "AES/CBC/PKCS5Padding" "DES/CBC/PKCS5Padding" "DESede/CBC/PKCS5Padding" "AES/CBC/PKCS7Padding" - ) - metavariable: $ALG - severity: ERROR - - id: java_crypto_rule-CustomMessageDigest - languages: - - java - message: | - The application was found implementing a custom `java.security.MessageDigest`. It is - strongly recommended that a standard Digest algorithm be chosen instead as implementing - a digest by hand is error-prone. The National Institute of Standards and - Technology (NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or - SHA-512/256. - - Example of creating a SHA-384 hash: - ``` - // Create a MessageDigest using the SHA-384 algorithm - MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384"); - // Call update with your data - sha384Digest.update(input); - // Only call digest once all data has been fed into the update sha384digest instance - byte[] output = sha384Digest.digest(); - // output base64 encoded version of the hash - System.out.println("hash: " + Base64.getEncoder().encodeToString(output)); - ``` - metadata: - category: security - cwe: CWE-327 - owasp: - - A6:2017-Security Misconfiguration - - A04:2021-Insecure Design - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - technology: - - java - patterns: - - pattern: | - class $CLAZZ extends java.security.MessageDigest { - ... - } - severity: WARNING - - id: java_crypto_rule-HazelcastSymmetricEncryption - languages: - - java - message: | - The network communications for Hazelcast is configured to use a deprecated symmetric cipher. - Consider using TLS/SSL when establishing communications across the Hazelcast cluster. - - For more information on configuring TLS/SSL for Hazelcast see: - https://docs.hazelcast.com/imdg/4.2/security/tls-ssl - metadata: - category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Inadequate encryption strength - technology: - - java - patterns: - - pattern: new com.hazelcast.config.SymmetricEncryptionConfig() - severity: WARNING - - id: java_crypto_rule-InsufficientKeySizeRsa - languages: - - java - message: | - The application is generating an RSA key that is less than the recommended 2048 bits. - The National Institute of Standards and Technology (NIST) deprecated signing Digital - Certificates that contained RSA Public Keys of 1024 bits in December 2010. While - 1024-bit RSA keys have not been factored yet, advances in compute may make it possible - in the near future. - - Consider upgrading to the newer asymmetric algorithm such as `Ed25519` which handles - the complexities of generating key pairs and choosing correct key sizes for you: - ``` - public static KeyPair generateEd25519() throws NoSuchAlgorithmException { - // Choose Ed25519 for KeyPairGenerator Instance - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Ed25519"); - // Generate a KeyPair and return - return keyPairGenerator.generateKeyPair(); - } - ``` - - Otherwise use a key size greater than 2048 when generating RSA keys: - ``` - public static KeyPair generateRSA() throws NoSuchAlgorithmException { - // Choose RSA for KeyPairGenerator Instance - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); - // Initialize with 2048 key size - keyPairGenerator.initialize(2048); - // Generate a KeyPair and return - return keyPairGenerator.generateKeyPair(); - } - ``` - - For more information on Ed25519 see: http://ed25519.cr.yp.to/ - - For more information on Java Cryptography see: - https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html - metadata: - category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Inadequate encryption strength - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $GEN = KeyPairGenerator.getInstance($ALG, ...); - ... - - pattern-either: - - pattern: $VAR.initialize($SIZE, ...); - - pattern: new java.security.spec.RSAKeyGenParameterSpec($SIZE,...); - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - - metavariable-regex: - metavariable: $ALG - regex: '"(RSA|DSA)"' - severity: WARNING - - id: java_crypto_rule-NullCipher - languages: - - java - message: | - The application was found creating a `NullCipher` instance. `NullCipher` implements the - `Cipher` interface by returning ciphertext identical to the supplied plaintext. This means - any data passed to the `doFinal(...)` or `update(...)` methods will not actually encrypt - the input. - - Remove the NullCipher reference and replace with a legitimate `Cipher` instance such as - `ChaCha20-Poly1305` - - Example using `ChaCha20Poly1305`: - ``` - public encrypt() throws Exception { - chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8)); - } - - public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException { - // Use DRBG according to - http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf - return SecureRandom.getInstance("DRBG", - // Security strength in bits (default is 128) - DrbgParameters.instantiation(256, - // Set prediction resistance and re-seeding - DrbgParameters.Capability.PR_AND_RESEED, - // Set the personalization string (optional, not necessary) - "some_personalization_string".getBytes() - ) - ); - } - - public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws - NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, - InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create a ChaCha20-Poly1305 cipher instance - Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding"); - // Create our parameterSpec using our ivKey - AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey); - // Create a SecretKeySpec using our secretKey - SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20"); - // Initialize and return the cipher for the provided mode - chaChaCipher.init(mode, secretKeySpec, parameterSpec, random); - return chaChaCipher; - } - - public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, - NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { - // Get a DRBG random number generator instance - SecureRandom random = getSecureRandomDRBG(); - // Create secretKey - byte[] secretKey = new byte[32]; - random.nextBytes(secretKey); - // Create an IV Key - byte[] ivKey = new byte[12]; - random.nextBytes(ivKey); - - // Create a chaCha encryption cipher instance - Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey); - - // Encrypt the text using ChaCha20Poly1305 - byte[] cipherText = null; - try { - cipherText = chaChaEncryptor.doFinal(plainText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to encrypt text"); - return; - } - System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText)); - - // Create a chaCha decryption cipher instance - Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey); - - // Decrypt the text - byte[] decryptedText = null; - try { - decryptedText = chaChaDecryptor.doFinal(cipherText); - } catch (IllegalBlockSizeException | BadPaddingException e) { - System.out.println("failed to decrypt text"); - return; - } - System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8)); - } - ``` - - For more information on Java Cryptography see: - https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - technology: - - java - pattern: new javax.crypto.NullCipher() - severity: WARNING - - id: java_crypto_rule-RsaNoPadding - languages: - - java - message: | - The software uses the RSA algorithm but does not incorporate Optimal Asymmetric - Encryption Padding (OAEP). By not enabling padding, the algorithm maybe vulnerable - to [chosen plaintext attacks](https://en.wikipedia.org/wiki/Chosen-plaintext_attack). - - To enable OAEP mode, pass `RSA/ECB/OAEPWithSHA-256AndMGF1Padding` to the `Cipher.getInstance` - method. - - Example encrypting and decrypting a message using RSA with OAEP: - ``` - public static void encryptWithRSA() throws InvalidKeyException, NoSuchAlgorithmException, - NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { - // Generate an RSA Public and Private Key Pair - KeyPair keyPair = generateRSAKeys(); - // Create a Cipher instance using RSA, ECB with OAEP - Cipher rsaEncryptor = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); - // Initialize to ENCRYPT_MODE with the public key - rsaEncryptor.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); - // Encrypt our secret message - byte[] cipherText = rsaEncryptor.doFinal("Some secret - message".getBytes(StandardCharsets.UTF_8)); - - // Create a Cipher instance using RSA, ECB with OAEP - Cipher rsaDecryptor = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); - // Initialize to DECRYPT_MODE with the private key - rsaDecryptor.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); - // Decrypt the secret message - byte[] plainText = rsaDecryptor.doFinal(cipherText); - // Debug output - System.out.println(new String(plainText)); - } - ``` - More information on Optimal asymmetric encryption padding: - https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding - - For more information on Java Cryptography see: - https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html - metadata: - category: security - cwe: CWE-780 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of RSA algorithm without OAEP - patterns: - - pattern-either: - - pattern: javax.crypto.Cipher.getInstance("$ALG", ...) + django.http.HttpResponseRedirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponseRedirect(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., request.$W[...], ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) + - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) + - pattern: return django.http.HttpResponseRedirect(..., request.$W[...], ...) + - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W[...], ...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W[...], ...) + - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W[...]}...", ...) + - pattern: django.http.HttpResponseRedirect(..., request.$W, ...) + - pattern: django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) + - pattern: django.http.HttpResponseRedirect(..., $S % request.$W, ...) + - pattern: django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseRedirect(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseRedirect(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseRedirect(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseRedirect(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseRedirect(..., $STR + $DATA, ...) - pattern: | - $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); + $DATA = request.$W + ... + $INTERM = $STR + $DATA ... - javax.crypto.Cipher.getInstance($PROP, ...); + django.http.HttpResponseRedirect(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., request.$W, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) + - pattern: $A = django.http.HttpResponseRedirect(..., $S % request.$W, ...) + - pattern: $A = django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) + - pattern: return django.http.HttpResponseRedirect(..., request.$W, ...) + - pattern: return django.http.HttpResponseRedirect(..., $S.format(..., request.$W, ...), ...) + - pattern: return django.http.HttpResponseRedirect(..., $S % request.$W, ...) + - pattern: return django.http.HttpResponseRedirect(..., f"...{request.$W}...", ...) - metavariable-regex: - metavariable: $ALG - regex: (?i)^RSA/.*NoPadding$ + metavariable: $W + regex: (?!get_full_path) severity: WARNING - - id: java_crypto_rule-WeakMessageDigest + - id: python.django.security.injection.path-traversal.path-traversal-open.path-traversal-open languages: - - java - message: | - The application was found using an insecure or risky digest or signature algorithm. Both MD5 - and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. - strongly recommended that a standard Digest algorithm be chosen instead as implementing - a digest by hand is error-prone. - - Example of creating a SHA-384 hash: - ``` - // Create a MessageDigest using the SHA-384 algorithm - MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384"); - // Call update with your data - sha384Digest.update(input); - // Only call digest once all data has been fed into the update sha384digest instance - byte[] output = sha384Digest.digest(); - // output base64 encoded version of the hash - System.out.println("hash: " + Base64.getEncoder().encodeToString(output)); - ``` - - For more information on secure password storage see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + - python + message: Found request data in a call to 'open'. Ensure the request data is validated or sanitized, otherwise it could result in path traversal attacks and therefore sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or the pathlib library. metadata: category: security - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A04:2021-Insecure Design - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm (SHA1/MD5) + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + subcategory: + - vuln technology: - - java + - django patterns: + - pattern-inside: | + def $FUNC(...): + ... - pattern-either: - - pattern: java.security.MessageDigest.getInstance("$ALG", ...) - - pattern: java.security.Signature.getInstance("$ALG", ...) + - pattern: open(..., request.$W.get(...), ...) + - pattern: open(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: open(..., $S % request.$W.get(...), ...) + - pattern: open(..., f"...{request.$W.get(...)}...", ...) - pattern: | - $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); + $DATA = request.$W.get(...) ... - java.security.MessageDigest.getInstance("$ALG", ...); + open(..., $DATA, ...) - pattern: | - $PROP = (java.util.Properties $P).getProperty(..., "$ALG"); + $DATA = request.$W.get(...) ... - java.security.Signature.getInstance("$ALG", ...); - - metavariable-comparison: - comparison: | - $ALG in ( - "MD2" "MD4" "MD5" "MD5withRSA" - "SHA-1" "SHA1withRSA" "SHA1withDSA" - ) - metavariable: $ALG - severity: WARNING - - id: java_crypto_rule-WeakTLSProtocol-DefaultHttpClient - languages: - - java - message: | - The `org.apache.http.impl.client.DefaultHttpClient` does not verify the hostnames upon connection. - - This allows for an adversary who is in between the application and the target host to intercept - potentially sensitive information or transmit malicious data. - - Do not use the `org.apache.http.impl.client.DefaultHttpClient();` as it is deprecated. Instead - use the new `java.net.http.HttpClient` that was introduced in Java 9. - - Example connecting to a host that will automatically do TLS validation: - ``` - // Create a new java.net.http.HttpClient - HttpClient httpClient = HttpClient.newHttpClient(); - // Create a HttpRequest builder - HttpRequest request = HttpRequest.newBuilder() - // Create a URI for a website which requires TLS - .uri(URI.create("https://www.example.com/")) - // Build the request - .build(); - - // Use the httpClient to send the request and use an HttpResponse.BodyHandlers String type - HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - // Debug print - System.out.println(response); - ``` - metadata: - category: security - cwe: CWE-295 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Improper certificate validation - patterns: - - pattern: new org.apache.http.impl.client.DefaultHttpClient(); - severity: WARNING - - id: java_crypto_rule-WeakTLSProtocol-SSLContext - languages: - - java - message: | - Avoid initializing SSLContext with insecure protocols like `SSL`, `SSLv2`, or `SSLv3`. - These protocols are outdated and do not validate certificates by default. Additionally, - these older `SSL` versions have many known security issues. - - Instead, use secure protocols like `TLSv1.2` or `TLSv1.3`. - ``` - SSLContext context = SSLContext.getInstance("TLSv1.3"); - ``` - For more information on see OWASP: - - https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/09-Testing_for_Weak_Cryptography/01-Testing_for_Weak_SSL_TLS_Ciphers_Insufficient_Transport_Layer_Protection - metadata: - category: security - cwe: CWE-295 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Improper certificate validation - patterns: - - pattern-either: - - pattern: javax.net.ssl.SSLContext.getInstance("$PROTO", ...) + $INTERM = $DATA + ... + open(..., $INTERM, ...) - pattern: | - $PROP = (java.util.Properties $P).getProperty(..., "$PROTO"); + $DATA = request.$W.get(...) ... - javax.net.ssl.SSLContext.getInstance($PROP, ...); - - metavariable-comparison: - comparison: | - $PROTO not in ("TLS" "TLSv1.2" "TLSv1.3" "DTLSv1.2" "DTLSv1.3") - metavariable: $PROTO - severity: WARNING - - id: java_crypto_rule-WeakTLSProtocolVersion - languages: - - java - message: | - The application was found enabling insecure TLS protocol versions. When enabling protocol - versions for an `SSLContext`, only the following versions should be allowed: - - TLSv1.2 - - TLSv1.3 - - DTLSv1.2 - - DTLSv1.3 - - To mitigate potential security risks, it is strongly advised to enforce TLS 1.2 as the minimum - protocol version and disallow older versions such as TLS 1.0. Do note that newer versions of - Java do not even support TLS 1.0 and will throw `NoSuchAlgorithmException`. Versions of TLS - prior to 1.2 could expose the connection to downgrade attacks, where an adversary intercepts - the - connection and alters the requested protocol version to be a less secure one. - - In many scenarios, relying on the default system configuration does not meet compliance - standards. This is due to the application being deployed across diverse systems with varying - configurations and Java versions. While the default value may be secure on modern and - up-to-date systems, it may not hold true for older systems. Consequently, it is highly - recommended to explicitly define a secure configuration in all cases. - - Example configuring an SSLContext with TLSv1.2: - ``` - // Create an SSLContext with TLSv1.2 explicitly - SSLContext tlsContext = SSLContext.getInstance("TLSv1.2"); // or TLSv1.3, DTLSv1.2, DTLSv1.3 - - // Alternatively, set the enabled protocols - SSLContext serverSslContext = SSLContext.getInstance("TLS"); - SSLEngine serverEngine = serverSslContext.createSSLEngine(); - // Calling setEnabledProtocols will override the original context's configured protocol version - serverEngine.setEnabledProtocols(new String[]{ "TLSv1.2" }); - ``` - - For more information on `SSLContext` see: - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/javax/net/ssl/SSLContext.html - - For more information on MiTM attacks see: - - https://owasp.org/www-community/attacks/Manipulator-in-the-middle_attack - metadata: - category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Inadequate encryption strength - patterns: - - pattern-either: - - pattern-inside: | - import javax.net.ssl.*; + $INTERM = $DATA ... - - pattern-inside: | - import javax.net.ssl.SSLContext; + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W.get(...) ... - - pattern-either: - - pattern-inside: | - SSLContext.getInstance("$UNSAFE_VERSION"); - - pattern-inside: | - SSLContext.getInstance(...); + open(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) ... - $ENGINE.setEnabledProtocols(new String[]{...,"$UNSAFE_VERSION",...}); - - pattern-not-inside: | - $C = SSLContext.getInstance(...); - ... - $ENGINE.setEnabledProtocols(new String[]{...,"TLSv1.2",...}); - - pattern-not-inside: | - $C = SSLContext.getInstance(...); - ... - $ENGINE.setEnabledProtocols(new String[]{...,"TLSv1.3",...}); - - pattern-not-inside: | - $C = SSLContext.getInstance(...); - ... - $ENGINE.setEnabledProtocols(new String[]{...,"DTLSv1.2",...}); - - pattern-not-inside: | - $C = SSLContext.getInstance(...); - ... - $ENGINE.setEnabledProtocols(new String[]{...,"DTLSv1.3",...}); - - metavariable-regex: - metavariable: $UNSAFE_VERSION - regex: ^(TLS|(D)?TLSv1.(0|1))$ - severity: WARNING - - id: java_endpoint_rule-HostnameVerifier - languages: - - java - message: "The `HostnameVerifier` has been set to always return `true`. This effectively \ndisables the validation of server or client certificates. This could allow an \nadversary who is in between the application and the target host to launch a Man \nin the middle attack (MITM) i.e intercept potentially sensitive information or \ninject malicious content into the communication stream.\n\nTo mitigate this vulnerability and enhance the security of your application, it is \nstrongly advised to adhere to the default HostnameVerifier settings. This ensures \nthat the validation mechanism remains intact, providing a crucial layer of security \nagainst unauthorized interception and data manipulation.\n\nImplementing the default HostnameVerifier can be achieved with the following code \nsnippet:\n```\n// Use the default HostnameVerifier\nHttpsURLConnection connection = (HttpsURLConnection) url.openConnection();\nconnection.setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier());\n```\nFor more information on TLS security, refer the following OWASP documentation:\nhttps://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html\n" - metadata: - category: security - cwe: CWE-295 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Improper certificate validation - patterns: - - pattern-inside: | - class $V implements HostnameVerifier { - ... - } - - pattern-either: + $INTERM = $STR.format(..., $DATA, ...) + ... + open(..., $INTERM, ...) - pattern: | - boolean verify(...) { + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + with open(..., $INTERM, ...) as $FD: ... - return true; + - pattern: | + $DATA = request.$W.get(...) + ... + open(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + with open(..., $INTERM, ...) as $FD: ... - } - - pattern-not: - patterns: - - pattern: | - boolean verify(...) { - ... - return $VAR; - ... - } - - metavariable-regex: - metavariable: $VAR - regex: ^((?!true).)*$ - - pattern-not: | - boolean verify(...) { - $VAR = true; - ... - return $VAR; - ... - } - severity: WARNING - - id: java_endpoint_rule-UnvalidatedRedirect - languages: - - java - message: "Unvalidated redirects occur when an application redirects a user to a\ndestination URL specified by a user supplied parameter that is not validated.\nSuch vulnerabilities can be used to facilitate phishing attacks.\n\nTo avoid open redirect vulnerabilities in Java, one effective strategy is to\nonly allow redirection to URLs that are pre-defined in a safe list. This safe\nlist can be implemented using a collection like a Map, List, or Dictionary,\nwhere you store all the valid URLs or URL patterns. When a redirect request is\nmade, you can check if the requested URL is in this safe list before proceeding \nwith the redirection. For example:\n\n```\n protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {\n private List safeUrls = new ArrayList<>();\n safeUrls.add(\"/home\");\n safeUrls.add(\"/user/profile\");\n safeUrls.add(\"/dashboard\");\n \n String redirectUrl = request.getParameter(\"url\");\n\n if (safeUrls.contains(redirectUrl)) {\n response.sendRedirect(redirectUrl);\n } else {\n response.sendRedirect(\"/errorPage\");\n }\n }\"\n``` \n" - metadata: - category: security - cwe: CWE-601 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Info - shortDescription: URL redirection to untrusted site ('Open Redirect') - mode: taint - pattern-sanitizers: - - patterns: - - pattern-inside: | - if ($SAFE.contains($URL)){ + - pattern: | + $DATA = request.$W.get(...) + ... + open(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + with open(..., $INTERM, ...) as $FD: ... - } - - pattern-either: - - pattern: | - ($X.servlet.http.HttpServletResponse $RES).sendRedirect($URL) - - pattern: | - ($X.servlet.http.HttpServletResponse $RES).addHeader("Location", $URL) - pattern-sinks: - - pattern-either: - pattern: | - ($X.servlet.http.HttpServletResponse $RES).sendRedirect($URL) + $DATA = request.$W.get(...) + ... + open(..., $STR + $DATA, ...) - pattern: | - ($X.servlet.http.HttpServletResponse $RES).addHeader("Location", $URL) - pattern-sources: - - patterns: + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + open(..., $INTERM, ...) - pattern: | - $URL = ($X.servlet.http.HttpServletRequest $REQ).$M(...); - - metavariable-regex: - metavariable: $M - regex: (getParameter|getCookies|getHeader|getHeaders|getHeaderNames|getPathInfo|getPathTranslated|getContextPath|getQueryString|getRemoteUser|getRequestedSessionId|getRequestURI|getRequestURL|getServletPath|getParts|getPart|getReader) - severity: ERROR - - id: java_endpoint_rule-X509TrustManager - languages: - - java - message: "The `X509TrustManager` has been configured to return null. This effectively disables the\nvalidation of server or client certificates. This could allow an adversary who is in \nbetween the application and the target host to launch a Man in the middle attack (MITM) i.e \nintercept potentially sensitive information or inject malicious content into the \ncommunication stream.\n\nConsider using the \ndefault `TrustManager` instead of implementing a custom one. If you must override\nthe default verification process, implement proper TrustManager verification for\n`checkServerTrusted` and `checkClientTrusted` by throwing `CertificateException` if \nthe certificate is invalid.\n\nFor most applications, using the default TrustManager provided by the Java runtime is \nsufficient and recommended. Following is an example using the built in `TrustManagerFactory` \nto manage validating certificate chains:\n```\n// Use the default TrustManagerFactory\nTrustManagerFactory trustManagerFactory =\nTrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());\n// Use default system KeyStore, alternatively pass in your own keystore.\ntrustManagerFactory.init((KeyStore) null);\n// Create SSLContext for TLS connections\nSSLContext tlsContext = SSLContext.getInstance(\"TLS\");\n// Initialize the tlsContext with our trust manager and a SecureRandom number generator.\ntlsContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());\n```\nFor more information on TLS security, refer the following OWASP documentation:\nhttps://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html\n" - metadata: - category: security - cwe: CWE-295 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Improper certificate validation - patterns: - - pattern-inside: | - class $V implements X509TrustManager { - ... - } - - pattern-either: - - pattern: public void checkClientTrusted(...) {} - - pattern: public void checkServerTrusted(...) {} - - patterns: - - pattern-either: - - pattern: | - X509Certificate[] getAcceptedIssuers() { - ... - return null; - ... - } - - pattern-not: - patterns: - - pattern: | - X509Certificate[] getAcceptedIssuers() { - ... - return $VAR; - ... - } - - metavariable-regex: - metavariable: $VAR - regex: ^((?!null).)*$ - - pattern-not: | - X509Certificate[] getAcceptedIssuers() { - $VAR = null; - ... - return $VAR; - ... - } - severity: WARNING - - id: java_file_rule-FileUploadFileName - languages: - - java - message: | - The filename provided by the FileUpload API can be tampered with - which could lead to unauthorized access or file inclusion vulnerabilities. - To mitigate this risk, it is essential to conduct rigorous validation of the - filenames provided by clients. This validation should ensure that the filename - adheres to a predefined structure, is devoid of potentially dangerous characters - (such as forward slashes / and backslashes \), and corresponds to an authorized - file only. - - For example, as a remediation strategy, the application could: - 1. Sanitize Filenames: Create a function to sanitize filenames by removing - or replacing unauthorized characters, including path traversal sequences (../ or ..\). - 2. Allowlist Validation: Implement a allowlist approach, allowing only filenames - that match a specific pattern or are part of a predefined list. - 3. Use Server-Generated Filenames: Rather than relying on client-provided filenames, - generate unique names server-side for storing files. - 4. Verify File Paths: Ensure files are being saved in the correct, - intended directory, and prevent redirection to unauthorized directories. - - Example remediation: - ``` - public class FileUploadHandler { - - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - Part filePart = request.getPart("file"); - String fileName = filePart.getSubmittedFileName(); - - // removes any path information from the filename - String sanitizedFileName = sanitizeFileName(fileName); - if (!isFileNameAllowed(sanitizedFileName)) { - throw new SecurityException("Invalid file name"); - } - - // Generate a unique file name for storage - String storedFileName = UUID.randomUUID().toString() + ".txt"; - - Path targetPath = Paths.get("uploads").resolve(storedFileName); - Files.copy(fileContent, targetPath, StandardCopyOption.REPLACE_EXISTING); - } - - private String sanitizeFileName(String fileName) { - return Paths.get(fileName).getFileName().toString(); - } - - private boolean isFileNameAllowed(String fileName) { - return fileName.matches("[a-zA-Z0-9._-]+"); - } - } - ``` - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Info - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - technology: - - java - pattern-either: - - patterns: - - pattern-inside: | - $FILES = (ServletFileUpload $SFU).parseRequest(($X.servlet.http.HttpServletRequest $REQ)); + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA ... - for(FileItem $ITEM : $FILES) { + with open(..., $INTERM, ...) as $FD: ... - } - - pattern: $ITEM.getName() - - pattern: ($X.servlet.http.Part $PART).getSubmittedFileName() - severity: WARNING - - id: java_file_rule-FilenameUtils - languages: - - java - message: "The filename provided by the FileUpload API can be tampered with by the client to reference\nunauthorized files. The provided filename should be properly validated to ensure it's properly\nstructured, contains no unauthorized path characters (e.g., / \\), and refers to an authorized\nfile.\n\nThe application was found to take a parameter from user input to construct a path name. If an\nunfiltered parameter is passed to this file API, files from an arbitrary filesystem location\ncould be read. When data from an unstrusted source is untrusted source is used to construct\na file path, an attacker could potentially gain access to restrcited files locations outside\nthe relevant context.\n\nFor example, if the application tries to access the users profile picture based on their user\nname by concatenating the username to the filepath:\n\n\"images/userprofiles/\" + username\n\nThe expected result of this would be \"images/userprofiles/alice\", however an attacker could\nuse a malicious input such as \"../../../etc/passwd\" to gain access to and/or manipulate\nsensitive information\n\nAssume all input is malicious. Use an \"accept known good\" input validation strategy.\n\nInputs can be sanitized by using the getName() method with concat() method to remove the \npotentially malicious path traversal and limit the scope to a restricted directory. Or \ninput can also be sanitized by using resolve() method alongwith startsWith() method to \nverify that the base path of the file is safe and expected.\n\nExample of limiting path traversal using getName:\n\n```\nprotected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {\n\n String input = req.getHeader(\"input\");\n\n input = getName(input);\n \n String safePath = concat(basePath, input);\n\n // Read the contents of the file\n File file = new File(safePath);\n}\n```\n" - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Info - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - technology: - - java - mode: taint - pattern-sanitizers: - - pattern: | - $NAME = org.apache.commons.io.FilenameUtils.getName(...); - ... - $SAFE = concat($BASE, $NAME); - - pattern: | - $RET $FUN(...){ - ... - $PATH = $BP.resolve(...); - ... - if(!$PATH.startsWith(...)) { - throw new $EXC(...); - } - ... - } - pattern-sinks: - - pattern: org.apache.commons.io.FilenameUtils.concat(...) - - pattern: org.apache.commons.io.FilenameUtils.getFullPath(...) - - pattern: org.apache.commons.io.FilenameUtils.getFullPathNoEndSeparator(...) - - pattern: org.apache.commons.io.FilenameUtils.getPath(...) - - pattern: org.apache.commons.io.FilenameUtils.getPathNoEndSeparator(...) - - pattern: org.apache.commons.io.FilenameUtils.normalize(...) - - pattern: org.apache.commons.io.FilenameUtils.normalizeNoEndSeparator(...) - - pattern: org.apache.commons.io.FilenameUtils.normalizeNoEndSeparator(...) - - pattern: org.apache.commons.io.FilenameUtils.removeExtension(...) - - pattern: org.apache.commons.io.FilenameUtils.separatorsToSystem(...) - - pattern: org.apache.commons.io.FilenameUtils.separatorsToUnix(...) - - pattern: org.apache.commons.io.FilenameUtils.separatorsToWindows(...) - pattern-sources: - - pattern: (HttpServletRequest $REQ) - severity: WARNING - - id: java_inject_rule-CommandInjection - languages: - - java - message: | - OS command injection is a critical vulnerability that can lead to a full system - compromise as it may allow an adversary to pass in arbitrary commands or arguments - to be executed. - - User input should never be used in constructing commands or command arguments - to functions which execute OS commands. This includes filenames supplied by - user uploads or downloads. - - Ensure your application does not: - - - Use user-supplied information in the process name to execute. - - Use user-supplied information in an OS command execution function which does - not escape shell meta-characters. - - Use user-supplied information in arguments to OS commands. - - The application should have a hardcoded set of arguments that are to be passed - to OS commands. If filenames are being passed to these functions, it is - recommended that a hash of the filename be used instead, or some other unique - identifier. It is strongly recommended that a native library that implements - the same functionality be used instead of using OS system commands, due to the - risk of unknown attacks against third party commands. - - When specifying the OS command, ensure the application uses the full path - information, otherwise the OS may attempt to look up which process to execute - and could be vulnerable to untrusted search path vulnerabilities (CWE-426). - - Example of safely executing an OS command: - ``` - public static void executeCommand(String userFileData) throws java.io.IOException { - // Generate a random filename, do not use user input - String fileName = UUID.randomUUID().toString(); - // Create a Buffered/FileWriter - BufferedWriter writer = new BufferedWriter(new FileWriter(fileName)); - // Write the user content to our random file - writer.write(userFileData); - // Close the file to flush contents - writer.close(); - // Create the process builder with a hardcoded path to the binary, and our randomly - generated filename - ProcessBuilder processBuilder = new ProcessBuilder("/opt/app/path", fileName); - // Start the process - Process process = processBuilder.start(); - // Handle/redirect output of process here - // ... - } - ``` - - For more information on OS command injection, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-78 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') - technology: - - java - mode: taint - pattern-propagators: - - from: $X - pattern: $LIST.add($X) - to: $LIST - - from: $X - pattern: $MAP.put(..., $X) - to: $MAP - - from: $X - pattern: $STR.concat($X) - to: $STR - - from: $X - pattern: $STR = String.format(..., $X, ...) - to: $STR - - from: $X - pattern: $STR = String.join(..., $X, ...) - to: $STR - pattern-sinks: - - pattern: (ProcessBuilder $PB).command(...) - - pattern: new ProcessBuilder(...) - - pattern: (Runtime $R).exec(...) - pattern-sources: - - pattern: (javax.servlet.http.HttpServletRequest $R).$METHOD(...) - - pattern: (java.util.Scanner $S).$METHOD(...) - - pattern: (java.util.stream.Stream).$METHOD(...) - - pattern: (java.util.StringJoiner $SJ).toString(...) - - pattern: (java.sql.ResultSet.getString $R).$METHOD(...) - - pattern: (java.lang.System $S).getProperty(...) - - pattern: (java.lang.System $S).getenv(...) - - pattern: (java.lang.StringBuilder $SB).toString(...) - - pattern: (java.io.FileInputStream $F).read(...) - - pattern: (java.io.FileReader $F).read(...) - - pattern: (java.net.Socket $S).getInputStream(...) - - pattern: (java.net.Socket $S).getOutputStream(...) - - pattern: (java.net.DatagramSocket $S).receive(...) - - pattern: (java.net.DatagramSocket $S).getInputStream(...) - - pattern: java.nio.file.Files.readAllBytes(...) - - pattern: java.nio.file.Files.readAllLines(...) - - pattern: java.nio.file.Files.lines(...) - - pattern: java.nio.file.Files.newBufferedReader(...) - - pattern: org.apache.commons.io.IOUtils.toString(...) - - pattern: org.apache.commons.io.IOUtils.readLines(...) - - pattern: org.apache.commons.io.IOUtils.toByteArray(...) - - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).readValue(...) - - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).treeToValue(...) - - pattern: $CLASS.$METHOD(..., (javax.servlet.http.HttpServletRequest $R), ...) - - pattern: $FUNC(..., (javax.servlet.http.HttpServletRequest $R), ...) - - patterns: - - pattern-inside: $FUNC(..., String $X, ...) { ... } - - focus-metavariable: $X - severity: WARNING - - id: java_inject_rule-ELInjection - languages: - - java - message: "This rule identifies potential Expression Language (EL) injection vulnerabilities within Java applications. \nThe rule targets use of `createValueExpression`, `createMethodExpression`, `ELProcessor.eval`, `getValue`, \nand `setValue` methods, particularly when input to these methods is not a hardcoded string, indicating dynamic \nevaluation of potentially untrusted input. \n\n`createValueExpression` creates a `ValueExpression` object which gets evaluated upon calling methods like \n`getValue()` and `setValue()` or a Lambda `invoke()` i.e. it evaluates the expression passed to the \n`createValueExpression` method.\n\nSimilarly, `createMethodExpression` creates a `MethodExpression` object which gets evaluated upon calling \nmethods like `invoke()` and `getMethodInfo()`.\n`ELProcessor.eval`, `getValue()`, and `setValue()` methods all evaluate their expressions which are passed \nas parameters.\n\nCalling these method directly with user-supplied input may allow an adversary to execute arbitrary Java \ncode, including OS system commands. Never call these methods directly with user-supplied input. Consider \nalternate methods such as a lookup table to take user input and resolve hardcoded values.\n\nSecure example:\n\n```\nimport javax.el.ELProcessor;\nimport java.util.Set;\n\npublic class SafeELHandling {\n private static final Set ALLOWED_VALUES = Set.of(\"value1\", \"value2\", \"value3\");\n\n public void processInput(String userInput) {\n // Validate user input against the allowlist\n if (!ALLOWED_VALUES.contains(userInput)) {\n throw new IllegalArgumentException(\"Invalid input\");\n }\n \n ELProcessor elProcessor = new ELProcessor();\n elProcessor.defineBean(\"userInput\", userInput);\n \n // Example EL expression using the safe, predefined input\n String result = (String) elProcessor.eval(userInput);\n }\n}\n```\n" - metadata: - category: security - cwe: CWE-917 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Info - shortDescription: Improper neutralization of special elements used in an expression language statement ('Expression Language Injection') - technology: - - java - pattern-either: - - patterns: + - pattern: $A = open(..., request.$W.get(...), ...) + - pattern: $A = open(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $A = open(..., $S % request.$W.get(...), ...) + - pattern: $A = open(..., f"...{request.$W.get(...)}...", ...) + - pattern: return open(..., request.$W.get(...), ...) + - pattern: return open(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: return open(..., $S % request.$W.get(...), ...) + - pattern: return open(..., f"...{request.$W.get(...)}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + with open(..., $DATA, ...) as $FD: + ... + - pattern: open(..., request.$W(...), ...) + - pattern: open(..., $S.format(..., request.$W(...), ...), ...) + - pattern: open(..., $S % request.$W(...), ...) + - pattern: open(..., f"...{request.$W(...)}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + open(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W(...) + ... + open(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W(...) + ... + open(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W(...) + ... + open(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W(...) + ... + open(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: $A = open(..., request.$W(...), ...) + - pattern: $A = open(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $A = open(..., $S % request.$W(...), ...) + - pattern: $A = open(..., f"...{request.$W(...)}...", ...) + - pattern: return open(..., request.$W(...), ...) + - pattern: return open(..., $S.format(..., request.$W(...), ...), ...) + - pattern: return open(..., $S % request.$W(...), ...) + - pattern: return open(..., f"...{request.$W(...)}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + with open(..., $DATA, ...) as $FD: + ... + - pattern: open(..., request.$W[...], ...) + - pattern: open(..., $S.format(..., request.$W[...], ...), ...) + - pattern: open(..., $S % request.$W[...], ...) + - pattern: open(..., f"...{request.$W[...]}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + open(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W[...] + ... + open(..., $STR.format(..., $DATA, ...), ...) - pattern: | - (ExpressionFactory $EXP).createValueExpression((ELContext $CTX), $EXPR, - ...) - - pattern-not: | - (ExpressionFactory $EXP).createValueExpression((ELContext $CTX), "...", - ...) - - patterns: + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + open(..., $INTERM, ...) - pattern: | - (ExpressionFactory $EXP).createMethodExpression((ELContext $CTX), $EXPR, - ...) - - pattern-not: | - (ExpressionFactory $EXP).createMethodExpression((ELContext $CTX), "...", - ...) - - patterns: + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + with open(..., $INTERM, ...) as $FD: + ... - pattern: | - ($X.el.ELProcessor $P).eval(...) - - pattern-not: | - ($X.el.ELProcessor $P).eval("...", ...) - - patterns: + $DATA = request.$W[...] + ... + open(..., $STR % $DATA, ...) - pattern: | - ($X.el.ELProcessor $P).getValue(...) - - pattern-not: | - ($X.el.ELProcessor $P).getValue("...", ...) - - patterns: + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + open(..., $INTERM, ...) - pattern: | - ($X.el.ELProcessor $P).setValue(...) - - pattern-not: "($X.el.ELProcessor $P).setValue(\"...\", \"...\") \n" - severity: WARNING - - id: java_inject_rule-FileDisclosureRequestDispatcher - languages: - - java - message: | - The `HttpRequest.getRequestDispatcher()`'s `include` and `forward` methods will return - any file that is resolvable within the web application context. This includes the `web.xml` - file, any compiled classes, `jsp` files, and additional JAR or WAR libraries that are - accessible. - - Never pass user-supplied input directly to any of these methods. Use a lookup table or - hardcode - which views or paths the user should be directed to. Another option is to use a simple HTTP - redirect by returning an empty response body with a 301 status code and a `Location` redirect - header. In Java servlets, this can be done by using the `response.sendRedirect(...)` method. - - Example using a redirect instead of a `RequestDispatcher`: - ``` - // Create a look up table or pull from a data source - HashMap lookupTable = new HashMap<>(); - lookupTable.put("key1", "/Resource1"); - lookupTable.put("key2", "/Resource2"); - // Get user input - String userInput = request.getParameter("key"); - // Look up resource to redirect to from the user input - String redirectValue = lookupTable.getOrDefault(userInput, "/Resource1"); - // Redirect the user - response.sendRedirect(redirectValue); - ``` - metadata: - category: security - cwe: CWE-552 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: HIGH - shortDescription: Files or directories accessible to external parties - mode: taint - pattern-sinks: - - patterns: - - pattern-not-inside: | - $VAL = $MAP.getOrDefault(..., "..."); + $DATA = request.$W[...] ... - - pattern-inside: | - $REQ = $HTTP.getRequestDispatcher(...); + $INTERM = $STR % $DATA ... - - pattern-either: - - pattern: $REQ.include($FST, $SND) - - pattern: $REQ.forward($FST, $SND) - pattern-sources: - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameter(...) - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterNames(); - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterValues(...); - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterMap(); - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getHeader(...); - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getPathInfo(); - severity: ERROR - - id: java_inject_rule-FileDisclosureSpringFramework - languages: - - java - message: | - The `org.springframework.web.servlet.ModelAndView` class may - potentially allow access to restricted files if called with user-supplied input. - - The ModelAndView class looks up a view by name to resolve a `.jsp` - file. If this view name comes from user-supplied input, it could be abused to attempt - to return a JSP view that the user should not have access to. - - Use a lookup table or hardcode which views or paths the user should be directed to. - - Example using a lookup table to resolve a view from a Spring MVC application: - ``` - @RequestMapping(value="/mvc", method=RequestMethod.GET) - public ModelAndView mvc(HttpServletRequest request, HttpServletResponse response, Model model) - { - // Create a look up table or pull from a data source - HashMap lookupTable = new HashMap<>(); - lookupTable.put("key1", "view1"); - lookupTable.put("key2", "view2"); - // Get user input - String userInput = request.getParameter("key"); - // Look up view from the user input - String viewValue = lookupTable.getOrDefault(userInput, "Resource1"); - // return the new model and view - return new ModelAndView(viewValue); - } - ``` - - Example using a redirect instead of a `RequestDispatcher` in Spring: - ``` - @RequestMapping(value="/mvc", method=RequestMethod.GET) - public void mvc(HttpServletRequest request, HttpServletResponse response, Model model) - { - // Create a look up table or pull from a data source - HashMap lookupTable = new HashMap<>(); - lookupTable.put("key1", "view1"); - lookupTable.put("key2", "view2"); - // Get user input - String userInput = request.getParameter("key"); - // Look up resource to redirect to from the user input - String redirectValue = lookupTable.getOrDefault(userInput, "/Resource1"); - // return the new model and view - response.sendRedirect(redirectValue); - } - ``` - metadata: - category: security - cwe: CWE-552 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: HIGH - shortDescription: Files or directories accessible to external parties - mode: taint - pattern-sinks: - - patterns: - - pattern-not-inside: | - $FST = $MAP.getOrDefault(..., "..."); + with open(..., $INTERM, ...) as $FD: ... - - pattern: new org.springframework.web.servlet.ModelAndView($FST, ...); - - focus-metavariable: $FST - - patterns: - - pattern-not-inside: | - $FST = $MAP.getOrDefault(..., "..."); + - pattern: | + $DATA = request.$W[...] ... - - pattern-inside: | - $MVC = new org.springframework.web.servlet.ModelAndView(); + open(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] ... - - pattern: $MVC.setViewName(...); - pattern-sources: - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameter(...) - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterNames(); - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterValues(...); - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getParameterMap(); - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getHeader(...); - - pattern: (javax.servlet.http.HttpServletRequest $VAR).getPathInfo(); - severity: ERROR - - id: java_inject_rule-HttpParameterPollution - languages: - - java - message: | - The application was found including unvalidated user input into a URL, which could lead to - HTTP Parameter Pollution (HPP) or worse, Server Side Request Forgery (SSRF). This could - allow an adversary to override the value of a URL or a request parameter. HTTP Parameter - Pollution - (HPP) attacks consist of injecting encoded query string delimiters into other existing - parameters. If a web - application does not properly sanitize the user input, an adversary may modify the logic of - these - requests to other applications. - - To remediate this issue, never allow user input directly into creation of a URL or URL - parameter. Consider - using a map to look up user-supplied information and return exact values to be used in the - generation of - requests. - - Example using a map to look up a key to be used in a HTTP request: - ``` - HashMap lookupTable = new HashMap<>(); - lookupTable.put("key1", "value1"); - lookupTable.put("key2", "value2"); - String userInput = request.getParameter("key"); - - // Create a CloseableHttpClient, ideally any requests issued should be done - // out-of-band from the servlet request itself (such as using a separate thread/scheduler - system) - try (final CloseableHttpClient httpClient = HttpClients.createDefault()) { - // Lookup the value from our user input from our lookupTable - String value = lookupTable.getOrDefault(userInput, "value1"); - // Construct the url, with the hardcoded url and only pass in the value from the - lookupTable, - // not direct user input - final HttpGet httpget = new HttpGet("https://example.com/getId?key="+value); - // Execute the request - CloseableHttpResponse clientResponse = httpClient.execute(httpget); - // Read the response - byte[] responseData = clientResponse.getEntity().getContent().readAllBytes(); - // Handle the response - // ... - } - ``` - - If using a map is not possible, the user-supplied input must be encoded prior to use, and - never allow full - URLs: - ``` - // Get user input - String userInput = request.getParameter("key"); - // Encode the string using java.net.URLEncoder with the UTF-8 character set - String encodedString = java.net.URLEncoder.encode(userInput, StandardCharsets.UTF_8); - // Create a CloseableHttpClient, ideally any requests issued should be done - // out-of-band from the servlet request itself (such as using a separate thread/scheduler - system) - try (final CloseableHttpClient httpClient = HttpClients.createDefault()) { - // Construct the url, with the hardcoded url and only pass in the encoded value, never a - full URL - final HttpGet httpget = new HttpGet("https://example.com/getId?key="+encodedString); - // Execute the request - CloseableHttpResponse clientResponse = httpClient.execute(httpget); - // Read the response - byte[] responseData = clientResponse.getEntity().getContent().readAllBytes(); - // handle the response - } - ``` - - For more information on SSRF see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - - For more information on HTTP Parameter Pollution see: - https://en.wikipedia.org/wiki/HTTP_parameter_pollution - metadata: - category: security - cwe: CWE-88 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of argument delimiters in a command ('Argument Injection') - technology: - - java - mode: taint - pattern-sanitizers: - - pattern: java.net.URLEncoder.encode(...) - - pattern: com.google.common.net.UrlEscapers.urlPathSegmentEscaper().escape(...) - pattern-sinks: - - pattern: new org.apache.http.client.methods.HttpGet(...) - - pattern: new org.apache.commons.httpclient.methods.GetMethod(...) - - pattern: (org.apache.commons.httpclient.methods.GetMethod $GM).setQueryString(...) - pattern-sources: - - pattern: (HttpServletRequest $REQ).getParameter(...) - severity: ERROR - - id: java_inject_rule-LDAPInjection - languages: - - java - message: | - LDAP injection attacks exploit LDAP queries to influence how data is returned by - the LDAP server. - - Later versions of Java's `InitialDirContext.search` introduced a four argument method, one of - which is the `filterArg` parameter. The `filterArg` will be automatically encoded when - querying - the LDAP server. If this method signature is not available, the application must encode the - LDAP strings manually. - - More details on the four argument `search` method can be found here: - https://docs.oracle.com/en/java/javase/20/docs/api/java.naming/javax/naming/directory/InitialDirContext.html#search(javax.naming.Name,java.lang.String,java.lang.Object[],javax.naming.directory.SearchControls) - - To encode the string manually, it is recommended that all input passed to LDAP querying - systems - encode the following values: - - - Any occurrence of the null character must be escaped as “\00”. - - Any occurrence of the open parenthesis character must be escaped as “\28”. - - Any occurrence of the close parenthesis character must be escaped as “\29”. - - Any occurrence of the asterisk character must be escaped as “\2a”. - - Any occurrence of the backslash character must be escaped as “\5c”. - - Example function that safely encodes user-supplied input to be used in an LDAP query. - ``` - public static String encodeLDAPString(String input) { - // Note the \ character is replaced first - CharSequence[] chars = new CharSequence[] { "\\", "\0", "(", ")", "*" }; - CharSequence[] encoded = new CharSequence[] { "\\5c", "\\00", "\\28", "\\29", "\\2a" }; - // Iterate over each character sequence, replacing the raw value with an encoded version of - it - for (int i = 0; i < chars.length; i++) - { - // re-assign to input - input = input.replace(chars[i], encoded[i]); - } - // return our modified input string - return input; - } - ``` - - Example code that using the `filterArgs` parameter which automatically encodes for us: - ``` - // Create a properties to hold the ldap connection details - Properties props = new Properties(); - // Use the com.sun.jndi.ldap.LdapCtxFactory factory provider - props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); - // The LDAP server URL - props.put(Context.PROVIDER_URL, "ldap://ldap.example.org:3889"); - // User details for the connection - props.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=example,dc=org"); - // LDAP account password - String ldapAccountPassword = getAccountPasswordFromSecureStoreOrKMS(); - // Pass in the LDAP password - props.put(Context.SECURITY_CREDENTIALS, ldapAccountPassword); - - // Create the LDAPContext - InitialDirContext ldapContext = new InitialDirContext(props); - // Example using SUBTREE_SCOPE SearchControls - SearchControls searchControls = new SearchControls(); - searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); - - // Get user input for query - String userQuery = someUserInput; - // Use searchArguments to hold the user-supplied input - Object[] searchArguments = new Object[]{userQuery}; - // Hardcode the BaseDN, use the {0} format specifier to use the searchArguments array value, - and pass in the search controls. - // searchArguments automatically encode - NamingEnumeration answer = ldapContext.search("dc=example,dc=org", "(cn={0})", - searchArguments, searchControls); - // Process the response answer - while (answer.hasMoreElements()) { - ... - } - ``` - - For more information on LDAP Injection see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-90 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of special elements used in an LDAP query ('LDAP Injection') - technology: - - java - mode: taint - pattern-sinks: - - pattern: javax.naming.ldap.LdapName(...) - - pattern: (javax.naming.directory.Context $C).lookup(...) - - pattern: (javax.naming.Context $C).lookup(...) - - patterns: - - pattern-inside: (com.unboundid.ldap.sdk.LDAPConnection $C).search($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-either: - - pattern: $CTX.lookup(...) - - patterns: - - pattern-inside: $CTX.search($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.search($NAME, $FILTER, ...) - - pattern: $FILTER - - metavariable-pattern: - metavariable: $CTX - pattern-either: - - pattern: (DirContext $C) - - pattern: (InitialDirContext $IDC) - - pattern: (LdapContext $LC) - - pattern: (EventDirContext $EDC) - - pattern: (LdapCtx $LC) - - pattern: (javax.naming.directory.DirContext $C) - - pattern: (javax.naming.directory.InitialDirContext $IDC) - - pattern: (javax.naming.ldap.LdapContext $LC) - - pattern: (javax.naming.event.EventDirContext $EDC) - - pattern: (com.sun.jndi.ldap.LdapCtx $LC) - - patterns: - - pattern-either: - - patterns: - - pattern-inside: $CTX.list($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.lookup($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.search($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.search($NAME, $FILTER, ...) - - pattern: $FILTER - - metavariable-pattern: - metavariable: $CTX - pattern-either: - - pattern: (LdapTemplate $LT) - - pattern: (LdapOperations $LO) - - pattern: (org.springframework.ldap.core.LdapTemplate $LT) - - pattern: (org.springframework.ldap.core.LdapOperations $LO) - pattern-sources: - - patterns: - - pattern-inside: | - $FUNC(..., $VAR, ...) { + $INTERM = f"...{$DATA}..." + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + with open(..., $INTERM, ...) as $FD: ... - } - - pattern: $VAR - - patterns: - - pattern-inside: | - $FUNC(..., $X, ...) { + - pattern: | + $DATA = request.$W[...] + ... + open(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + with open(..., $INTERM, ...) as $FD: ... - $VAR = ... + $X; + - pattern: $A = open(..., request.$W[...], ...) + - pattern: $A = open(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $A = open(..., $S % request.$W[...], ...) + - pattern: $A = open(..., f"...{request.$W[...]}...", ...) + - pattern: return open(..., request.$W[...], ...) + - pattern: return open(..., $S.format(..., request.$W[...], ...), ...) + - pattern: return open(..., $S % request.$W[...], ...) + - pattern: return open(..., f"...{request.$W[...]}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + with open(..., $DATA, ...) as $FD: ... - } - - pattern: $VAR - severity: WARNING - - id: java_inject_rule-OgnlInjection - languages: - - java - message: | - The Object Graph Navigation Language (OGNL) is an expression language that allows access to - Java objects and properties stored in an ActionContext. Usage of these low-level - functions is discouraged because they can effectively execute strings as code, leading to - remote code execution vulnerabilities. Consider using struts tags when processing - user-supplied input and templates. - - Much like the Struts security guide recommending to not use raw `${}` EL expressions, - do not call or use the following OGNL packages with user-supplied input: - - - `com.opensymphony.xwork2.ognl` - - `com.opensymphony.xwork2.util` - - `com.opensymphony.xwork2.util.reflection` - - `org.apache.struts2.util.StrutsUtil` - - For more information on Struts2 security see: - https://struts.apache.org/security/#do-not-use-incoming-untrusted-user-input-in-forced-expression-evaluation - metadata: - category: security - cwe: CWE-917 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Expression injection (OGNL) - technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern-inside: com.opensymphony.xwork2.util.TextParseUtil.translateVariables($VAL, ...) - - pattern: $VAL - - patterns: - - pattern-inside: com.opensymphony.xwork2.util.TextParseUtil.translateVariablesCollection($VAL, ...) - - pattern: $VAL - - pattern: com.opensymphony.xwork2.util.TextParseUtil.shallBeIncluded(...) - - pattern: com.opensymphony.xwork2.util.TextParseUtil.commaDelimitedStringToSet(...) - - patterns: - - pattern-inside: (com.opensymphony.xwork2.util.TextParser $P).evaluate($VAR, $VAL, ...) - - pattern: $VAL - - patterns: - - pattern-inside: (com.opensymphony.xwork2.util.OgnlTextParser $P).evaluate($VAR, $VAL, ...) - - pattern: $VAL - - pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getGetMethod($CLZ, ...) - - pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getSetMethod($CLZ, ...) - - pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getField($CLZ, ...) - - patterns: - - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setProperties($MAP, ...) - - pattern: $MAP - - patterns: - - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setProperty($VAL, ...) - - pattern: $VAL - - patterns: - - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getValue($VAL, ...) - - pattern: $VAL - - patterns: - - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setValue($VAL, ...) - - pattern: $VAL - - pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getGetMethod($CLZ, ...) - - pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getSetMethod($CLZ, ...) - - pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getField($CLZ, ...) - - patterns: - - pattern-inside: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).setProperties($MAP, ...) - - pattern: $MAP - - patterns: - - pattern-inside: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).setProperty($VAR, ...) - - pattern: $VAR - - patterns: - - pattern-inside: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getValue($VAR, ...) - - pattern: $VAR - - patterns: - - pattern-inside: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).setValue($VAR, ...) - - pattern: $VAR - - patterns: - - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).setProperties($MAP, ...) - - pattern: $MAP - - patterns: - - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).setProperty($VAR, ...) - - pattern: $VAR - - patterns: - - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).getValue($VAR, ...) - - pattern: $VAR - - patterns: - - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).setValue($VAR, ...) - - pattern: $VAR - - patterns: - - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).callMethod($VAR, ...) - - pattern: $VAR - - patterns: - - pattern-inside: (com.opensymphony.xwork2.ognl.OgnlUtil $P).compile($VAR, ...) - - pattern: $VAR - - pattern: (org.apache.struts2.util.VelocityStrutsUtil $P).evaluate(...) - - pattern: org.apache.struts2.util.StrutsUtil.findString(...) - - pattern: org.apache.struts2.util.StrutsUtil.findValue(..., $VAL) - - pattern: org.apache.struts2.util.StrutsUtil.getText(...) - - pattern: org.apache.struts2.util.StrutsUtil.translateVariables(...) - - patterns: - - pattern-inside: org.apache.struts2.util.StrutsUtil.makeSelectList($VAR, ...) - - pattern: $VAR - - patterns: - - pattern-inside: (org.apache.struts2.views.jsp.ui.OgnlTool $T).findValue($VAR, ...) - - pattern: $VAR - - pattern: (com.opensymphony.xwork2.util.ValueStack $V).findString(...) - - patterns: - - pattern-inside: (com.opensymphony.xwork2.util.ValueStack $V).findValue($VAR, ...) - - pattern: $VAR - - patterns: - - pattern-inside: (com.opensymphony.xwork2.util.ValueStack $V).setValue($VAR, ...) - - pattern: $VAR - - patterns: - - pattern-inside: (com.opensymphony.xwork2.util.ValueStack $V).setParameter($VAR, ...) - - pattern: $VAR - pattern-sources: - - patterns: - - pattern-inside: | - $FUNC(..., $VAR, ...) { + - pattern: open(..., request.$W, ...) + - pattern: open(..., $S.format(..., request.$W, ...), ...) + - pattern: open(..., $S % request.$W, ...) + - pattern: open(..., f"...{request.$W}...", ...) + - pattern: | + $DATA = request.$W + ... + open(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W + ... + open(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W + ... + open(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + with open(..., $INTERM, ...) as $FD: ... - } - - metavariable-pattern: - metavariable: $VAR - pattern-either: - - pattern: (String $S) - - pattern: (Map $M) - - pattern: (Map $M) - - pattern: (Map $M) - - pattern: $VAR - severity: WARNING - - id: java_inject_rule-SpotbugsPathTraversalAbsolute - languages: - - java - message: | - The application dynamically constructs file or path information. If the path - information comes from user input, it could be abused to read sensitive files, - access other users' data, or aid in exploitation to gain further system access. - - User input should never be used in constructing paths or files for interacting - with the filesystem. This includes filenames supplied by user uploads or downloads. - If possible, consider hashing user input or replacing it with unique values and - use `Path.resolve` to resolve and validate the path information - prior to processing any file functionality. - - Example using `Path.resolve` and not allowing direct user input: - ``` - // Class to store our user data along with a randomly generated file name - public static class UserData { - private String userFileNameUnsafe; - private String fileName; - public UserData(String userFileName) { - this.userFileNameUnsafe = userFileName; - // Generate a random ID for the filename - this.fileName = UUID.randomUUID().toString(); - } - public String getUserFileNameUnsafe() { return userFileNameUnsafe; }; - public String getFileName() { return fileName; }; - } - - public static void main(String[] args) throws Exception { - // User input, saved only as a reference - UserData userData = new UserData("..\\test.txt"); - // Restrict all file processing to this directory only - String base = "/var/app/restricted"; - Path basePath = Paths.get(base); - // Resolve the full path, but only use our random generated filename - Path fullPath = basePath.resolve(userData.getFileName()); - // verify the path is contained within our basePath - if (!fullPath.startsWith(base)) { - throw new Exception("Invalid path specified!"); - } - // process / work with file - } - ``` - - For more information on path traversal issues see OWASP: - https://owasp.org/www-community/attacks/Path_Traversal - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - technology: - - java - mode: taint - pattern-propagators: - - from: $X - pattern: $LIST.add($X) - to: $LIST - - from: $X - pattern: $MAP.put(..., $X) - to: $MAP - - from: $X - pattern: $STR.concat($X) - to: $STR - - from: $X - pattern: $STR = String.format(..., $X, ...) - to: $STR - - from: $X - pattern: $STR = String.join(..., $X, ...) - to: $STR - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - - patterns: - - pattern-inside: | - $U = new java.net.URI($VAR) - - pattern-either: - - pattern-inside: new java.io.File($U) - - pattern-inside: java.nio.file.Paths.get($U) - - pattern: $VAR - - patterns: - - pattern-inside: new java.io.RandomAccessFile($INPUT,...) - - pattern: $INPUT - - pattern: new java.io.FileReader(...) - - pattern: new javax.activation.FileDataSource(...) - - pattern: new java.io.FileInputStream(...) - - pattern: new java.io.FileOutputStream(...) - - pattern: new java.io.File(...) - - pattern: java.nio.file.Paths.get(...) - - pattern: java.io.File.createTempFile(...) - - pattern: java.io.File.createTempDirectory(...) - - pattern: java.nio.file.Files.createTempFile(...) - - pattern: java.nio.file.Files.createTempDirectory(...) - - patterns: - - pattern: $SRC.$METHOD(...) - - metavariable-pattern: - metavariable: $SRC - pattern-either: - - pattern: getClass() - - pattern: getClass().getClassLoader() - - pattern: (ClassLoader $C) - - pattern: (Class $C) - - pattern: $CLZ.getClassLoader() - - metavariable-pattern: - metavariable: $METHOD - pattern-either: - - pattern: getResourceAsStream - - pattern: getResource - - patterns: - - pattern-inside: new java.io.FileWriter($PATH, ...) - - pattern: $PATH - - patterns: - - pattern-inside: new java.io.FileOutputStream($PATH, ...) - - pattern: $PATH - pattern-sources: - - pattern: (javax.servlet.http.HttpServletRequest $R).$METHOD(...) - - pattern: (java.util.Scanner $S).$METHOD(...) - - pattern: (java.util.stream.Stream).$METHOD(...) - - pattern: (java.util.StringJoiner $SJ).toString(...) - - pattern: (java.sql.ResultSet.getString $R).$METHOD(...) - - pattern: (java.lang.System $S).getProperty(...) - - pattern: (java.lang.System $S).getenv(...) - - pattern: (java.lang.StringBuilder $SB).toString(...) - - pattern: (java.io.FileInputStream $F).read(...) - - pattern: (java.io.FileReader $F).read(...) - - pattern: (java.net.Socket $S).getInputStream(...) - - pattern: (java.net.Socket $S).getOutputStream(...) - - pattern: (java.net.DatagramSocket $S).receive(...) - - pattern: (java.net.DatagramSocket $S).getInputStream(...) - - pattern: java.nio.file.Files.readAllBytes(...) - - pattern: java.nio.file.Files.readAllLines(...) - - pattern: java.nio.file.Files.lines(...) - - pattern: java.nio.file.Files.newBufferedReader(...) - - pattern: org.apache.commons.io.IOUtils.toString(...) - - pattern: org.apache.commons.io.IOUtils.readLines(...) - - pattern: org.apache.commons.io.IOUtils.toByteArray(...) - - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).readValue(...) - - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).treeToValue(...) - - pattern: $CLASS.$METHOD(..., (javax.servlet.http.HttpServletRequest $R), ...) - - pattern: $FUNC(..., (javax.servlet.http.HttpServletRequest $R), ...) - - patterns: - - pattern-inside: $FUNC(..., @RequestParam String $X, ...) { ... } - - focus-metavariable: $X - severity: WARNING - - id: java_ldap_rule-AnonymousLDAP - languages: - - java - message: | - The application does not provide authentication when communicating an LDAP - server. It is strongly recommended that the LDAP server be configured with - authentication and restrict what queries users can execute. - - Example code that authenticates with a remote LDAP server and encodes any - user-supplied input: - ``` - // Create a properties to hold the ldap connection details - Properties props = new Properties(); - // Use the com.sun.jndi.ldap.LdapCtxFactory factory provider - props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); - // The LDAP server URL - props.put(Context.PROVIDER_URL, "ldap://ldap.example.org:3889"); - // User details for the connection - props.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=example,dc=org"); - // LDAP account password - String ldapAccountPassword = getAccountPasswordFromSecureStoreOrKMS(); - // Pass in the LDAP password - props.put(Context.SECURITY_CREDENTIALS, ldapAccountPassword); - - // Create the LDAPContext - InitialDirContext ldapContext = new InitialDirContext(props); - // Example using SUBTREE_SCOPE SearchControls - SearchControls searchControls = new SearchControls(); - searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); - - // Get user input for query - String userQuery = someUserInput; - // Use searchArguments to hold the user-supplied input - Object[] searchArguments = new Object[]{userQuery}; - // Hardcode the BaseDN, use the {0} format specifier to use the searchArguments array value, - and pass in the search controls. - // searchArguments automatically encode - NamingEnumeration answer = ldapContext.search("dc=example,dc=org", "(cn={0})", - searchArguments, searchControls); - // Process the response answer - while (answer.hasMoreElements()) { - ... - } - ``` - - For information on enabling authentication, please see your LDAP server's - documentation. - - For more information on LDAP Injection see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-306 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: High - shortDescription: Missing authentication for critical function (LDAP) - patterns: - - pattern-inside: | - import javax.naming.Context; - ... - - pattern: $ENV.put(Context.SECURITY_AUTHENTICATION, "none"); - severity: WARNING - - id: java_password_rule-ConstantDBPassword - languages: - - java - message: | - A potential hard-coded password was identified in a database connection string. - Passwords should not be stored directly in code - but loaded from secure locations such as a Key Management System (KMS). - - The purpose of using a Key Management System is so access can be audited and keys easily - rotated - in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine - when or if, a key is compromised. - - The recommendation on which KMS to use depends on the environment the application is running - in: - - - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - - For on premise or other alternatives to cloud providers, consider [Hashicorp's - Vault](https://www.vaultproject.io/) - - For other cloud providers, please see their documentation - metadata: - category: security - cwe: CWE-259 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: Critical - shortDescription: Use of hard-coded password - technology: - - java - patterns: - - pattern: java.sql.DriverManager.getConnection($URI, $USR, "..."); - severity: ERROR - - id: java_password_rule-EmptyDBPassword - languages: - - java - message: | - The application does not provide authentication when communicating a database - server. It is strongly recommended that the database server be configured with - authentication and restrict what queries users can execute. - - Please see your database server's documentation on how to configure a password. - - Additionally, passwords should not be stored directly in code - but loaded from secure locations such as a Key Management System (KMS). - - The purpose of using a Key Management System is so access can be audited and keys easily - rotated - in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine - when or if, a key is compromised. - - The recommendation on which KMS to use depends on the environment the application is running - in: - - - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - - For on premise or other alternatives to cloud providers, consider [Hashicorp's - Vault](https://www.vaultproject.io/) - - For other cloud providers, please see their documentation - metadata: - category: security - cwe: CWE-306 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: Critical - shortDescription: Missing authentication for critical function (database) - technology: - - java - patterns: - - pattern: java.sql.DriverManager.getConnection($URI, $USR, ""); - severity: ERROR - - id: java_password_rule-HardcodePassword - languages: - - java - message: | - A potential hard-coded password was identified in a hard-coded string. - Passwords should not be stored directly in code - but loaded from secure locations such as a Key Management System (KMS). - - The purpose of using a Key Management System is so access can be audited and keys easily - rotated - in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine - when or if, a key is compromised. - - The recommendation on which KMS to use depends on the environment the application is running - in: - - - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - - For on premise or other alternatives to cloud providers, consider [Hashicorp's - Vault](https://www.vaultproject.io/) - - For other cloud providers, please see their documentation - metadata: - category: security - cwe: CWE-259 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: High - shortDescription: Use of hard-coded password - technology: - - java - pattern-either: - - pattern: new java.security.KeyStore.PasswordProtection("...".toCharArray()) - - pattern: java.security.KeyStore.getInstance(...).load(..., "...".toCharArray()) - - pattern: (java.security.KeyStore $KS).load(..., "...".toCharArray()) - - pattern: KeyManagerFactory.getInstance(...).init(..., "...".toCharArray()) - - pattern: (KeyManagerFactory $KMF).init(..., "...".toCharArray()) - - pattern: PBEKeySpec("...", ...) - - pattern: PasswordAuthentication("...", "...") - - pattern: (PasswordCallback $CB).setPassword("...") - - pattern: KerberosKey(...,"...",...) - - pattern: java.sql.DriverManager.getConnection(..., "...") - - pattern: io.vertx.ext.web.handler.CSRFHandler.create(..., "...") - - pattern: $S.setPassword("...") - severity: ERROR - - id: java_perm_rule-DangerousPermissions - languages: - - java - message: | - The application was found to permit the `RuntimePermission` of `createClassLoader`, - `ReflectPermission` of `suppressAccessChecks`, or both. - - By granting the `RuntimePermission` of `createClassLoader`, a compromised application - could instantiate their own class loaders and load arbitrary classes. - - By granting the `ReflectPermission` of `suppressAccessChecks` an application will no longer - check Java language access checks on fields and methods of a class. This will effectively - grant access to protected and private members. - - For more information on `RuntimePermission` see: - https://docs.oracle.com/javase/8/docs/api/java/lang/RuntimePermission.html - - For more information on `ReflectPermission` see: - https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/ReflectPermission.html - metadata: - category: security - confidence: HIGH - cwe: CWE-732 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Incorrect permission assignment for critical resource - pattern-either: - - pattern: | - $RUNVAR = new RuntimePermission("createClassLoader"); - ... - (PermissionCollection $PC).add($RUNVAR); - - pattern: | - $REFVAR = new ReflectPermission("suppressAccessChecks"); - ... - (PermissionCollection $PC).add($REFVAR); - - pattern: (PermissionCollection $PC).add(new ReflectPermission("suppressAccessChecks")) - - pattern: (PermissionCollection $PC).add(new RuntimePermission("createClassLoader")) - severity: WARNING - - id: java_perm_rule-OverlyPermissiveFilePermissionInline - languages: - - java - message: | - The application was found setting file permissions to overly permissive values. Consider - using the following values if the application user is the only process to access - the file: - - - `r--` - read only access to the file - - `w--` - write only access to the file - - `rw-` - read/write access to the file - - Example setting read/write permissions for only the owner of a `Path`: - ``` - // Get a reference to the path - Path path = Paths.get("/tmp/somefile"); - // Create a PosixFilePermission set from java.nio.file.attribute - Set permissions = - java.nio.file.attribute.PosixFilePermissions.fromString("rw-------"); - // Set the permissions - java.nio.file.Files.setPosixFilePermissions(path, permissions); - ``` - - For all other values please see: - https://en.wikipedia.org/wiki/File-system_permissions#Symbolic_notation - metadata: - category: security - confidence: HIGH - cwe: CWE-732 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Incorrect permission assignment for critical resource - patterns: - - pattern-either: - - pattern: java.nio.file.Files.setPosixFilePermissions(..., java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING")); - pattern: | - $PERMISSIONS = java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING"); + $DATA = request.$W ... - java.nio.file.Files.setPosixFilePermissions(..., $PERMISSIONS); - - metavariable-regex: - metavariable: $PERM_STRING - regex: '[rwx-]{6}[rwx]{1,}' + open(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: | + $DATA = request.$W + ... + open(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + open(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + with open(..., $INTERM, ...) as $FD: + ... + - pattern: $A = open(..., request.$W, ...) + - pattern: $A = open(..., $S.format(..., request.$W, ...), ...) + - pattern: $A = open(..., $S % request.$W, ...) + - pattern: $A = open(..., f"...{request.$W}...", ...) + - pattern: return open(..., request.$W, ...) + - pattern: return open(..., $S.format(..., request.$W, ...), ...) + - pattern: return open(..., $S % request.$W, ...) + - pattern: return open(..., f"...{request.$W}...", ...) + - pattern: | + $DATA = request.$W + ... + with open(..., $DATA, ...) as $FD: + ... severity: WARNING - - id: java_script_rule-ScriptInjection + - id: python.django.security.injection.raw-html-format.raw-html-format languages: - - java - message: | - The application executes an argument using a `ScriptEngine`'s `eval` method. This - may allow for direct OS commands to be executed as it's possible to pass in strings - such as `java.lang.Runtime.getRuntime().exec('/bin/sh ...');`. - - Never pass user-supplied input directly to the `eval` function. If possible hardcode all - JavasScript code or use a lookup table to resolve user input to known values. If none of these - techniques are possible, use `javax.script.Bindings` to pass input to the script engine. - - Example using `Binding` to safely pass in string values: - ``` - // Get ECMAScript engine - ScriptEngine engine = new ScriptEngineManager().getEngineByName("ECMAScript"); - - // User input, consisting of first and last name - String userFirstName = "John"; - String userLastName = "Snow"; - - // Create bindings to pass into our script, forcing the values to be String. - Bindings bindings = engine.createBindings(); - bindings.put("fname", new String(userFirstName)); - bindings.put("lname", new String(userLastName)); - - // Example script that concatenates a greeting with the user-supplied input first/last name - String script = "var greeting='Hello ';" + - // fname and lname variables will be resolved by our bindings defined above - "greeting += fname + ' ' + lname;" + - // prints greeting - "greeting"; - - try { - // Execute the script, passing in the bindings - Object bindingsResult = engine.eval(script, bindings); - // Work with result - // ... - } catch (ScriptException e) { - // Handle exception - e.printStackTrace(); - } - ``` + - python + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates (`django.shortcuts.render`) which will safely render HTML instead. metadata: category: security - cwe: CWE-94 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper control of generation of code ('Code Injection') + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://docs.djangoproject.com/en/3.2/topics/http/shortcuts/#render + - https://docs.djangoproject.com/en/3.2/topics/security/#cross-site-scripting-xss-protection + subcategory: + - vuln + technology: + - django mode: taint + pattern-sanitizers: + - pattern: django.utils.html.escape(...) pattern-sinks: - - patterns: - - pattern: (javax.script.ScriptEngine $ENGINE).eval($ARG, ...); - - pattern-not: (javax.script.ScriptEngine $ENGINE).eval("..."); - - pattern-not: (javax.script.ScriptEngine $ENGINE).eval("...", (javax.script.Bindings $BINDING)); - patterns: - pattern-either: - - pattern: (javax.script.Invocable $INVC).invokeFunction(..., $ARG) - - pattern: (javax.script.Invocable $INVC).invokeMethod(..., $ARG) + - patterns: + - pattern-either: + - pattern: '"$HTMLSTR" % ...' + - pattern: '"$HTMLSTR".format(...)' + - pattern: '"$HTMLSTR" + ...' + - pattern: f"$HTMLSTR{...}..." + - patterns: + - pattern-inside: | + $HTML = "$HTMLSTR" + ... + - pattern-either: + - pattern: $HTML % ... + - pattern: $HTML.format(...) + - pattern: $HTML + ... + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... pattern-sources: - patterns: - - pattern-inside: $FUNC(..., $VAR, ...) { ... } - - pattern: $VAR - severity: ERROR - - id: java_script_rule-SpringSpelExpressionParser + - pattern: request.$ANYTHING + - pattern-not: request.build_absolute_uri + severity: WARNING + - id: python.django.security.injection.reflected-data-httpresponse.reflected-data-httpresponse languages: - - java - message: | - The application was found calling SpringFramework's `SpelExpressionParser.parseExpression`. - Calling this method directly with user-supplied input may allow an adversary to - execute arbitrary Java code including OS system commands. - - Never call `parseExpression` or `parseRaw` directly with user-supplied input. Consider - alternate - methods such as a lookup table to take user input and resolve hardcoded values. - - Later versions of SpringFramework introduced a `SimpleEvaluationContext` which can be - used to access bound data when calling the `getValue` result of `parseExpression`. This - `SimpleEvaluationContext` has a reduced set of functionality and can restrict data binding - to read-only or read-write contexts. An adversary could still access public properties - or fields on custom types that have been provided to the evaluation context. Use with caution. - - Example using `SimpleEvaluationContext` with a read-write data binding context: - ``` - @RequestMapping(value="/spel", method=RequestMethod.POST) - public String spel(@Validated User user, Model model) { - // Create the Expression Parser - SpelExpressionParser parser = new SpelExpressionParser(); - // Parse the expression - Expression parsedExpression = parser.parseExpression(model.getPossiblyUnsafeData()); - // Create the read-write data binding context - SimpleEvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build(); - // Execute the expression, passing in the read-write context - Object result = parsedExpression.getValue(context); - // work with the result - // ... - return "user"; - } - ``` - - For more information on SimpleEvaluationContext see: - https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/expression/spel/support/SimpleEvaluationContext.html + - python + message: Found user-controlled request data passed into HttpResponse. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed. metadata: category: security - cwe: CWE-917 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an expression language statement ('Expression Language Injection') + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss + subcategory: + - vuln + technology: + - django patterns: - - pattern: ($PARSER $P).$METHOD($ARG); - - pattern-not: ($PARSER $P).$METHOD("..."); - - metavariable-pattern: - metavariable: $PARSER - pattern-either: - - pattern: org.springframework.expression.spel.standard.SpelExpressionParser - - pattern: org.springframework.expression.ExpressionParser - - metavariable-regex: - metavariable: $METHOD - regex: (parseExpression|parseRaw) - severity: ERROR - - id: java_smtp_rule-InsecureSmtp + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: django.http.HttpResponse(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: django.http.HttpResponse(..., $S % request.$W.get(...), ...) + - pattern: django.http.HttpResponse(..., f"...{request.$W.get(...)}...", ...) + - pattern: django.http.HttpResponse(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponse(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponse(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponse(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponse(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponse(..., request.$W.get(...), ...) + - pattern: return django.http.HttpResponse(..., request.$W.get(...), ...) + - pattern: django.http.HttpResponse(..., $S.format(..., request.$W(...), ...), ...) + - pattern: django.http.HttpResponse(..., $S % request.$W(...), ...) + - pattern: django.http.HttpResponse(..., f"...{request.$W(...)}...", ...) + - pattern: django.http.HttpResponse(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponse(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponse(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponse(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponse(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponse(..., request.$W(...), ...) + - pattern: return django.http.HttpResponse(..., request.$W(...), ...) + - pattern: django.http.HttpResponse(..., $S.format(..., request.$W[...], ...), ...) + - pattern: django.http.HttpResponse(..., $S % request.$W[...], ...) + - pattern: django.http.HttpResponse(..., f"...{request.$W[...]}...", ...) + - pattern: django.http.HttpResponse(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponse(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponse(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponse(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.HttpResponse(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponse(..., request.$W[...], ...) + - pattern: return django.http.HttpResponse(..., request.$W[...], ...) + - pattern: django.http.HttpResponse(..., $S.format(..., request.$W, ...), ...) + - pattern: django.http.HttpResponse(..., $S % request.$W, ...) + - pattern: django.http.HttpResponse(..., f"...{request.$W}...", ...) + - pattern: django.http.HttpResponse(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponse(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponse(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponse(..., f"...{$DATA}...", ...) + - pattern: $A = django.http.HttpResponse(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + $A = django.http.HttpResponse(..., $INTERM, ...) + - pattern: return django.http.HttpResponse(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponse(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponse(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponse(..., $INTERM, ...) + severity: WARNING + - id: python.django.security.injection.reflected-data-httpresponsebadrequest.reflected-data-httpresponsebadrequest languages: - - java - message: | - The Apache commons mail client by default does not enable TLS server identity. - This allows for an adversary who is in between the application and the target host to intercept - potentially sensitive information or transmit malicious data. - - Enable checking server identity by calling `Email.setSSLCheckServerIdentity(true)` - - Example email client that enables TLS and server identity: - ``` - // Create an email client - Email email = new SimpleEmail(); - // Configure the email hostname - email.setHostName("smtp.mail.example.com"); - // Set the port - email.setSmtpPort(465); - // Securely retrieve username and password values - String username = getUserNameFromKMSorSecretStore(); - String password = getPasswordFromKMSorSecretStore(); - // Configure the Authenticator - DefaultAuthenticator auth = new DefaultAuthenticator(username, password); - // Set the authenticator - email.setAuthenticator(auth); - // Ensure we use SSL on connect - email.setSSLOnConnect(true); - // Ensure we validate server identity - email.setSSLCheckServerIdentity(true); - // configure the rest of the email - email.setFrom("x@example.com"); - email.setSubject("TestMail"); - email.setMsg("This is a test mail ... :-)"); - email.addTo("y@example.com"); - email.send(); - ``` + - python + message: Found user-controlled request data passed into a HttpResponseBadRequest. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed. metadata: category: security - cwe: CWE-297 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Improper validation of certificate with host mismatch + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss + subcategory: + - vuln + technology: + - django patterns: + - pattern-inside: | + def $FUNC(...): + ... - pattern-either: - - pattern-inside: | - $E = new org.apache.commons.mail.SimpleEmail(...); + - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W.get(...), ...) + - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W.get(...)}...", ...) + - pattern: django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseBadRequest(..., $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) + - pattern: return django.http.HttpResponseBadRequest(..., request.$W.get(...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W(...), ...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W(...), ...) + - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W(...)}...", ...) + - pattern: django.http.HttpResponseBadRequest(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseBadRequest(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) ... - - pattern-inside: | - $E = new org.apache.commons.mail.Email(...); + django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W(...) ... - - pattern-inside: | - $E = new org.apache.commons.mail.MultiPartEmail(...); + $INTERM = $STR + $DATA ... - - pattern-inside: | - $E = new org.apache.commons.mail.HtmlEmail(...); + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W(...), ...) + - pattern: return django.http.HttpResponseBadRequest(..., request.$W(...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W[...], ...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W[...], ...) + - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W[...]}...", ...) + - pattern: django.http.HttpResponseBadRequest(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] ... - - pattern-inside: | - $E = new org.apache.commons.mail.ImageHtmlEmail(...); + django.http.HttpResponseBadRequest(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] ... - - pattern-not: | - $E.setSSLOnConnect(true); - ... - $E.setSSLCheckServerIdentity(true); - severity: ERROR - - id: java_smtp_rule-SmtpClient - languages: - - java - message: | - The application was found calling `MimeMessage` methods without encoding - new line characters. Much like HTTP, Simple Mail Transfer Protocol (SMTP) is a - text based protocol that uses headers to convey additional directives for how - email messages should be treated. An adversary could potentially cause email - messages to be sent to unintended recipients by abusing the CC or BCC headers - if they were able to inject them. - - To mitigate this issue, `\r\n` (CRLF) character sequences must be escaped - or encoded prior to being used in any of the `MimeMessage` methods. - - Example that escapes values that come from user input with - [Apache Commons Text](https://commons.apache.org/proper/commons-text/): - ``` - // Create a MimeMessage with a javax.mail.Session - Message message = new MimeMessage(session); - // Set the from address - message.setFrom(new InternetAddress("source@example.com")); - // Set the to address - message.setRecipients(Message.RecipientType.TO,new InternetAddress[] {new - InternetAddress("destination@example.com")}); - // Example user input - String subject = "potentially malicious data"; - String headerValue = "potentially malicious data"; - // Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \\r\\n. - message.setSubject(StringEscapeUtils.escapeJava(subject)); - // Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \\r\\n. - message.addHeader("HeaderName", StringEscapeUtils.escapeJava(header)); - // Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \\r\\n. - message.setDescription(StringEscapeUtils.escapeJava("some description")); - // Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \\r\\n. - message.setDisposition(StringEscapeUtils.escapeJava("some disposition")); - // Set the mail body text - message.setText("Some email content."); - // Send the message - ``` - metadata: - category: security - cwe: CWE-77 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Low - shortDescription: Improper neutralization of special elements used in a command - patterns: - - pattern-inside: | - $M = new MimeMessage(...); - ... - - pattern-either: - - patterns: - - pattern-either: - - pattern: $M.setSubject($VAR) - - pattern: $M.addHeader($ARG, $VAR) - - pattern: $M.addHeader($VAR, $ARG) - - pattern: $M.setDescription($VAR) - - pattern: $M.setDisposition($VAR) - - metavariable-regex: - metavariable: $VAR - regex: ^[a-zA-Z_$][a-zA-Z0-9_$]*$ - - patterns: - - pattern-either: - - pattern: $M.setSubject($OBJ.$GETTER(...)) - - pattern: $M.setSubject($OBJ.$GETTER(...) + ...) - - pattern: $M.setSubject(... + $OBJ.$GETTER(...)) - - pattern: $M.setSubject(... + $OBJ.$GETTER(...) + ...) - - pattern: $M.addHeader($ARG, $OBJ.$GETTER(...)) - - pattern: $M.addHeader($ARG, $OBJ.$GETTER(...) + ...) - - pattern: $M.addHeader($ARG, ... + $OBJ.$GETTER(...)) - - pattern: $M.addHeader($ARG, ... + $OBJ.$GETTER(...) + ...) - - pattern: $M.addHeader($OBJ.$GETTER(...), $ARG) - - pattern: $M.addHeader($OBJ.$GETTER(...) + ..., $ARG) - - pattern: $M.addHeader(... + $OBJ.$GETTER(...), $ARG) - - pattern: $M.addHeader(... + $OBJ.$GETTER(...) + ..., $ARG) - - pattern: $M.setDescription($OBJ.$GETTER(...)) - - pattern: $M.setDisposition($OBJ.$GETTER(...) + ...) - - pattern: $M.setDisposition(... + $OBJ.$GETTER(...)) - - pattern: $M.setDisposition(... + $OBJ.$GETTER(...) + ...) - - metavariable-regex: - metavariable: $GETTER - regex: ^get - severity: ERROR - - id: java_ssrf_rule-SSRF - languages: - - java - message: | - Server-Side-Request-Forgery (SSRF) exploits backend systems that initiate requests to third - parties. - If user input is used in constructing or sending these requests, an attacker could supply - malicious - data to force the request to other systems or modify request data to cause unwanted actions. - - Ensure user input is not used directly in constructing URLs or URIs when initiating requests - to third party - systems from back end systems. Care must also be taken when constructing payloads using user - input. Where - possible restrict to known URIs or payloads. Consider using a server-side map where keys are - used to return - URLs such as `https://site/goto?key=1` where `{key: 1, url: 'http://some.url/', key: 2, url: - 'http://...'}`. - - If you must use user-supplied input for requesting URLs, it is strongly recommended that the - HTTP client - chosen allows you to customize and block certain IP ranges at the network level. By blocking - RFC 1918 - addresses or other network address ranges, you can limit the severity of a successful SSRF - attack. Care must - also be taken to block certain protocol or address formatting such as IPv6. - - If you cannot block address ranges at the client level, you may want to run the HTTP client - as a protected - user, or in a protected network where you can apply IP Table or firewall rules to block access - to dangerous - addresses. Finally, if none of the above protections are available, you could also run a - custom HTTP proxy - and force all requests through it to handle blocking dangerous addresses. - - Example using a map to look up a key to be used in a HTTP request: - ``` - HashMap lookupTable = new HashMap<>(); - lookupTable.put("key1", "https://example.com/"); - lookupTable.put("key2", "https://safeurl.com/"); - String userInput = request.getParameter("key"); - - // Create a CloseableHttpClient, ideally any requests issued should be done - // out-of-band from the servlet request itself (such as using a separate thread/scheduler - system) - try (final CloseableHttpClient httpClient = HttpClients.createDefault()) { - // Lookup the value from our user input from our lookupTable - String value = lookupTable.getOrDefault(userInput, "https://example.com/"); - // Construct the url, with the hardcoded url and only pass in the value from the - lookupTable, - // not direct user input - final HttpGet httpget = new HttpGet(value); - // Execute the request - CloseableHttpResponse clientResponse = httpClient.execute(httpget); - // Read the response - byte[] responseData = clientResponse.getEntity().getContent().readAllBytes(); - // Handle the response - // ... - } - ``` - - If using a map is not possible, the user-supplied input must be encoded prior to use, and - never allow full - URLs: - ``` - // Get user input - String userInput = request.getParameter("key"); - // Encode the string using java.net.URLEncoder with the UTF-8 character set - String encodedString = java.net.URLEncoder.encode(userInput, StandardCharsets.UTF_8); - // Create a CloseableHttpClient, ideally any requests issued should be done - // out-of-band from the servlet request itself (such as using a separate thread/scheduler - system) - try (final CloseableHttpClient httpClient = HttpClients.createDefault()) { - // Construct the url, with the hardcoded url and only pass in the encoded value, never a - full URL - final HttpGet httpget = new HttpGet("https://example.com/getId?key="+encodedString); - // Execute the request - CloseableHttpResponse clientResponse = httpClient.execute(httpget); - // Read the response - byte[] responseData = clientResponse.getEntity().getContent().readAllBytes(); - // handle the response - } - ``` - - For more information on SSRF see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-918 - owasp: - - A1:2017-Injection - - A10:2021-Server-Side Request Forgery - security-severity: Medium - shortDescription: Server-Side Request Forgery (SSRF) - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - import java.net.*; - ... - - pattern-inside: | - import java.net.URL; - ... - - pattern-inside: | - import java.net.URI; - ... - - pattern: new $TYPE(...). ... .$FUNC - - pattern-not: new $TYPE("..."). ... .$FUNC - - metavariable-pattern: - metavariable: $FUNC - pattern-either: - - pattern: connect - - pattern: GetContent - - pattern: openConnection - - pattern: openStream - - pattern: getContent - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: URL - - pattern: java.net.URL - - pattern: URI - - pattern: java.net.URI - - patterns: - - pattern-either: - - pattern-inside: | - import java.net.*; - ... - - pattern-inside: | - import java.net.InetSocketAddress; - ... + $INTERM = $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) - pattern: | - new InetSocketAddress(..., $PORT) - - pattern-not: | - new InetSocketAddress("...", $PORT) - severity: ERROR - - id: java_strings_rule-BadHexConversion - languages: - - java - message: | - The application is using `Integer.toHexString` on a digest array buffer which - may lead to an incorrect version of values. - - Consider using the `java.util.HexFormat` object introduced in Java 17. For older Java applications - consider using the `javax.xml.bind.DatatypeConverter`. - - Example using `HexFormat` to create a human-readable string: - ``` - // Create a MessageDigest using the SHA-384 algorithm - MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384"); - // Call update with your data - sha384Digest.update("some input".getBytes(StandardCharsets.UTF_8)); - // Only call digest once all data has been fed into the update sha384digest instance - byte[] output = sha384Digest.digest(); - // Create a JDK 17 HexFormat object - HexFormat hex = HexFormat.of(); - // Use formatHex on the byte array to create a string (note that alphabet characters are - lowercase) - String hexString = hex.formatHex(output); - ``` - - For more information on DatatypeConverter see: - https://docs.oracle.com/javase/9/docs/api/javax/xml/bind/DatatypeConverter.html#printHexBinary-byte:A- - metadata: - category: security - confidence: HIGH - cwe: CWE-704 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Info - shortDescription: Incorrect type conversion or cast - patterns: - - pattern-inside: | - $B_ARR = (java.security.MessageDigest $MD).digest(...); - ... - - pattern-either: + $DATA = request.$W[...] + ... + django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) - pattern: | - for(...) { - ... - $B = $B_ARR[...]; - ... - Integer.toHexString($B); - } + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) - pattern: | - for(...) { - ... - Integer.toHexString($B_ARR[...]); - } + $DATA = request.$W[...] + ... + django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) - pattern: | - for(byte $B :$B_ARR) { - ... - Integer.toHexString($B); - } + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) - pattern: | - while(...) { - ... - Integer.toHexString($B_ARR[...]) - } + $DATA = request.$W[...] + ... + django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) - pattern: | - do { - ... - Integer.toHexString($B_ARR[...]) - } while(...) + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) - pattern: | - while(...) { - ... - $B = $B_ARR[...]; - ... - Integer.toHexString($B); - } + $DATA = request.$W[...] + ... + django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) - pattern: | - do { - ... - $B = $B_ARR[...]; - ... - Integer.toHexString($B); - } while(...) + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W[...], ...) + - pattern: return django.http.HttpResponseBadRequest(..., request.$W[...], ...) + - pattern: django.http.HttpResponseBadRequest(..., $S.format(..., request.$W, ...), ...) + - pattern: django.http.HttpResponseBadRequest(..., $S % request.$W, ...) + - pattern: django.http.HttpResponseBadRequest(..., f"...{request.$W}...", ...) + - pattern: django.http.HttpResponseBadRequest(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseBadRequest(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseBadRequest(..., $STR.format(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseBadRequest(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseBadRequest(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + django.http.HttpResponseBadRequest(..., $STR + $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + django.http.HttpResponseBadRequest(..., $INTERM, ...) + - pattern: $A = django.http.HttpResponseBadRequest(..., request.$W, ...) + - pattern: return django.http.HttpResponseBadRequest(..., request.$W, ...) severity: WARNING - - id: java_strings_rule-FormatStringManipulation + - id: python.django.security.injection.request-data-fileresponse.request-data-fileresponse languages: - - java - message: | - The application allows user input to control format string parameters. By passing invalid - format - string specifiers an adversary could cause the application to throw exceptions or possibly - leak - internal information depending on application logic. - - Never allow user-supplied input to be used to create a format string. Replace all format - string - arguments with hardcoded format strings containing the necessary specifiers. - - Example of using `String.format` safely: - ``` - // Get untrusted user input - String userInput = request.getParameter("someInput"); - // Ensure that user input is not included in the first argument to String.format - String.format("Hardcoded string expecting a string: %s", userInput); - // ... - ``` + - python + message: Found user-controlled request data being passed into a file open, which is them passed as an argument into the FileResponse. This is dangerous because an attacker could specify an arbitrary file to read, which could result in leaking important data. Be sure to validate or sanitize the user-inputted filename in the request data before using it in FileResponse. metadata: category: security - confidence: HIGH - cwe: CWE-134 + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Use of externally-controlled format string + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss + subcategory: + - vuln + technology: + - django patterns: + - pattern-inside: | + def $FUNC(...): + ... - pattern-either: - - patterns: - - pattern-inside: | - String $INPUT = (HttpServletRequest $REQ).getParameter(...); - ... - - pattern-inside: | - String $FORMAT_STR = ... + $INPUT; - ... - - patterns: - - pattern-inside: | - String $INPUT = (HttpServletRequest $REQ).getParameter(...); - ... - - pattern-inside: | - String $FORMAT_STR = ... + $INPUT + ...; - ... - - pattern-inside: | - String $FORMAT_STR = ... + (HttpServletRequest $REQ).getParameter(...) + ...; + - pattern: django.http.FileResponse(..., request.$W.get(...), ...) + - pattern: | + $DATA = request.$W.get(...) ... - - pattern-inside: | - String $FORMAT_STR = ... + (HttpServletRequest $REQ).getParameter(...); + django.http.FileResponse(..., open($DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) ... - - pattern-either: - - pattern: String.format($FORMAT_STR, ...); - - pattern: String.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - - pattern: (java.util.Formatter $F).format($FORMAT_STR, ...); - - pattern: (java.util.Formatter $F).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - - pattern: (java.io.PrintStream $F).printf($FORMAT_STR, ...); - - pattern: (java.io.PrintStream $F).printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - - pattern: (java.io.PrintStream $F).format($FORMAT_STR, ...); - - pattern: (java.io.PrintStream $F).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - - pattern: System.out.printf($FORMAT_STR, ...); - - pattern: System.out.printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - - pattern: System.out.format($FORMAT_STR, ...); - - pattern: System.out.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); - severity: ERROR - - id: java_strings_rule-ModifyAfterValidation - languages: - - java - message: |+ - The application was found matching a variable during a regular expression - pattern match, and then calling string modification functions after validation has occurred. - This is usually indicative of a poor input validation strategy as an adversary may attempt to - exploit the removal of characters. - - For example a common mistake in attempting to remove path characters to protect against path - traversal is to match '../' and then remove any matches. However, if an adversary were to - include in their input: '....//' then the `replace` method would replace the first `../` but - cause the leading `..` and trailing `/` to join into the final string of `../`, effectively - bypassing the check. - - To remediate this issue always perform string modifications before any validation of a string. - It is strongly recommended that strings be encoded instead of replaced or removed prior to - validation. - - - Example replaces `..` before validation. Do note this is still not a recommended method for - protecting against directory traversal, always use randomly generated IDs or filenames instead: - ``` - // This is ONLY for demonstration purpose, never use untrusted input - // in paths, always use randomly generated filenames or IDs. - String input = "test../....//dir"; - // Use replaceAll _not_ replace - input = input.replaceAll("\\.\\.", ""); - // Input would be test///dir at this point - // Create a pattern to match on - Pattern pattern = Pattern.compile("\\.\\."); - // Create a matcher - Matcher match = pattern.matcher(input); - // Call find to see if .. is still in our string - if (match.find()) { - throw new Exception(".. detected"); - } - // Use the input (but do not modify the string) - System.out.println(input + " safe"); - ``` - - For more information see Carnegie Mellon University's Secure Coding Guide: - https://wiki.sei.cmu.edu/confluence/display/java/IDS11-J.+Perform+any+string+modifications+before+validation - - metadata: - category: security - confidence: HIGH - cwe: CWE-182 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Info - shortDescription: Collapse of data into unsafe value - patterns: - - pattern: | - (java.util.regex.Pattern $Y).matcher($VAR); - ... - $VAR.$METHOD(...); - - metavariable-regex: - metavariable: $METHOD - regex: (replace|replaceAll|replaceFirst|concat) - severity: WARNING - - id: java_strings_rule-NormalizeAfterValidation - languages: - - java - message: | - The application was found matching a variable during a regular expression - pattern match, and then calling a Unicode normalize function after validation has occurred. - This is usually indicative of a poor input validation strategy as an adversary may attempt to - exploit the normalization process. - - To remediate this issue, always perform Unicode normalization before any validation of a - string. - - Example of normalizing a string before validation: - ``` - // User input possibly containing malicious unicode - String userInput = "\uFE64" + "tag" + "\uFE65"; - // Normalize the input - userInput = Normalizer.normalize(userInput, Normalizer.Form.NFKC); - // Compile our regex pattern looking for < or > characters - Pattern pattern = Pattern.compile("[<>]"); - // Create a matcher from the userInput - Matcher matcher = pattern.matcher(userInput); - // See if the matcher matches - if (matcher.find()) { - // It did so throw an error - throw new Exception("found banned characters in input"); - } - ``` - - For more information see Carnegie Mellon University's Secure Coding Guide: - https://wiki.sei.cmu.edu/confluence/display/java/IDS01-J.+Normalize+strings+before+validating+them - metadata: - category: security - confidence: HIGH - cwe: CWE-180 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Info - shortDescription: 'Incorrect behavior order: validate before canonicalize' - patterns: - - pattern: | - $Y = java.util.regex.Pattern.compile("[<>]"); - ... - $Y.matcher($VAR); - ... - java.text.Normalizer.normalize($VAR, ...); - severity: WARNING - - id: java_templateinjection_rule-TemplateInjection - languages: - - java - message: | - The application may allow control over a template string. Providing user input directly in the - template by - dynamically creating template strings may allow an adversary to execute arbitrary Java code, - including - OS system commands. - - For Velocity, never call `evaluate` with user-supplied input in the template string. Use a - `VelocityContext` - object instead to data-bind user-supplied information as it will be treated as an underlying - data type and not - template code. - - Example using Apache Velocity's `VelocityContext` and escape tools to pass in user-supplied - data to a template: - ``` - // Create a tool manager - ToolManager manager = new ToolManager(true); - // Create a context from the tool manager - Context context = manager.createContext(); - // For demonstration purposes, alternatively configure from a properties file - context.put("esc", new EscapeTool()); - // For demonstration purposes, create an output buffer - StringWriter stringWriter = new StringWriter(); - // Get userInput - String userInput = "potentially malicious data"; - // Use the context to pass in the userInput value - context.put("userInput", userInput); - // Pass in the context, the output buffer, a logtag (demo), and the template with userInput - // making sure to escape it if in the context of HTML. - Velocity.evaluate(context, stringWriter, "demo", "Hello $esc.html($userInput)"); - // Work with the output buffer - // ... - ``` - - For other templating engines, please see your framework's documentation. - metadata: - category: security - cwe: CWE-94 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper control of generation of code ('Code Injection') - pattern-either: - - patterns: - - pattern: org.apache.velocity.app.Velocity.evaluate(..., $VAR) - - pattern-not: org.apache.velocity.app.Velocity.evaluate(..., "...") - - patterns: - - pattern-not-inside: | - $C = (freemarker.template.Configuration $CFG).getTemplate("..."); + $INTERM = open($DATA, ...) ... - - pattern-inside: | - $C = (freemarker.template.Configuration $CFG).getTemplate($IN); + django.http.FileResponse(..., $INTERM, ...) + - pattern: $A = django.http.FileResponse(..., request.$W.get(...), ...) + - pattern: return django.http.FileResponse(..., request.$W.get(...), ...) + - pattern: django.http.FileResponse(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) ... - - pattern: $C.process(...) - - patterns: - - pattern-inside: | - import com.mitchellbosecke.pebble.PebbleEngine; + django.http.FileResponse(..., open($DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = open($DATA, ...) + ... + django.http.FileResponse(..., $INTERM, ...) + - pattern: $A = django.http.FileResponse(..., request.$W(...), ...) + - pattern: return django.http.FileResponse(..., request.$W(...), ...) + - pattern: django.http.FileResponse(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + django.http.FileResponse(..., open($DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = open($DATA, ...) + ... + django.http.FileResponse(..., $INTERM, ...) + - pattern: $A = django.http.FileResponse(..., request.$W[...], ...) + - pattern: return django.http.FileResponse(..., request.$W[...], ...) + - pattern: django.http.FileResponse(..., request.$W, ...) + - pattern: | + $DATA = request.$W ... - - pattern-inside: | - $C = $T.getTemplate($IN); + django.http.FileResponse(..., open($DATA, ...), ...) + - pattern: | + $DATA = request.$W ... - - pattern-not-inside: | - $C = $T.getTemplate("..."); + $INTERM = open($DATA, ...) ... - - pattern: $C.evaluate(...) - severity: ERROR - - id: java_unsafe_rule-ExternalConfigControl + django.http.FileResponse(..., $INTERM, ...) + - pattern: $A = django.http.FileResponse(..., request.$W, ...) + - pattern: return django.http.FileResponse(..., request.$W, ...) + severity: WARNING + - id: python.django.security.injection.request-data-write.request-data-write languages: - - java - message: | - The application was found using user-supplied input in a `java.sql.Connection`'s - `setCatalog` call. This could allow an adversary to supply a different database for the - lifetime of the connection. Allowing external control of system settings can disrupt service - or cause an application to behave in unexpected, and potentially malicious ways. Most likely - this would only cause an error by providing a nonexistent catalog name. - - It is recommended to not use user-supplied input when selecting the database for an - applications - database connection. + - python + message: Found user-controlled request data passed into '.write(...)'. This could be dangerous if a malicious actor is able to control data into sensitive files. For example, a malicious actor could force rolling of critical log files, or cause a denial-of-service by using up available disk space. Instead, ensure that request data is properly escaped or sanitized. metadata: category: security - cwe: CWE-15 + confidence: MEDIUM + cwe: + - 'CWE-93: Improper Neutralization of CRLF Sequences (''CRLF Injection'')' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Low - shortDescription: External control of system or configuration setting + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln technology: - - java - patterns: + - django + pattern-either: + - pattern: $F.write(..., request.$W.get(...), ...) - pattern: | - $TAINTED = (HttpServletRequest $REQ).getParameter(...); + $DATA = request.$W.get(...) ... - (java.sql.Connection $CONN).setCatalog($TAINTED); - severity: WARNING - - id: java_xml_rule-SAMLIgnoreComments - languages: - - java - message: "SAML parses attestations as an XML document. By processing XML comments, comment\nfields can end up modifying the interpretation of input fields. This could allow\nan adversary to insert an XML comment to break up the attestation's username\nor other fields, allowing an attacker to bypass authorization or authentication checks.\n\nTo remediate this issue, when using `org.opensaml.xml.parse.BasicParserPool` ensure\n`setIgnoreComments(false)` is not called.\n\nThe default value of `ignoreComments` is true, which is safe. \n\nRef:\n- https://javadoc.io/doc/org.opensaml/xmltooling/latest/org/opensaml/xml/parse/BasicParserPool.html#ignoreComments\n\nFor more information on how this issue can be exploited see:\nhttps://developer.okta.com/blog/2018/02/27/a-breakdown-of-the-new-saml-authentication-bypass-vulnerability\n\nFor more information on SAML security see OWASP:\nhttps://cheatsheetseries.owasp.org/cheatsheets/SAML_Security_Cheat_Sheet.html\n" - metadata: - category: security - cwe: CWE-1390 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Weak authentication - pattern: (org.opensaml.xml.parse.BasicParserPool $POOL).setIgnoreComments(false); - severity: WARNING - - id: java_xml_rule-XmlDecoder - languages: - - java - message: | - Deserialization attacks exploit the process of reading serialized data and turning it back - into an object. By constructing malicious objects and serializing them, an adversary may - attempt to: - - - Inject code that is executed upon object construction, which occurs during the - deserialization process. - - Exploit mass assignment by including fields that are not normally a part of the serialized - data but are read in during deserialization. - - Consider safer alternatives such as serializing data in the JSON format. Ensure any format - chosen allows - the application to specify exactly which object types are allowed to be deserialized. - Additionally, when - deserializing, never deserialize to base object types like `Object` and only cast to the exact - object - type that is expected. - - To protect against mass assignment, only allow deserialization of the specific fields that are - required. If this is not easily done, consider creating an intermediary type that - can be serialized with only the necessary fields exposed. - - Do note that `XMLEncoder` and `XMLDecoder` are not recommended. If the application must - use this serialization method, use a custom ClassLoader to prevent loading of arbitrary - classes: - ``` - XMLDecoder decoder = new XMLDecoder(inputStream, null, null, new ClassLoader() { - @Override - protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (!name.equals(NameOfBeanHere.class.getName()) && - !name.equals(XMLDecoder.class.getName())) { - throw new RuntimeException("Unauthorized deserialization attempt: " + name); - } - - return super.loadClass(name, resolve); - } - }); - ``` - - For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java - - For more details on deserialization attacks in general, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html - - It should be noted that [tools exist](https://github.com/frohoff/ysoserial) to - automatically create - exploit code for these vulnerabilities. - metadata: - category: security - cwe: CWE-502 - owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: High - shortDescription: Deserialization of untrusted data - patterns: + $F.write(..., $DATA, ...) - pattern: | - (java.beans.XMLDecoder $D).readObject(); - - pattern-not: - pattern-either: - - patterns: - - pattern-inside: | - java.beans.XMLDecoder $DEC = new java.beans.XMLDecoder(..., $CL); - ... - - pattern: $DEC.readObject(); - - metavariable-pattern: - metavariable: $CL - patterns: - - pattern: | - new ClassLoader(){ - ... - $RET loadClass(String name, boolean resolve){ - if($X){ - throw ... - } - ... - } - ... - } - - metavariable-pattern: - metavariable: $X - pattern-either: - - pattern: | - !name.equals(...) - - pattern: | - !$LIST.contains(name) - - patterns: - - pattern-inside: | - ClassLoader $CLASS_LOADER = $CL; - ... - java.beans.XMLDecoder $DEC = new java.beans.XMLDecoder(..., $CLASS_LOADER); - ... - - pattern: $DEC.readObject(); - - metavariable-pattern: - metavariable: $CL - patterns: - - pattern: | - new ClassLoader(){ - ... - $RET loadClass(String name, boolean resolve){ - if($X){ - throw ... - } - ... - } - ... - } - - metavariable-pattern: - metavariable: $X - pattern-either: - - pattern: | - !name.equals(...) - - pattern: | - !$LIST.contains(name) - severity: WARNING - - id: java_xml_rule-XsltTransform - languages: - - java - message: | - The application performs XSLT translation with potentially malicious input. An adversary who - is able to influence the - loaded - XSL document could call XSL functions or exploit External XML Entity (XXE) attacks that allow - file - retrieval or force the parser to connect to arbitrary servers to exfiltrate files. It is - strongly - recommended that an alternative approach is used to work with XML data. - - For increased security, never process user-supplied XSL style sheets. If XSLT processing is - absolutely - necessary, ensure that `FEATURE_SECURE_PROCESSING` is enabled prior to processing the XSLT - file: - ``` - // Create a new TransformerFactory instance - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - // Enable the FEATURE_SECURE_PROCESSING feature - transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - // Read in the XML Source - Source xmlSource = new StreamSource(new FileInputStream("hardcoded.xml")); - // Read in the XSL template file - Source xslSource = new StreamSource(new FileInputStream("hardcoded.xsl")); - /// Create the transformer object to do the transformation - Transformer transformer = transformerFactory.newTransformer(xslSource); - // Create a Result object for output - Result result = new StreamResult(System.out); - // Execute the transformation process - transformer.transform(xmlSource, result); - ``` - - For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java - - For more information on the secure processing feature see: - - https://xml.apache.org/xalan-j/features.html#secureprocessing - metadata: - category: security - cwe: CWE-91 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: XML injection (aka Blind XPath injection) - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: (javax.xml.transform.TransformerFactory $T).newTransformer($SRC, ...) - - pattern-inside: (javax.xml.transform.Transformer $T).transform($SRC, ...) - - pattern: $SRC - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $FUNC(...,String $VAR, ...) { - ... - } - - pattern-either: - - pattern: new FileInputStream(<... $VAR ...>); - - pattern: getClass().getResourceAsStream(<... $VAR ...>) - - patterns: - - pattern-inside: | - class $CLZ { - String $X = "..."; - ... - } - - pattern-inside: | - $FUNC(...,String $Y, ...) { - ... - } - - pattern-either: - - pattern: new FileInputStream($X + $Y); - - pattern: getClass().getResourceAsStream($X + $Y) - severity: WARNING - - id: java_xss_rule-WicketXSS - languages: - - java - message: | - The application is disabling Wicket's string escaping functionality by calling - `setEscapeModelStrings(false)`. - This could lead to Cross Site Scripting (XSS) if used with user-supplied input. XSS is an - attack which exploits - a web application or system to treat user input - as markup or script code. It is important to encode the data depending on the specific context - it - is used in. There are at least six context types: - - - Inside HTML tags `
    context 1
    ` - - Inside attributes: `
    ` - - Inside event attributes `` - - Inside script blocks: `` - - Unsafe element HTML assignment: `element.innerHTML = "context 5"` - - Inside URLs: `link` - - Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if - user input - is ever output inside of script tags. - - User input that is displayed within the application must be encoded, sanitized or validated - to ensure it cannot be treated as HTML or executed as JavaScript code. Care must also be - taken - to not mix server-side templating with client-side templating, as the server-side templating - will - not encode things like {{ 7*7 }} which may execute client-side templating features. - - It is _NOT_ advised to encode user input prior to inserting into a data store. The data will - need to be - encoded depending on context of where it is output. It is much safer to force the displaying - system to - handle the encoding and not attempt to guess how it should be encoded. - - Use Wicket's built in escaping feature by calling `Component.setEscapeModelStrings(true);` - - For more information on Wicket components see: - - https://nightlies.apache.org/wicket/apidocs/9.x/org/apache/wicket/Component.html - - For more information on XSS see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-79 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - patterns: - - pattern-inside: | - import org.apache.wicket.$A; + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $F.write(..., $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $F.write(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $F.write(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + $F.write(..., $INTERM, ...) + - pattern: $A = $F.write(..., request.$W.get(...), ...) + - pattern: return $F.write(..., request.$W.get(...), ...) + - pattern: $F.write(..., request.$W(...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $F.write(..., $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $F.write(..., $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $F.write(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W(...) + ... + $F.write(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + $F.write(..., $INTERM, ...) + - pattern: $A = $F.write(..., request.$W(...), ...) + - pattern: return $F.write(..., request.$W(...), ...) + - pattern: $F.write(..., request.$W[...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $F.write(..., $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $F.write(..., $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $F.write(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W[...] + ... + $F.write(..., f"...{$DATA}...", ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + $F.write(..., $INTERM, ...) + - pattern: $A = $F.write(..., request.$W[...], ...) + - pattern: return $F.write(..., request.$W[...], ...) + - pattern: $F.write(..., request.$W, ...) + - pattern: | + $DATA = request.$W + ... + $F.write(..., $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $F.write(..., $B.$C(..., $DATA, ...), ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $B.$C(..., $DATA, ...) + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W + ... + $F.write(..., $STR % $DATA, ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + $F.write(..., $INTERM, ...) + - pattern: | + $DATA = request.$W ... + $F.write(..., f"...{$DATA}...", ...) - pattern: | - $OBJ.setEscapeModelStrings(false); + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + $F.write(..., $INTERM, ...) + - pattern: $A = $F.write(..., request.$W, ...) + - pattern: return $F.write(..., request.$W, ...) severity: WARNING - - id: java_xss_rule-XSSReqParamToServletWriter + - id: python.django.security.injection.sql.sql-injection-extra.sql-injection-using-extra-where languages: - - java - message: | - The application is returning user-supplied data from an HTTP request directly into an HTTP - response output - writer. This could lead to Cross Site Scripting (XSS) if the input were malicious - script code and the application server is not properly validating the output. - - XSS is an attack which exploits a web application or system to treat user input - as markup or script code. It is important to encode the data depending on the specific context - it is used in. There are at least six context types: - - - Inside HTML tags `
    context 1
    ` - - Inside attributes: `
    ` - - Inside event attributes `` - - Inside script blocks: `` - - Unsafe element HTML assignment: `element.innerHTML = "context 5"` - - Inside URLs: `link` - - Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if - user input - is ever output inside of script tags. - - User input that is displayed within the application must be encoded, sanitized or validated - to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be - taken - to not mix server-side templating with client-side templating, as the server-side templating - will - not encode things like {{ 7*7 }} which may execute client-side templating features. - - It is _NOT_ advised to encode user input prior to inserting into a data store. The data will - need to be - encoded depending on context of where it is output. It is much safer to force the displaying - system to - handle the encoding and not attempt to guess how it should be encoded. - - If possible do not use user input directly in the output to the response writer. - - If the application must output user-supplied input, it will need to encode the data depending - on - the output context. - - Consider using [Apache Commons Text](https://commons.apache.org/proper/commons-text/) - `StringEscapeUtils` methods for various context. Please note there is no way to safely - output script code in most circumstances, regardless of encoding. If calling the HTTP - response writer directly, ensure that the `Content-Type` is set to `text/plain` so it will - not be accidentally interpreted by HTML by modern browsers. - ``` - // Get user input - String htmlInput = request.getParameter("userInput"); - // Encode the input using the Html4 encoder - String htmlEncoded = StringEscapeUtils.escapeHtml4(htmlInput); - // Force the HTTP response to be content type of text/plain so it is not interpreted as HTML - response.setContentType("text/plain"); - // Ensure UTF-8 - response.setCharacterEncoding("UTF-8"); - // Write response - response.getWriter().write(htmlEncoded); - ``` - - For more information on XSS see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + - python + message: User-controlled data from a request is passed to 'extra()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use parameterized queries or escape the user-controlled data by using `params` and not using quote placeholders in the SQL string. metadata: category: security - cwe: CWE-79 + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.djangoproject.com/en/3.0/ref/models/expressions/#.objects.extra + subcategory: + - vuln technology: - - java - mode: taint - pattern-propagators: - - from: $X - pattern: $LIST.add($X) - to: $LIST - - from: $X - pattern: $MAP.put(..., $X) - to: $MAP - - from: $X - pattern: $STR.concat($X) - to: $STR - - from: $X - pattern: $STR = String.format(..., $X, ...) - to: $STR - - from: $X - pattern: $STR = String.join(..., $X, ...) - to: $STR - pattern-sanitizers: - - pattern: org.owasp.encoder.Encode.forHtml(...) - - pattern: org.owasp.esapi.ESAPI.encoder().encodeForHTML(...) - - pattern: org.apache.commons.text.StringEscapeUtils.escapeHtml3(...) - - pattern: org.apache.commons.text.StringEscapeUtils.escapeHtml4(...) - - pattern: org.owasp.benchmark.helpers.Utils.encodeForHTML(...) - pattern-sinks: - - pattern: (javax.servlet.http.HttpServletResponse $R).getWriter().print(...) - - patterns: - - pattern-inside: | - $W = (javax.servlet.http.HttpServletResponse $R).getWriter(); + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W.get(...), ...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W.get(...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W.get(...)}...", ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) + - pattern: return $MODEL.objects.extra(..., where=[..., request.$W.get(...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W(...), ...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W(...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W(...)}...", ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) + - pattern: return $MODEL.objects.extra(..., where=[..., request.$W(...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W[...], ...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W[...], ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W[...]}...", ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." ... - - pattern: $W.print(...); - - pattern: (javax.servlet.http.HttpServletResponse $R).getWriter().println(...) - - patterns: - - pattern-inside: | - $W = (javax.servlet.http.HttpServletResponse $R).getWriter(); + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W[...] ... - - pattern: $W.println(...); - - pattern: (javax.servlet.http.HttpServletResponse $R).getWriter().format(...) - - patterns: - - pattern-inside: | - $W = (javax.servlet.http.HttpServletResponse $R).getWriter(); + $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) + - pattern: | + $DATA = request.$W[...] ... - - pattern: $W.format(...); - - pattern: (javax.servlet.http.HttpServletResponse $R).getWriter().append(...) - - patterns: - - pattern-inside: | - $W = (javax.servlet.http.HttpServletResponse $R).getWriter(); + $INTERM = $STR + $DATA ... - - pattern: $W.append(...); - - pattern: (javax.servlet.http.HttpServletResponse $R).getWriter().write(...) - - patterns: - - pattern-inside: | - $W = (javax.servlet.http.HttpServletResponse $R).getWriter(); + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) + - pattern: return $MODEL.objects.extra(..., where=[..., request.$W[...], ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S.format(..., request.$W, ...), ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., $S % request.$W, ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., f"...{request.$W}...", ...], ...) + - pattern: $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) + - pattern: | + $DATA = request.$W ... - - pattern: $W.write(...); - pattern-sources: - - pattern: (javax.servlet.http.HttpServletRequest $R).$METHOD(...) - - pattern: (java.util.Scanner $S).$METHOD(...) - - pattern: (java.util.stream.Stream).$METHOD(...) - - pattern: (java.util.StringJoiner $SJ).toString(...) - - pattern: (java.sql.ResultSet.getString $R).$METHOD(...) - - pattern: (java.lang.System $S).getProperty(...) - - pattern: (java.lang.System $S).getenv(...) - - pattern: (java.lang.StringBuilder $SB).toString(...) - - pattern: (java.io.FileInputStream $F).read(...) - - pattern: (java.io.FileReader $F).read(...) - - pattern: (java.net.Socket $S).getInputStream(...) - - pattern: (java.net.Socket $S).getOutputStream(...) - - pattern: (java.net.DatagramSocket $S).receive(...) - - pattern: (java.net.DatagramSocket $S).getInputStream(...) - - pattern: java.nio.file.Files.readAllBytes(...) - - pattern: java.nio.file.Files.readAllLines(...) - - pattern: java.nio.file.Files.lines(...) - - pattern: java.nio.file.Files.newBufferedReader(...) - - pattern: org.apache.commons.io.IOUtils.toString(...) - - pattern: org.apache.commons.io.IOUtils.readLines(...) - - pattern: org.apache.commons.io.IOUtils.toByteArray(...) - - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).readValue(...) - - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).treeToValue(...) - - pattern: $CLASS.$METHOD(..., (javax.servlet.http.HttpServletRequest $R), ...) - - pattern: $FUNC(..., (javax.servlet.http.HttpServletRequest $R), ...) - - patterns: - - pattern-inside: $FUNC(..., String $X, ...) { ... } - - focus-metavariable: $X + $MODEL.objects.extra(..., where=[..., $DATA, ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., $STR.format(..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., $STR % $DATA, ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., f"...{$DATA}...", ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., $STR + $DATA, ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: $A = $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) + - pattern: return $MODEL.objects.extra(..., where=[..., request.$W, ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W + ... + $MODEL.objects.extra(..., where=[..., $STR % (..., $DATA, ...), ...], ...) + - pattern: | + $DATA = request.$W.get(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W[...] + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) + - pattern: | + $DATA = request.$W + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.extra(..., where=[..., $INTERM, ...], ...) severity: WARNING - - id: java_xxe_rule-XMLRdr + - id: python.django.security.injection.sql.sql-injection-rawsql.sql-injection-using-rawsql languages: - - java - message: | - External XML entities are a feature of XML parsers that allow documents to contain references - to - other documents or data. This feature can be abused to read files, communicate with external - hosts, - exfiltrate data, or cause a Denial of Service (DoS). - - The XMLReaderFactory has been deprecated. It is recommended that - [SAXParserFactory](https://docs.oracle.com/javase/9/docs/api/javax/xml/parsers/SAXParserFactory.html) - be used - instead. Additionally when using the SAXParser it must be configured to disallow doctypes, - which will - protect against the majority of XXE attacks. - - Example creating a SAXParser with disallowing the doctypes feature enabled: - ``` - // Create a SAXParserFactory - SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); - // Enable the feature which disallows context 1` - - Inside attributes: `
    ` - - Inside event attributes `` - - Inside script blocks: `` - - Unsafe element HTML assignment: `element.innerHTML = "context 5"` - - Inside URLs: `link` - - Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if - user input - is ever output inside of script tags. - - User input that is displayed within the application must be encoded, sanitized or validated - to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be - taken - to not mix server-side templating with client-side templating, as the server-side templating - will - not encode things like {{ 7*7 }} which may execute client-side templating features. - - It is _NOT_ advised to encode user input prior to inserting into a data store. The data will - need to be - encoded depending on context of where it is output. It is much safer to force the displaying - system to - handle the encoding and not attempt to guess how it should be encoded. - - Remove the call to `dangerouslySetInnerHTML` or ensure that the data used in this call does - not come from user-supplied input. - - For more information on dangerously setting inner HTML see: - - https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html - metadata: - category: security - cwe: CWE-79 - owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - pattern-either: - - pattern: | - <$X dangerouslySetInnerHTML=... /> - - pattern: | - {dangerouslySetInnerHTML: ...} - severity: WARNING - - id: javascript_require_rule-non-literal-require - languages: - - javascript - - typescript - message: | - The application was found to dynamically import a module by calling `require` using a - non-literal string. An adversary might be able to read the first line of - arbitrary files. If they had write access to the file system, they may also be able to - execute arbitrary code. - - To remediate this issue, use a hardcoded string literal when calling `require`. Never call it - it with dynamically created variables or user-supplied data. - metadata: - category: security - cwe: CWE-95 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Low - shortDescription: Improper neutralization of directives in dynamically evaluated code ('Eval Injection') - source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-non-literal-require.js - patterns: - - pattern: require($OBJ) - - pattern-not: require('...') - severity: WARNING - - id: javascript_timing_rule-possible-timing-attacks - languages: - - javascript - message: | - The application was found executing string comparisons using one of `===`, `!==`, `==` or `!=` - against security sensitive values. String comparisons like this are not constant time, meaning - the - first character found not to match in the two strings will immediately exit the conditional - statement. - This allows an adversary to calculate or observe small timing differences depending on the - strings - passed to this comparison. This potentially allows an adversary the ability to brute force a - string - that will match the expected value by monitoring different character values. - - To remediate this issue, use the `crypto.timingSafeEqual` method when comparing strings. - - Example using `crypto.timingSafeEqual` to safely compare strings: - ``` - function constantTimeIsPasswordEqual(userInput) { - // Retrieve the password from a secure data store such as a KMS or Hashicorp's vault. - const password = getPasswordFromSecureDataStore(); - // Use crypto timingSafeEqual to ensure the comparison is done in constant time. - return crypto.timingSafeEqual(Buffer.from(userInput, 'utf-8'), Buffer.from(password, - 'utf-8')); - } - ``` - - For more information on constant time comparison see: - - https://nodejs.org/api/crypto.html#crypto_crypto_timingsafeequal_a_b - metadata: - category: security - cwe: CWE-208 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Observable timing discrepancy - patterns: - - pattern-not: if ($Z == null) { ... }; - - pattern-not: if ($Z === null) { ... }; - - pattern-not: if ($Z != null) { ... }; - - pattern-not: if ($Z !== null) { ... }; - - pattern-not: if ($Q != undefined) { ... }; - - pattern-not: if ($Q !== undefined) { ... }; - - pattern-not: if ($Q == undefined) { ... }; - - pattern-not: if ($Q === undefined) { ... }; - - pattern-not: return $Y == null; - - pattern-not: return $Y === null; - - pattern-not: return $Y != null; - - pattern-not: return $Y !== null; - - pattern-not: return $Y == undefined; - - pattern-not: return $Y === undefined; - - pattern-not: return $Y != undefined; - - pattern-not: return $Y !== undefined; - - pattern-either: - - pattern: | - if (password == $X) { - ... - } + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X == password) { - ... - } + $DATA = request.$W.get(...) + ... + $CURSOR.execute(..., $STR + $DATA, ...) - pattern: | - if (password === $X) { - ... - } + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: $A = $CURSOR.execute(..., request.$W.get(...), ...) + - pattern: return $CURSOR.execute(..., request.$W.get(...), ...) + - pattern: $CURSOR.execute(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $CURSOR.execute(..., $S % request.$W(...), ...) + - pattern: $CURSOR.execute(..., f"...{request.$W(...)}...", ...) + - pattern: $CURSOR.execute(..., request.$W(...), ...) - pattern: | - if ($X === password) { - ... - } + $DATA = request.$W(...) + ... + $CURSOR.execute(..., $DATA, ...) - pattern: | - if (pass == $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X == pass) { - ... - } + $DATA = request.$W(...) + ... + $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) - pattern: | - if (pass === $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X === pass) { - ... - } + $DATA = request.$W(...) + ... + $CURSOR.execute(..., $STR % $DATA, ...) - pattern: | - if (secret == $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X == secret) { - ... - } + $DATA = request.$W(...) + ... + $CURSOR.execute(..., f"...{$DATA}...", ...) - pattern: | - if (secret === $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X === secret) { - ... - } + $DATA = request.$W(...) + ... + $CURSOR.execute(..., $STR + $DATA, ...) - pattern: | - if (api == $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: $A = $CURSOR.execute(..., request.$W(...), ...) + - pattern: return $CURSOR.execute(..., request.$W(...), ...) + - pattern: $CURSOR.execute(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $CURSOR.execute(..., $S % request.$W[...], ...) + - pattern: $CURSOR.execute(..., f"...{request.$W[...]}...", ...) + - pattern: $CURSOR.execute(..., request.$W[...], ...) - pattern: | - if ($X == api) { - ... - } + $DATA = request.$W[...] + ... + $CURSOR.execute(..., $DATA, ...) - pattern: | - if (api === $X) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X === api) { - ... - } + $DATA = request.$W[...] + ... + $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) - pattern: | - if (apiKey == $X) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X == apiKey) { - ... - } + $DATA = request.$W[...] + ... + $CURSOR.execute(..., $STR % $DATA, ...) - pattern: | - if (apiKey === $X) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X === apiKey) { - ... - } + $DATA = request.$W[...] + ... + $CURSOR.execute(..., f"...{$DATA}...", ...) - pattern: | - if (apiSecret == $X) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X == apiSecret) { - ... - } + $DATA = request.$W[...] + ... + $CURSOR.execute(..., $STR + $DATA, ...) - pattern: | - if (apiSecret === $X) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: $A = $CURSOR.execute(..., request.$W[...], ...) + - pattern: return $CURSOR.execute(..., request.$W[...], ...) + - pattern: $CURSOR.execute(..., $S.format(..., request.$W, ...), ...) + - pattern: $CURSOR.execute(..., $S % request.$W, ...) + - pattern: $CURSOR.execute(..., f"...{request.$W}...", ...) + - pattern: $CURSOR.execute(..., request.$W, ...) - pattern: | - if ($X === apiSecret) { - ... - } + $DATA = request.$W + ... + $CURSOR.execute(..., $DATA, ...) - pattern: | - if (token == $X) { - ... - } + $DATA = request.$W + ... + $INTERM = $DATA + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X == token) { - ... - } + $DATA = request.$W + ... + $CURSOR.execute(..., $STR.format(..., $DATA, ...), ...) - pattern: | - if (token === $X) { - ... - } + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X === token) { - ... - } + $DATA = request.$W + ... + $CURSOR.execute(..., $STR % $DATA, ...) - pattern: | - if (hash == $X) { - ... - } + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X == hash) { - ... - } + $DATA = request.$W + ... + $CURSOR.execute(..., f"...{$DATA}...", ...) - pattern: | - if (hash === $X) { - ... - } + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + $CURSOR.execute(..., $INTERM, ...) - pattern: | - if ($X === hash) { - ... - } + $DATA = request.$W + ... + $CURSOR.execute(..., $STR + $DATA, ...) - pattern: | - if (auth_token == $X) { - ... - } + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + $CURSOR.execute(..., $INTERM, ...) + - pattern: $A = $CURSOR.execute(..., request.$W, ...) + - pattern: return $CURSOR.execute(..., request.$W, ...) - pattern: | - if ($X == auth_token) { - ... - } + $DATA = request.$W.get(...) + ... + $CURSOR.execute($STR % (..., $DATA, ...), ...) - pattern: | - if (auth_token === $X) { - ... - } + $DATA = request.$W[...] + ... + $CURSOR.execute($STR % (..., $DATA, ...), ...) - pattern: | - if ($X === auth_token) { - ... - } + $DATA = request.$W(...) + ... + $CURSOR.execute($STR % (..., $DATA, ...), ...) - pattern: | - if (password != $X) { - ... - } + $DATA = request.$W + ... + $CURSOR.execute($STR % (..., $DATA, ...), ...) - pattern: | - if ($X != password) { - ... - } + $DATA = request.$W.get(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $CURSOR.execute($INTERM, ...) - pattern: | - if (password !== $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $CURSOR.execute($INTERM, ...) - pattern: | - if ($X !== password) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $CURSOR.execute($INTERM, ...) - pattern: | - if (pass != $X) { - ... - } + $DATA = request.$W + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $CURSOR.execute($INTERM, ...) + severity: WARNING + - id: python.django.security.injection.sql.sql-injection-using-raw.sql-injection-using-raw + languages: + - python + message: Data that is possible user-controlled from a python request is passed to `raw()`. This could lead to SQL injection and attackers gaining access to protected information. Instead, use django's QuerySets, which are built with query parameterization and therefore not vulnerable to sql injection. For example, you could use `Entry.objects.filter(date=2006)`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.djangoproject.com/en/3.0/topics/security/#sql-injection-protection + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: $MODEL.objects.raw(..., $S % request.$W.get(...), ...) + - pattern: $MODEL.objects.raw(..., f"...{request.$W.get(...)}...", ...) + - pattern: $MODEL.objects.raw(..., request.$W.get(...), ...) - pattern: | - if ($X != pass) { - ... - } + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw(..., $DATA, ...) - pattern: | - if (pass !== $X) { - ... - } + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X !== pass) { - ... - } + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) - pattern: | - if (secret != $X) { - ... - } + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X != secret) { - ... - } + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw(..., $STR % $DATA, ...) - pattern: | - if (secret !== $X) { - ... - } + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X !== secret) { - ... - } + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw(..., f"...{$DATA}...", ...) - pattern: | - if (api != $X) { - ... - } + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X != api) { - ... - } + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw(..., $STR + $DATA, ...) - pattern: | - if (api !== $X) { - ... - } + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: $A = $MODEL.objects.raw(..., request.$W.get(...), ...) + - pattern: return $MODEL.objects.raw(..., request.$W.get(...), ...) + - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W(...), ...), ...) + - pattern: $MODEL.objects.raw(..., $S % request.$W(...), ...) + - pattern: $MODEL.objects.raw(..., f"...{request.$W(...)}...", ...) + - pattern: $MODEL.objects.raw(..., request.$W(...), ...) - pattern: | - if ($X !== api) { - ... - } + $DATA = request.$W(...) + ... + $MODEL.objects.raw(..., $DATA, ...) - pattern: | - if (apiKey != $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X != apiKey) { - ... - } + $DATA = request.$W(...) + ... + $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) - pattern: | - if (apiKey !== $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X !== apiKey) { - ... - } + $DATA = request.$W(...) + ... + $MODEL.objects.raw(..., $STR % $DATA, ...) - pattern: | - if (apiSecret != $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X != apiSecret) { - ... - } + $DATA = request.$W(...) + ... + $MODEL.objects.raw(..., f"...{$DATA}...", ...) - pattern: | - if (apiSecret !== $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X !== apiSecret) { - ... - } + $DATA = request.$W(...) + ... + $MODEL.objects.raw(..., $STR + $DATA, ...) - pattern: | - if (token != $X) { - ... - } + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: $A = $MODEL.objects.raw(..., request.$W(...), ...) + - pattern: return $MODEL.objects.raw(..., request.$W(...), ...) + - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W[...], ...), ...) + - pattern: $MODEL.objects.raw(..., $S % request.$W[...], ...) + - pattern: $MODEL.objects.raw(..., f"...{request.$W[...]}...", ...) + - pattern: $MODEL.objects.raw(..., request.$W[...], ...) - pattern: | - if ($X != token) { - ... - } + $DATA = request.$W[...] + ... + $MODEL.objects.raw(..., $DATA, ...) - pattern: | - if (token !== $X) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X !== token) { - ... - } + $DATA = request.$W[...] + ... + $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) - pattern: | - if (hash != $X) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X != hash) { - ... - } + $DATA = request.$W[...] + ... + $MODEL.objects.raw(..., $STR % $DATA, ...) - pattern: | - if (hash !== $X) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X !== hash) { - ... - } + $DATA = request.$W[...] + ... + $MODEL.objects.raw(..., f"...{$DATA}...", ...) - pattern: | - if (auth_token != $X) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - if ($X != auth_token) { - ... - } + $DATA = request.$W[...] + ... + $MODEL.objects.raw(..., $STR + $DATA, ...) - pattern: | - if (auth_token !== $X) { - ... - } + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: $A = $MODEL.objects.raw(..., request.$W[...], ...) + - pattern: return $MODEL.objects.raw(..., request.$W[...], ...) + - pattern: $MODEL.objects.raw(..., $S.format(..., request.$W, ...), ...) + - pattern: $MODEL.objects.raw(..., $S % request.$W, ...) + - pattern: $MODEL.objects.raw(..., f"...{request.$W}...", ...) + - pattern: $MODEL.objects.raw(..., request.$W, ...) - pattern: | - if ($X !== auth_token) { - ... - } + $DATA = request.$W + ... + $MODEL.objects.raw(..., $DATA, ...) - pattern: | - return $X === auth_token; + $DATA = request.$W + ... + $INTERM = $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - return auth_token === $X; + $DATA = request.$W + ... + $MODEL.objects.raw(..., $STR.format(..., $DATA, ...), ...) - pattern: | - return $X === token; + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - return token === $X; + $DATA = request.$W + ... + $MODEL.objects.raw(..., $STR % $DATA, ...) - pattern: | - return $X === hash; + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - return hash === $X; + $DATA = request.$W + ... + $MODEL.objects.raw(..., f"...{$DATA}...", ...) - pattern: | - return $X === password; + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + $MODEL.objects.raw(..., $INTERM, ...) - pattern: | - return password === $X; + $DATA = request.$W + ... + $MODEL.objects.raw(..., $STR + $DATA, ...) - pattern: | - return $X === pass; + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + $MODEL.objects.raw(..., $INTERM, ...) + - pattern: $A = $MODEL.objects.raw(..., request.$W, ...) + - pattern: return $MODEL.objects.raw(..., request.$W, ...) - pattern: | - return pass === $X; + $DATA = request.$W.get(...) + ... + $MODEL.objects.raw($STR % (..., $DATA, ...), ...) - pattern: | - return $X === apiKey; + $DATA = request.$W[...] + ... + $MODEL.objects.raw($STR % (..., $DATA, ...), ...) - pattern: | - return apiKey === $X; + $DATA = request.$W(...) + ... + $MODEL.objects.raw($STR % (..., $DATA, ...), ...) - pattern: | - return $X === apiSecret; + $DATA = request.$W + ... + $MODEL.objects.raw($STR % (..., $DATA, ...), ...) - pattern: | - return apiSecret === $X; + $DATA = request.$W.get(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.raw($INTERM, ...) - pattern: | - return $X === api_key; + $DATA = request.$W(...) + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.raw($INTERM, ...) - pattern: | - return api_key === $X; + $DATA = request.$W[...] + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.raw($INTERM, ...) - pattern: | - return $X === api_secret; + $DATA = request.$W + ... + $INTERM = $STR % (..., $DATA, ...) + ... + $MODEL.objects.raw($INTERM, ...) + severity: WARNING + - id: python.django.security.injection.ssrf.ssrf-injection-requests.ssrf-injection-requests + languages: + - python + message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF). To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. See https://owasp.org/www-community/attacks/Server_Side_Request_Forgery to learn more about SSRF vulnerabilities. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: requests.$METHOD(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: requests.$METHOD(..., $S % request.$W.get(...), ...) + - pattern: requests.$METHOD(..., f"...{request.$W.get(...)}...", ...) + - pattern: requests.$METHOD(..., request.$W.get(...), ...) - pattern: | - return api_secret === $X; + $DATA = request.$W.get(...) + ... + requests.$METHOD(..., $DATA, ...) - pattern: | - return $X === secret; + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return secret === $X; + $DATA = request.$W.get(...) + ... + requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) - pattern: | - return $X === api; + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return api === $X; + $DATA = request.$W.get(...) + ... + requests.$METHOD(..., $STR % $DATA, ...) - pattern: | - return $X == auth_token; + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return auth_token == $X; + $DATA = request.$W.get(...) + ... + requests.$METHOD(..., f"...{$DATA}...", ...) - pattern: | - return $X == token; + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return token == $X; + $DATA = request.$W.get(...) + ... + requests.$METHOD(..., $STR + $DATA, ...) - pattern: | - return $X == hash; + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: $A = requests.$METHOD(..., request.$W.get(...), ...) + - pattern: return requests.$METHOD(..., request.$W.get(...), ...) + - pattern: requests.$METHOD(..., $S.format(..., request.$W(...), ...), ...) + - pattern: requests.$METHOD(..., $S % request.$W(...), ...) + - pattern: requests.$METHOD(..., f"...{request.$W(...)}...", ...) + - pattern: requests.$METHOD(..., request.$W(...), ...) - pattern: | - return hash == $X; + $DATA = request.$W(...) + ... + requests.$METHOD(..., $DATA, ...) - pattern: | - return $X == password; + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return password == $X; + $DATA = request.$W(...) + ... + requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) - pattern: | - return $X == pass; + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return pass == $X; + $DATA = request.$W(...) + ... + requests.$METHOD(..., $STR % $DATA, ...) - pattern: | - return $X == apiKey; + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return apiKey == $X; + $DATA = request.$W(...) + ... + requests.$METHOD(..., f"...{$DATA}...", ...) - pattern: | - return $X == apiSecret; + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return apiSecret == $X; + $DATA = request.$W(...) + ... + requests.$METHOD(..., $STR + $DATA, ...) - pattern: | - return $X == api_key; + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: $A = requests.$METHOD(..., request.$W(...), ...) + - pattern: return requests.$METHOD(..., request.$W(...), ...) + - pattern: requests.$METHOD(..., $S.format(..., request.$W[...], ...), ...) + - pattern: requests.$METHOD(..., $S % request.$W[...], ...) + - pattern: requests.$METHOD(..., f"...{request.$W[...]}...", ...) + - pattern: requests.$METHOD(..., request.$W[...], ...) - pattern: | - return api_key == $X; + $DATA = request.$W[...] + ... + requests.$METHOD(..., $DATA, ...) - pattern: | - return $X == api_secret; + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return api_secret == $X; + $DATA = request.$W[...] + ... + requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) - pattern: | - return $X == secret; + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return secret == $X; + $DATA = request.$W[...] + ... + requests.$METHOD(..., $STR % $DATA, ...) - pattern: | - return $X == api; + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return api == $X; + $DATA = request.$W[...] + ... + requests.$METHOD(..., f"...{$DATA}...", ...) - pattern: | - return $X !== auth_token; + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return auth_token !== $X; + $DATA = request.$W[...] + ... + requests.$METHOD(..., $STR + $DATA, ...) - pattern: | - return $X !== token; + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: $A = requests.$METHOD(..., request.$W[...], ...) + - pattern: return requests.$METHOD(..., request.$W[...], ...) + - pattern: requests.$METHOD(..., $S.format(..., request.$W, ...), ...) + - pattern: requests.$METHOD(..., $S % request.$W, ...) + - pattern: requests.$METHOD(..., f"...{request.$W}...", ...) + - pattern: requests.$METHOD(..., request.$W, ...) - pattern: | - return token !== $X; + $DATA = request.$W + ... + requests.$METHOD(..., $DATA, ...) - pattern: | - return $X !== hash; + $DATA = request.$W + ... + $INTERM = $DATA + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return hash !== $X; + $DATA = request.$W + ... + requests.$METHOD(..., $STR.format(..., $DATA, ...), ...) - pattern: | - return $X !== password; + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return password !== $X; + $DATA = request.$W + ... + requests.$METHOD(..., $STR % $DATA, ...) - pattern: | - return $X !== pass; + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return pass !== $X; + $DATA = request.$W + ... + requests.$METHOD(..., f"...{$DATA}...", ...) - pattern: | - return $X !== apiKey; + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + requests.$METHOD(..., $INTERM, ...) - pattern: | - return apiKey !== $X; + $DATA = request.$W + ... + requests.$METHOD(..., $STR + $DATA, ...) - pattern: | - return $X !== apiSecret; + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + requests.$METHOD(..., $INTERM, ...) + - pattern: $A = requests.$METHOD(..., request.$W, ...) + - pattern: return requests.$METHOD(..., request.$W, ...) + severity: ERROR + - id: python.django.security.injection.ssrf.ssrf-injection-urllib.ssrf-injection-urllib + languages: + - python + message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF), which could result in attackers gaining access to private organization data. To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery + subcategory: + - vuln + technology: + - django + patterns: + - pattern-inside: | + def $FUNC(...): + ... + - pattern-either: + - pattern: urllib.request.urlopen(..., $S.format(..., request.$W.get(...), ...), ...) + - pattern: urllib.request.urlopen(..., $S % request.$W.get(...), ...) + - pattern: urllib.request.urlopen(..., f"...{request.$W.get(...)}...", ...) + - pattern: urllib.request.urlopen(..., request.$W.get(...), ...) - pattern: | - return apiSecret !== $X; + $DATA = request.$W.get(...) + ... + urllib.request.urlopen(..., $DATA, ...) - pattern: | - return $X !== api_key; + $DATA = request.$W.get(...) + ... + $INTERM = $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return api_key !== $X; + $DATA = request.$W.get(...) + ... + urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) - pattern: | - return $X !== api_secret; + $DATA = request.$W.get(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return api_secret !== $X; + $DATA = request.$W.get(...) + ... + urllib.request.urlopen(..., $STR % $DATA, ...) - pattern: | - return $X !== secret; + $DATA = request.$W.get(...) + ... + $INTERM = $STR % $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return secret !== $X; + $DATA = request.$W.get(...) + ... + urllib.request.urlopen(..., f"...{$DATA}...", ...) - pattern: | - return $X !== api; + $DATA = request.$W.get(...) + ... + $INTERM = f"...{$DATA}..." + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return api !== $X; + $DATA = request.$W.get(...) + ... + urllib.request.urlopen(..., $STR + $DATA, ...) - pattern: | - return $X != auth_token; + $DATA = request.$W.get(...) + ... + $INTERM = $STR + $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: $A = urllib.request.urlopen(..., request.$W.get(...), ...) + - pattern: return urllib.request.urlopen(..., request.$W.get(...), ...) + - pattern: urllib.request.urlopen(..., $S.format(..., request.$W(...), ...), ...) + - pattern: urllib.request.urlopen(..., $S % request.$W(...), ...) + - pattern: urllib.request.urlopen(..., f"...{request.$W(...)}...", ...) + - pattern: urllib.request.urlopen(..., request.$W(...), ...) - pattern: | - return auth_token != $X; + $DATA = request.$W(...) + ... + urllib.request.urlopen(..., $DATA, ...) - pattern: | - return $X != token; + $DATA = request.$W(...) + ... + $INTERM = $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return token != $X; + $DATA = request.$W(...) + ... + urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) - pattern: | - return $X != hash; + $DATA = request.$W(...) + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return hash != $X; + $DATA = request.$W(...) + ... + urllib.request.urlopen(..., $STR % $DATA, ...) - pattern: | - return $X != password; + $DATA = request.$W(...) + ... + $INTERM = $STR % $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return password != $X; + $DATA = request.$W(...) + ... + urllib.request.urlopen(..., f"...{$DATA}...", ...) - pattern: | - return $X != pass; + $DATA = request.$W(...) + ... + $INTERM = f"...{$DATA}..." + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return pass != $X; + $DATA = request.$W(...) + ... + urllib.request.urlopen(..., $STR + $DATA, ...) - pattern: | - return $X != apiKey; + $DATA = request.$W(...) + ... + $INTERM = $STR + $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: $A = urllib.request.urlopen(..., request.$W(...), ...) + - pattern: return urllib.request.urlopen(..., request.$W(...), ...) + - pattern: urllib.request.urlopen(..., $S.format(..., request.$W[...], ...), ...) + - pattern: urllib.request.urlopen(..., $S % request.$W[...], ...) + - pattern: urllib.request.urlopen(..., f"...{request.$W[...]}...", ...) + - pattern: urllib.request.urlopen(..., request.$W[...], ...) - pattern: | - return apiKey != $X; + $DATA = request.$W[...] + ... + urllib.request.urlopen(..., $DATA, ...) - pattern: | - return $X != apiSecret; + $DATA = request.$W[...] + ... + $INTERM = $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return apiSecret != $X; + $DATA = request.$W[...] + ... + urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) - pattern: | - return $X != api_key; + $DATA = request.$W[...] + ... + $INTERM = $STR.format(..., $DATA, ...) + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return api_key != $X; + $DATA = request.$W[...] + ... + urllib.request.urlopen(..., $STR % $DATA, ...) - pattern: | - return $X != api_secret; + $DATA = request.$W[...] + ... + $INTERM = $STR % $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return api_secret != $X; + $DATA = request.$W[...] + ... + urllib.request.urlopen(..., f"...{$DATA}...", ...) - pattern: | - return $X != secret; + $DATA = request.$W[...] + ... + $INTERM = f"...{$DATA}..." + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - return secret != $X; + $DATA = request.$W[...] + ... + urllib.request.urlopen(..., $STR + $DATA, ...) - pattern: | - return $X != api; + $DATA = request.$W[...] + ... + $INTERM = $STR + $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: $A = urllib.request.urlopen(..., request.$W[...], ...) + - pattern: return urllib.request.urlopen(..., request.$W[...], ...) + - pattern: urllib.request.urlopen(..., $S.format(..., request.$W, ...), ...) + - pattern: urllib.request.urlopen(..., $S % request.$W, ...) + - pattern: urllib.request.urlopen(..., f"...{request.$W}...", ...) + - pattern: urllib.request.urlopen(..., request.$W, ...) - pattern: | - return api != $X; - severity: WARNING - - id: javascript_xss_rule-mustache-escape - languages: - - javascript - - typescript - message: | - Markup escaping disabled. This can be used with some template engines to escape - disabling of HTML entities, which can lead to XSS attacks. - metadata: - category: security - cwe: CWE-79 - owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of input during web page generation (XSS) - patterns: - - pattern-inside: | - $OBJ = require('mustache') - ... - - pattern-either: + $DATA = request.$W + ... + urllib.request.urlopen(..., $DATA, ...) - pattern: | - $OBJ.escape = function($TEXT) { - ... - return $TEXT; - } - - patterns: - - metavariable-regex: - metavariable: $X - regex: '"\{\{\{(.+?)\}\}\}"' - - pattern: $OBJ.render($X, ... ) - - patterns: - - metavariable-regex: - metavariable: $Y - regex: '"\{\{\&(.+?)\}\}"' - - pattern: $OBJ.render($Y, ... ) - severity: WARNING - - id: python_assert_rule-assert-used - languages: - - python - message: | - The application was found using `assert` in non-test code. Usually reserved for debug and test - code, the `assert` - function is commonly used to test conditions before continuing execution. However, enclosed - code will be removed - when compiling Python code to optimized byte code. Depending on the assertion and subsequent - logic, this could - lead to undefined behavior of the application or application crashes. - - To remediate this issue, remove the `assert` calls. If necessary, replace them with either `if` - conditions or - `try/except` blocks. - - Example using `try/except` instead of `assert`: - ``` - # Below try/except is equal to the assert statement of: - # assert user.is_authenticated(), "user must be authenticated" - try: - if not user.is_authenticated(): - raise AuthError("user must be authenticated") - except AuthError as e: - # Handle error - # ... - # Return, do not continue processing - return - ``` - metadata: - category: security - cwe: CWE-754 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Info - shortDescription: Improper check for unusual or exceptional conditions - patterns: - - pattern: assert(...) - - pattern-not-inside: | - import pytest - ... - - pattern-not-inside: | - import unittest - ... - severity: INFO - - id: python_bind-all-interfaces_rule-general-bindall-interfaces - languages: - - python - message: | - Binding to all network interfaces can potentially open up a service to - traffic on unintended interfaces, that may not be properly documented or - secured. By passing "0.0.0.0", "::" or an empty string as the address to the `socket.bind` - function, - the application will bind to all interfaces. - - Consider passing in the interface ip address through an environment variable, - configuration file, or by determining the primary interface(s) IP address. - - Example getting the IP address from an environment variable `IP_ADDRESS`: - ``` - # Get the IP_ADDRESS env variable, or bind to - # 127.0.0.1 if it is not set - address = os.getenv("IP_ADDRESS", "127.0.0.1") - # Create an internet socket - sock = socket.socket(socket.AF_INET) - # Set the port to listen on - port = 9777 - # Bind to the address and port combination - sock.bind((address, port)) - # Listen for connections - sock.listen() - # Handle the connection - ``` - metadata: - category: security - cwe: CWE-1327 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Low - shortDescription: Binding to an unrestricted IP address - patterns: - - pattern-either: + $DATA = request.$W + ... + $INTERM = $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - $S = socket.socket(...) + $DATA = request.$W ... - $S.bind(("0.0.0.0", ...)) + urllib.request.urlopen(..., $STR.format(..., $DATA, ...), ...) - pattern: | - $S = socket.socket(...) + $DATA = request.$W + ... + $INTERM = $STR.format(..., $DATA, ...) ... - $S.bind(("::", ...)) + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - $S = socket.socket(...) + $DATA = request.$W ... - $S.bind(("", ...)) - severity: INFO - - id: python_crypto_rule-cipher-modes - languages: - - python - message: | - Cryptographic algorithms provide many different modes of operation, only some of which provide - message integrity. Without message integrity it could be possible for an adversary to attempt - to tamper with the ciphertext which could lead to compromising the encryption key. Newer - algorithms - apply message integrity to validate ciphertext has not been tampered with. - - Instead of using an algorithm that requires configuring a cipher mode, an algorithm - that has built-in message integrity should be used. Consider using `ChaCha20Poly1305` or - `AES-256-GCM` instead. - - For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is - recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Example using `ChaCha20Poly1305`: - ``` - import os - # Import ChaCha20Poly1305 from cryptography - from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = ChaCha20Poly1305.generate_key() - # Create a new ChaCha20Poly1305 instance with our secure key - chacha = ChaCha20Poly1305(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = chacha.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - chacha.decrypt(nonce, cipher_text, aad) - ``` - - Example using `AESGCM`: - ``` - import os - # Import AESGCM from cryptography - from cryptography.hazmat.primitives.ciphers.aead import AESGCM - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = AESGCM.generate_key(bit_length=128) - # Create a new AESGCM instance with our secure key - aesgcm = AESGCM(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = aesgcm.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - aesgcm.decrypt(nonce, cipher_text, aad) - ``` - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - pattern: cryptography.hazmat.primitives.ciphers.modes.ECB(...) - severity: WARNING - - id: python_crypto_rule-crypto-cipher-blowfish - languages: - - python - message: | - The Blowfish encryption algorithm was meant as a drop-in replacement for DES and was created in - 1993. Smaller key sizes may make the ciphertext vulnerable to [birthday - attacks](https://en.wikipedia.org/wiki/Birthday_attack). While no known attacks against - Blowfish - exist, it should never be used to encrypt files over 4GB in size. If possible consider - using ChaCha20Poly1305 or AES-GCM instead of Blowfish. - - For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is - recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example using `ChaCha20Poly1305`: - ``` - import os - # Import ChaCha20Poly1305 from cryptography - from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = ChaCha20Poly1305.generate_key() - # Create a new ChaCha20Poly1305 instance with our secure key - chacha = ChaCha20Poly1305(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = chacha.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - chacha.decrypt(nonce, cipher_text, aad) - ``` - - Example using `AESGCM`: - ``` - import os - # Import AESGCM from cryptography - from cryptography.hazmat.primitives.ciphers.aead import AESGCM - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = AESGCM.generate_key(bit_length=128) - # Create a new AESGCM instance with our secure key - aesgcm = AESGCM(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = aesgcm.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - aesgcm.decrypt(nonce, cipher_text, aad) - ``` - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: Cryptodome.Cipher.Blowfish.new(...) - - pattern: Crypto.Cipher.Blowfish.new(...) - severity: WARNING - - id: python_crypto_rule-crypto-cipher-des - languages: - - python - message: | - DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. - Newer algorithms apply message integrity to validate ciphertext has not been tampered - with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the - alternatives such as `AES-256-GCM`. - - For older applications that don't have support for `ChaCha20Poly1305`, - `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example using `ChaCha20Poly1305`: - ``` - import os - # Import ChaCha20Poly1305 from cryptography - from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = ChaCha20Poly1305.generate_key() - # Create a new ChaCha20Poly1305 instance with our secure key - chacha = ChaCha20Poly1305(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = chacha.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - chacha.decrypt(nonce, cipher_text, aad) - ``` - - Example using `AESGCM`: - ``` - import os - # Import AESGCM from cryptography - from cryptography.hazmat.primitives.ciphers.aead import AESGCM - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = AESGCM.generate_key(bit_length=128) - # Create a new AESGCM instance with our secure key - aesgcm = AESGCM(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = aesgcm.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - aesgcm.decrypt(nonce, cipher_text, aad) - ``` - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: Cryptodome.Cipher.DES.new(...) - - pattern: Crypto.Cipher.DES.new(...) - severity: WARNING - - id: python_crypto_rule-crypto-cipher-rc2 - languages: - - python - message: | - DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. - Newer algorithms apply message integrity to validate ciphertext has not been tampered - with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the - alternatives such as `AES-256-GCM`. - - For older applications that don't have support for `ChaCha20Poly1305`, - `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example using `ChaCha20Poly1305`: - ``` - import os - # Import ChaCha20Poly1305 from cryptography - from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = ChaCha20Poly1305.generate_key() - # Create a new ChaCha20Poly1305 instance with our secure key - chacha = ChaCha20Poly1305(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = chacha.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - chacha.decrypt(nonce, cipher_text, aad) - ``` - - Example using `AESGCM`: - ``` - import os - # Import AESGCM from cryptography - from cryptography.hazmat.primitives.ciphers.aead import AESGCM - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = AESGCM.generate_key(bit_length=128) - # Create a new AESGCM instance with our secure key - aesgcm = AESGCM(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = aesgcm.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - aesgcm.decrypt(nonce, cipher_text, aad) - ``` - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: Cryptodome.Cipher.ARC2.new(...) - - pattern: Crypto.Cipher.ARC2.new - severity: WARNING - - id: python_crypto_rule-crypto-cipher-rc4 - languages: - - python - message: | - DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. - Newer algorithms apply message integrity to validate ciphertext has not been tampered - with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the - alternatives such as `AES-256-GCM`. - - For older applications that don't have support for `ChaCha20Poly1305`, - `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example using `ChaCha20Poly1305`: - ``` - import os - # Import ChaCha20Poly1305 from cryptography - from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = ChaCha20Poly1305.generate_key() - # Create a new ChaCha20Poly1305 instance with our secure key - chacha = ChaCha20Poly1305(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = chacha.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - chacha.decrypt(nonce, cipher_text, aad) - ``` - - Example using `AESGCM`: - ``` - import os - # Import AESGCM from cryptography - from cryptography.hazmat.primitives.ciphers.aead import AESGCM - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = AESGCM.generate_key(bit_length=128) - # Create a new AESGCM instance with our secure key - aesgcm = AESGCM(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = aesgcm.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - aesgcm.decrypt(nonce, cipher_text, aad) - ``` - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: Cryptodome.Cipher.ARC4.new(...) - - pattern: Crypto.Cipher.ARC4.new(...) - severity: WARNING - - id: python_crypto_rule-crypto-cipher-xor - languages: - - python - message: | - The application was found using the `xor` algorithm, which can be trivially decoded. - Newer algorithms apply message integrity to validate ciphertext has not been tampered - with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the - alternatives such as `AES-256-GCM`. - - For older applications that don't have support for `ChaCha20Poly1305`, - `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example using `ChaCha20Poly1305`: - ``` - import os - # Import ChaCha20Poly1305 from cryptography - from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = ChaCha20Poly1305.generate_key() - # Create a new ChaCha20Poly1305 instance with our secure key - chacha = ChaCha20Poly1305(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = chacha.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - chacha.decrypt(nonce, cipher_text, aad) - ``` - - Example using `AESGCM`: - ``` - import os - # Import AESGCM from cryptography - from cryptography.hazmat.primitives.ciphers.aead import AESGCM - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = AESGCM.generate_key(bit_length=128) - # Create a new AESGCM instance with our secure key - aesgcm = AESGCM(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = aesgcm.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - aesgcm.decrypt(nonce, cipher_text, aad) - ``` - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: Cryptodome.Cipher.XOR.new(...) - - pattern: Crypto.Cipher.XOR.new(...) - severity: WARNING - - id: python_crypto_rule-crypto-encrypt-dsa-rsa - languages: - - python - message: | - The application is generating an RSA key that is less than the recommended 2048 bits. - The National Institute of Standards and Technology (NIST) deprecated signing Digital - Certificates that contained RSA Public Keys of 1024 bits in December 2010. While - 1024-bit RSA keys have not been factored yet, advances in compute may make it possible - in the near future. - - Consider upgrading to the newer asymmetric algorithm such as `X25519` which handles - the complexities of generating key pairs and choosing correct key sizes for you: - ``` - from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey - - # Generate a private key for use in the exchange. - private_key = X25519PrivateKey.generate() - # Work with private key/exchange with a peer's - # public key to created a shared and derived key - # ... - ``` - - Otherwise use a key size greater than 2048 when generating RSA keys: - ``` - from cryptography.hazmat.primitives.asymmetric import rsa - # Generate a private key of 4096 bits - private_key = rsa.generate_private_key( - # do not change the exponent value from 65537 - public_exponent=65537, - key_size=4096, - ) - # Work with the private key to sign/encrypt data - # ... - ``` - - For more information on using the cryptography module see: - - https://cryptography.io/en/latest - metadata: - category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Inadequate encryption strength - patterns: - - pattern-either: + urllib.request.urlopen(..., $STR % $DATA, ...) - pattern: | - cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key(...,key_size=$SIZE,...) + $DATA = request.$W + ... + $INTERM = $STR % $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key($EXP, $SIZE,...) + $DATA = request.$W + ... + urllib.request.urlopen(..., f"...{$DATA}...", ...) - pattern: | - cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key($SIZE, ...) + $DATA = request.$W + ... + $INTERM = f"...{$DATA}..." + ... + urllib.request.urlopen(..., $INTERM, ...) - pattern: | - cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key(...,key_size=$SIZE,...) + $DATA = request.$W + ... + urllib.request.urlopen(..., $STR + $DATA, ...) - pattern: | - cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key($EXP, $SIZE, ...) - - pattern: cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key($SIZE,...) - - pattern: Crypto.PublicKey.RSA.generate($SIZE, ...) - - pattern: Crypto.PublicKey.DSA.generate($SIZE, ...) - - pattern: Cryptodome.PublicKey.DSA.generate($SIZE, ...) - - pattern: Cryptodome.PublicKey.RSA.generate($SIZE, ...) - - pattern: Crypto.PublicKey.DSA.generate(bits=$SIZE, ...) - - pattern: Cryptodome.PublicKey.DSA.generate(bits=$SIZE, ...) - - pattern: pycrypto_rsa.generate(bits=$SIZE, ...) - - pattern: pycrypto_dsa.generate(bits=$SIZE, ...) - - pattern: pycryptodomex_rsa.generate(bits=$SIZE, ...) - - pattern: pycryptodomex_rsa.generate($SIZE, ...) - - pattern: pycryptodomex_dsa.generate(bits=$SIZE, ...) - - pattern: pycryptodomex_dsa.generate($SIZE, ...) - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - severity: ERROR - - id: python_crypto_rule-crypto-encrypt-ec - languages: - - python - message: | - The application was found using an insufficient curve size for the Elliptical - Cryptography (EC) asymmetric algorithm. NIST recommends using a key size of - 224 or greater. - - To remediate this issue, replace the current key size with `ec.SECP384R1`, - - Example using `ec.SECP384R1`: - ``` - from cryptography.hazmat.primitives.asymmetric import ec - # Generate an EC private key using SECP384R1 - private_key = ec.generate_private_key( - ec.SECP384R1() - ) - # Work with/sign data using the key - # ... - ``` - - For more information on the cryptography module's EC section see: - - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/ - metadata: - category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Inadequate encryption strength - patterns: - - pattern-inside: cryptography.hazmat.primitives.asymmetric.ec.generate_private_key(...) - - pattern: cryptography.hazmat.primitives.asymmetric.ec.$SIZE - - metavariable-pattern: - metavariable: $SIZE - pattern-either: - - pattern: SECP192R1 - - pattern: SECT163K1 - - pattern: SECT163R2 - - focus-metavariable: $SIZE + $DATA = request.$W + ... + $INTERM = $STR + $DATA + ... + urllib.request.urlopen(..., $INTERM, ...) + - pattern: $A = urllib.request.urlopen(..., request.$W, ...) + - pattern: return urllib.request.urlopen(..., request.$W, ...) severity: ERROR - - id: python_crypto_rule-crypto-hash-md5 - languages: - - python - message: | - The application was found using an insecure or risky digest or signature algorithm. MD5 - and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. - It is strongly recommended that a standard digest algorithm be chosen instead as implementing - a custom algorithm is prone to errors. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example of creating a SHA-384 hash using the `cryptography` package: - ``` - from cryptography.hazmat.primitives import hashes - # Create a SHA384 digest - digest = hashes.Hash(hashes.SHA384()) - # Update the digest with some initial data - digest.update(b"some data to hash") - # Add more data to the digest - digest.update(b"some more data") - # Finalize the digest as bytes - result = digest.finalize() - ``` - - For more information on secure password storage see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: Crypto.Hash.MD5.new(...) - - pattern: Cryptodome.Hash.MD5.new (...) - severity: WARNING - - id: python_crypto_rule-crypto-hash-sha1 - languages: - - python - message: | - The application was found using an insecure or risky digest or signature algorithm. MD5 - and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. - It is strongly recommended that a standard digest algorithm be chosen instead as implementing - a custom algorithm is prone to errors. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example of creating a SHA-384 hash using the `cryptography` package: - ``` - from cryptography.hazmat.primitives import hashes - # Create a SHA384 digest - digest = hashes.Hash(hashes.SHA384()) - # Update the digest with some initial data - digest.update(b"some data to hash") - # Add more data to the digest - digest.update(b"some more data") - # Finalize the digest as bytes - result = digest.finalize() - ``` - - For more information on secure password storage see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: Crypto.Hash.SHA.new(...) - - pattern: Cryptodome.Hash.SHA.new (...) - severity: WARNING - - id: python_crypto_rule-crypto-hazmat-cipher-arc4 - languages: - - python - message: | - DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. - Newer algorithms apply message integrity to validate ciphertext has not been tampered - with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the - alternatives such as `AES-256-GCM`. - - For older applications that don't have support for `ChaCha20Poly1305`, - `AES-256-GCM` is recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Example using `ChaCha20Poly1305`: - ``` - import os - # Import ChaCha20Poly1305 from cryptography - from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = ChaCha20Poly1305.generate_key() - # Create a new ChaCha20Poly1305 instance with our secure key - chacha = ChaCha20Poly1305(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = chacha.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - chacha.decrypt(nonce, cipher_text, aad) - ``` - - Example using `AESGCM`: - ``` - import os - # Import AESGCM from cryptography - from cryptography.hazmat.primitives.ciphers.aead import AESGCM - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = AESGCM.generate_key(bit_length=128) - # Create a new AESGCM instance with our secure key - aesgcm = AESGCM(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = aesgcm.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - aesgcm.decrypt(nonce, cipher_text, aad) - ``` - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - pattern: cryptography.hazmat.primitives.ciphers.algorithms.ARC4(...) - severity: WARNING - - id: python_crypto_rule-crypto-hazmat-cipher-blowfish - languages: - - python - message: | - The Blowfish encryption algorithm was meant as a drop-in replacement for DES and was created in - 1993. Smaller key sizes may make the ciphertext vulnerable to [birthday - attacks](https://en.wikipedia.org/wiki/Birthday_attack). While no known attacks against - Blowfish - exist, it should never be used to encrypt files over 4GB in size. If possible consider - using ChaCha20Poly1305 or AES-GCM instead of Blowfish. - - For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is - recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Example using `ChaCha20Poly1305`: - ``` - import os - # Import ChaCha20Poly1305 from cryptography - from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = ChaCha20Poly1305.generate_key() - # Create a new ChaCha20Poly1305 instance with our secure key - chacha = ChaCha20Poly1305(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = chacha.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - chacha.decrypt(nonce, cipher_text, aad) - ``` - - Example using `AESGCM`: - ``` - import os - # Import AESGCM from cryptography - from cryptography.hazmat.primitives.ciphers.aead import AESGCM - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = AESGCM.generate_key(bit_length=128) - # Create a new AESGCM instance with our secure key - aesgcm = AESGCM(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = aesgcm.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - aesgcm.decrypt(nonce, cipher_text, aad) - ``` - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - pattern: cryptography.hazmat.primitives.ciphers.algorithms.Blowfish(...) - severity: WARNING - - id: python_crypto_rule-crypto-hazmat-cipher-idea - languages: - - python - message: | - The IDEA encryption algorithm was meant as a drop-in replacement for DES and was created in - 1991. A number of [vulnerabilities and - exploits](https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm#Security) have - been identified to work against IDEA and - it is no longer recommended. If possible consider - using ChaCha20Poly1305 or AES-GCM instead of Blowfish. - - For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is - recommended, however it has many drawbacks: - - Slower than `ChaCha20Poly1305`. - - Catastrophic failure if nonce values are reused. - - Example using `ChaCha20Poly1305`: - ``` - import os - # Import ChaCha20Poly1305 from cryptography - from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = ChaCha20Poly1305.generate_key() - # Create a new ChaCha20Poly1305 instance with our secure key - chacha = ChaCha20Poly1305(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = chacha.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - chacha.decrypt(nonce, cipher_text, aad) - ``` - - Example using `AESGCM`: - ``` - import os - # Import AESGCM from cryptography - from cryptography.hazmat.primitives.ciphers.aead import AESGCM - # Our plaintext to encrypt - plain_text = b"Secret text to encrypt" - # We do not require authenticated but unencrypted data, so set to None - aad = None - # Generate a secure key - key = AESGCM.generate_key(bit_length=128) - # Create a new AESGCM instance with our secure key - aesgcm = AESGCM(key) - # Note: nonce values _must_ be regenerated every time they are used. - nonce = os.urandom(12) - # Encrypt our plaintext - cipher_text = aesgcm.encrypt(nonce, plain_text, aad) - # Decrypt the plain text using the nonce and cipher_text - aesgcm.decrypt(nonce, cipher_text, aad) - ``` - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a Broken or Risky Cryptographic Algorithm - pattern: cryptography.hazmat.primitives.ciphers.algorithms.IDEA(...) - severity: WARNING - - id: python_crypto_rule-crypto.hazmat-hash-md5 - languages: - - python - message: | - The application was found using an insecure or risky digest or signature algorithm. MD2, MD5 - and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. - It is strongly recommended that a standard digest algorithm be chosen instead as implementing - a custom algorithm is prone to errors. - - Example of creating a SHA-384 hash using the `cryptography` package: - ``` - from cryptography.hazmat.primitives import hashes - # Create a SHA384 digest - digest = hashes.Hash(hashes.SHA384()) - # Update the digest with some initial data - digest.update(b"some data to hash") - # Add more data to the digest - digest.update(b"some more data") - # Finalize the digest as bytes - result = digest.finalize() - ``` - - For more information on secure password storage see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - pattern: cryptography.hazmat.primitives.hashes.MD5(...) - severity: WARNING - - id: python_crypto_rule-crypto.hazmat-hash-sha1 - languages: - - python - message: | - The application was found using an insecure or risky digest or signature algorithm. MD2, MD5 - and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. - It is strongly recommended that a standard digest algorithm be chosen instead as implementing - a custom algorithm is prone to error. - - Example of creating a SHA-384 hash using the `cryptography` package: - ``` - from cryptography.hazmat.primitives import hashes - # Create a SHA384 digest - digest = hashes.Hash(hashes.SHA384()) - # Update the digest with some initial data - digest.update(b"some data to hash") - # Add more data to the digest - digest.update(b"some more data") - # Finalize the digest as bytes - result = digest.finalize() - ``` - - For more information on secure password storage see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - pattern: cryptography.hazmat.primitives.hashes.SHA1(...) - severity: WARNING - - id: python_crypto_rule-hash-md2 + - id: python.django.security.nan-injection.nan-injection languages: - python - message: | - The application was found using an insecure or risky digest or signature algorithm. MD2, MD5 - and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example of creating a SHA-384 hash using the `cryptography` package: - ``` - from cryptography.hazmat.primitives import hashes - # Create a SHA384 digest - digest = hashes.Hash(hashes.SHA384()) - # Update the digest with some initial data - digest.update(b"some data to hash") - # Add more data to the digest - digest.update(b"some more data") - # Finalize the digest as bytes - result = digest.finalize() - ``` - - For more information on secure password storage see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ + message: Found user input going directly into typecast for bool(), float(), or complex(). This allows an attacker to inject Python's not-a-number (NaN) into the typecast. This results in undefind behavior, particularly when doing comparisons. Either cast to a different type, or add a guard checking for all capitalizations of the string 'nan'. metadata: category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: Crypto.Hash.MD2.new(...) - - pattern: Cryptodome.Hash.MD2.new (...) - severity: WARNING - - id: python_crypto_rule-hash-md4 + confidence: MEDIUM + cwe: + - 'CWE-704: Incorrect Type Conversion or Cast' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://discuss.python.org/t/nan-breaks-min-max-and-sorting-functions-a-solution/2868 + - https://blog.bitdiscovery.com/2021/12/python-nan-injection/ + subcategory: + - vuln + technology: + - django + mode: taint + pattern-sanitizers: + - not_conflicting: true + pattern: $ANYTHING(...) + pattern-sinks: + - patterns: + - pattern-either: + - pattern: float(...) + - pattern: bool(...) + - pattern: complex(...) + - pattern-not-inside: | + if $COND: + ... + ... + pattern-sources: + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + severity: ERROR + - id: python.django.security.passwords.password-empty-string.password-empty-string languages: - python - message: | - The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, - MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example of creating a SHA-384 hash using the `cryptography` package: - ``` - from cryptography.hazmat.primitives import hashes - # Create a SHA384 digest - digest = hashes.Hash(hashes.SHA384()) - # Update the digest with some initial data - digest.update(b"some data to hash") - # Add more data to the digest - digest.update(b"some more data") - # Finalize the digest as bytes - result = digest.finalize() - ``` - - For more information on secure password storage see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ + message: '''$VAR'' is the empty string and is being used to set the password on ''$MODEL''. If you meant to set an unusable password, set the password to None or call ''set_unusable_password()''.' metadata: category: security - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-521: Weak Password Requirements' + impact: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm + - A07:2021 - Identification and Authentication Failures + references: + - https://docs.djangoproject.com/en/3.0/ref/contrib/auth/#django.contrib.auth.models.User.set_password + subcategory: + - vuln + technology: + - django patterns: - pattern-either: - - pattern: Crypto.Hash.MD4.new(...) - - pattern: Cryptodome.Hash.MD4.new (...) - severity: WARNING - - id: python_crypto_rule-hash-md5 - languages: - - python - message: | - The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, - MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example of creating a SHA-384 hash using the `cryptography` package: - ``` - from cryptography.hazmat.primitives import hashes - # Create a SHA384 digest - digest = hashes.Hash(hashes.SHA384()) - # Update the digest with some initial data - digest.update(b"some data to hash") - # Add more data to the digest - digest.update(b"some more data") - # Finalize the digest as bytes - result = digest.finalize() - ``` - - For more information on secure password storage see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - pattern: hashlib.md5(...) - severity: WARNING - - id: python_crypto_rule-hash-sha1 - languages: - - python - message: | - The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, - MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. - - Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for - new applications, instead consider using the [cryptography](https://cryptography.io/) package. - - Example of creating a SHA-384 hash using the `cryptography` package: - ``` - from cryptography.hazmat.primitives import hashes - # Create a SHA384 digest - digest = hashes.Hash(hashes.SHA384()) - # Update the digest with some initial data - digest.update(b"some data to hash") - # Add more data to the digest - digest.update(b"some more data") - # Finalize the digest as bytes - result = digest.finalize() - ``` - - For more information on secure password storage see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - - For more information on the cryptography module see: - - https://cryptography.io/en/latest/ - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm - pattern: hashlib.sha1(...) - severity: WARNING - - id: python_crypto_rule-hashlib-new-insecure-functions + - pattern: | + $MODEL.set_password($EMPTY) + ... + $MODEL.save() + - pattern: | + $VAR = $EMPTY + ... + $MODEL.set_password($VAR) + ... + $MODEL.save() + - metavariable-regex: + metavariable: $EMPTY + regex: (\'\'|\"\") + severity: ERROR + - fix: | + None + id: python.django.security.passwords.use-none-for-password-default.use-none-for-password-default languages: - python - message: | - The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, - MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. - - This means - that two different values, when hashed, can lead to the same hash value. If the application is - trying - to use these hash methods for storing passwords, then it is recommended to switch to a - password hashing - algorithm such as Argon2id or PBKDF2. - It is strongly recommended that a standard digest algorithm be chosen instead as implementing - a custom algorithm is prone to errors. - - Example using `hashlib.sha384()` to create a SHA384 hash: - ``` - import hashlib - # Create a SHA384 digest - digest = hashlib.sha384() - # Update the digest with some initial data - digest.update(b"some data to hash") - # Add more data to the digest - digest.update(b"some more data") - # Finalize the digest as bytes - digest.digest() - ``` + message: '''$VAR'' is using the empty string as its default and is being used to set the password on ''$MODEL''. If you meant to set an unusable password, set the default value to ''None'' or call ''set_unusable_password()''.' metadata: category: security - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-521: Weak Password Requirements' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of a broken or risky cryptographic algorithm + - A07:2021 - Identification and Authentication Failures + references: + - https://docs.djangoproject.com/en/3.0/ref/contrib/auth/#django.contrib.auth.models.User.set_password + subcategory: + - vuln + technology: + - django patterns: - pattern-either: - - pattern: hashlib.new("=~/[M|m][D|d][4|5]/", ...) - - pattern: hashlib.new(..., name="=~/[M|m][D|d][4|5]/", ...) - - pattern: hashlib.new('sha1') - - pattern: hashlib.new(..., name='SHA1') - - pattern: hashlib.new('sha', string='test') - - pattern: hashlib.new(name='SHA', string='test') - severity: WARNING - - id: python_crypto_rule-import-pycrypto + - pattern: | + $VAR = request.$W.get($X, $EMPTY) + ... + $MODEL.set_password($VAR) + ... + $MODEL.save(...) + - pattern: | + def $F(..., $VAR=$EMPTY, ...): + ... + $MODEL.set_password($VAR) + - metavariable-pattern: + metavariable: $EMPTY + pattern: '""' + - focus-metavariable: $EMPTY + severity: ERROR + - id: python.fastapi.security.wildcard-cors.wildcard-cors languages: - python - message: | - The application was detected importing `pycrypto`. This package has been deprecated as it - contains - security vulnerabilities. - - To remediate this issue, consider using the [cryptography](https://cryptography.io/) - package instead. + message: CORS policy allows any origin (using wildcard '*'). This is insecure and should be avoided. metadata: category: security - cwe: CWE-1104 + confidence: MEDIUM + cwe: + - 'CWE-942: Permissive Cross-domain Policy with Untrusted Domains' + impact: LOW + likelihood: HIGH owasp: - - A9:2017-Using Components with Known Vulnerabilities - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of unmaintained third party components - pattern-either: - - pattern: import pycryto - - pattern: import Crypto.Cipher - - pattern: import Crypto.Hash - - pattern: import Crypto.IO - - pattern: import Crypto.Protocol - - pattern: import Crypto.PublicKey - - pattern: import Crypto.Random - - pattern: import Crypto.Signature - - pattern: import Crypto.Util - severity: ERROR - - id: python_deserialization_rule-cpickle + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + - https://cwe.mitre.org/data/definitions/942.html + subcategory: + - vuln + technology: + - python + - fastapi + vulnerability_class: + - Configuration + mode: taint + pattern-sinks: + - patterns: + - pattern: | + $APP.add_middleware( + CORSMiddleware, + allow_origins=$ORIGIN, + ...); + - focus-metavariable: $ORIGIN + pattern-sources: + - pattern: '[..., "*", ...]' + severity: WARNING + - id: python.flask.security.audit.app-run-param-config.avoid_app_run_with_bad_host languages: - python - message: | - The application was found using `cPickle` which is vulnerable to deserialization attacks. - Deserialization attacks exploit the process of reading serialized data and turning it back - into an object. By constructing malicious objects and serializing them, an adversary may - attempt to: - - - Inject code that is executed upon object construction, which occurs during the - deserialization process. - - Exploit mass assignment by including fields that are not normally a part of the serialized - data but are read in during deserialization. - - Consider safer alternatives such as serializing data in the JSON format. Ensure any format - chosen allows - the application to specify exactly which object types are allowed to be deserialized. - - To protect against mass assignment, only allow deserialization of the specific fields that are - required. If this is not easily done, consider creating an intermediary type that - can be serialized with only the necessary fields exposed. - - Example JSON deserializer using an intermediary type that is validated against a schema to - ensure - it is safe from mass assignment: - ``` - import jsonschema - - # Create a schema to validate our user-supplied input against - # an intermediary object - intermediary_schema = { - "type" : "object", - "properties" : { - "name": {"type" : "string"} - }, - "required": ["name"], - # Protect against random properties being added to the object - "additionalProperties": False, - } - # If a user attempted to add "'is_admin': True" it would cause a validation error - intermediary_object = {'name': 'test user'} - - try: - # Validate the user supplied intermediary object against our schema - jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) - user_object = {'user': - { - # Assign the deserialized data from intermediary object - 'name': intermediary_object['name'], - # Add in protected data in object definition (or set it from a class constructor) - 'is_admin': False, - } - } - # Work with the user_object - except jsonschema.exceptions.ValidationError as ex: - # Gracefully handle validation errors - # ... - ``` - - For more details on deserialization attacks in general, see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + message: Running flask app with host 0.0.0.0 could expose the server publicly. metadata: category: security - cwe: CWE-502 + confidence: HIGH + cwe: + - 'CWE-668: Exposure of Resource to Wrong Sphere' + impact: MEDIUM + likelihood: HIGH owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: High - shortDescription: Deserialization of untrusted data - pattern: cPickle.$FUNC(...) + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - flask + pattern-either: + - pattern: app.run(..., host="0.0.0.0", ...) + - pattern: app.run(..., "0.0.0.0", ...) severity: WARNING - - id: python_deserialization_rule-dill + - id: python.flask.security.audit.app-run-security-config.avoid_using_app_run_directly languages: - python - message: | - The application was found using `dill` which is vulnerable to deserialization attacks. - Deserialization attacks exploit the process of reading serialized data and turning it back - into an object. By constructing malicious objects and serializing them, an adversary may - attempt to: - - - Inject code that is executed upon object construction, which occurs during the - deserialization process. - - Exploit mass assignment by including fields that are not normally a part of the serialized - data but are read in during deserialization. - - Consider safer alternatives such as serializing data in the JSON format. Ensure any format - chosen allows - the application to specify exactly which object types are allowed to be deserialized. - - To protect against mass assignment, only allow deserialization of the specific fields that are - required. If this is not easily done, consider creating an intermediary type that - can be serialized with only the necessary fields exposed. - - Example JSON deserializer using an intermediary type that is validated against a schema to - ensure - it is safe from mass assignment: - ``` - import jsonschema - - # Create a schema to validate our user-supplied input against - # an intermediary object - intermediary_schema = { - "type" : "object", - "properties" : { - "name": {"type" : "string"} - }, - "required": ["name"], - # Protect against random properties being added to the object - "additionalProperties": False, - } - # If a user attempted to add "'is_admin': True" it would cause a validation error - intermediary_object = {'name': 'test user'} - - try: - # Validate the user supplied intermediary object against our schema - jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) - user_object = {'user': - { - # Assign the deserialized data from intermediary object - 'name': intermediary_object['name'], - # Add in protected data in object definition (or set it from a class constructor) - 'is_admin': False, - } - } - # Work with the user_object - except jsonschema.exceptions.ValidationError as ex: - # Gracefully handle validation errors - # ... - ``` - - For more details on deserialization attacks in general, see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + message: top-level app.run(...) is ignored by flask. Consider putting app.run(...) behind a guard, like inside a function metadata: category: security - cwe: CWE-502 + confidence: MEDIUM + cwe: + - 'CWE-668: Exposure of Resource to Wrong Sphere' + impact: MEDIUM + likelihood: LOW owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: High - shortDescription: Deserialization of untrusted data + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - flask patterns: - - pattern: dill.$FUNC(...) - - pattern-not: dill.$FUNC("...") + - pattern-not-inside: | + if __name__ == '__main__': + ... + - pattern-not-inside: | + def $X(...): + ... + - pattern: app.run(...) severity: WARNING - - id: python_deserialization_rule-marshal + - id: python.flask.security.audit.debug-enabled.debug-enabled languages: - python - message: | - The application was found using `dill` which is vulnerable to deserialization attacks. - Deserialization attacks exploit the process of reading serialized data and turning it back - into an object. By constructing malicious objects and serializing them, an adversary may - attempt to: - - - Inject code that is executed upon object construction, which occurs during the - deserialization process. - - Exploit mass assignment by including fields that are not normally a part of the serialized - data but are read in during deserialization. - - Consider safer alternatives such as serializing data in the JSON format. Ensure any format - chosen allows - the application to specify exactly which object types are allowed to be deserialized. - - To protect against mass assignment, only allow deserialization of the specific fields that are - required. If this is not easily done, consider creating an intermediary type that - can be serialized with only the necessary fields exposed. - - Example JSON deserializer using an intermediary type that is validated against a schema to - ensure - it is safe from mass assignment: - ``` - import jsonschema - - # Create a schema to validate our user-supplied input against - # an intermediary object - intermediary_schema = { - "type" : "object", - "properties" : { - "name": {"type" : "string"} - }, - "required": ["name"], - # Protect against random properties being added to the object - "additionalProperties": False, - } - # If a user attempted to add "'is_admin': True" it would cause a validation error - intermediary_object = {'name': 'test user'} - - try: - # Validate the user supplied intermediary object against our schema - jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) - user_object = {'user': - { - # Assign the deserialized data from intermediary object - 'name': intermediary_object['name'], - # Add in protected data in object definition (or set it from a class constructor) - 'is_admin': False, - } - } - # Work with the user_object - except jsonschema.exceptions.ValidationError as ex: - # Gracefully handle validation errors - # ... - ``` - - For more details on deserialization attacks in general, see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + message: Detected Flask app with debug=True. Do not deploy to production with this flag enabled as it will leak sensitive information. Instead, consider using Flask configuration variables or setting 'debug' using system environment variables. metadata: category: security - cwe: CWE-502 - owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: High - shortDescription: Deserialization of untrusted data - pattern-either: - - pattern: marshal.dump(...) - - pattern: marshal.dumps(...) - - pattern: marshal.load(...) - - pattern: marshal.loads(...) + confidence: HIGH + cwe: + - 'CWE-489: Active Debug Code' + impact: MEDIUM + likelihood: HIGH + owasp: A06:2017 - Security Misconfiguration + references: + - https://labs.detectify.com/2015/10/02/how-patreon-got-hacked-publicly-exposed-werkzeug-debugger/ + subcategory: + - vuln + technology: + - flask + patterns: + - pattern-inside: | + import flask + ... + - pattern: $APP.run(..., debug=True, ...) severity: WARNING - - id: python_deserialization_rule-pickle + - id: python.flask.security.audit.directly-returned-format-string.directly-returned-format-string languages: - python - message: | - The application was found using `pickle` which is vulnerable to deserialization attacks. - Deserialization attacks exploit the process of reading serialized data and turning it back - into an object. By constructing malicious objects and serializing them, an adversary may - attempt to: - - - Inject code that is executed upon object construction, which occurs during the - deserialization process. - - Exploit mass assignment by including fields that are not normally a part of the serialized - data but are read in during deserialization. - - Consider safer alternatives such as serializing data in the JSON format. Ensure any format - chosen allows the application to specify exactly which object types are allowed to be deserialized. - - To protect against mass assignment, only allow deserialization of the specific fields that are - required. If this is not easily done, consider creating an intermediary type that - can be serialized with only the necessary fields exposed. - - Example JSON deserializer using an intermediary type that is validated against a schema to ensure - it is safe from mass assignment: - ``` - import jsonschema - - # Create a schema to validate our user-supplied input against - # an intermediary object - intermediary_schema = { - "type" : "object", - "properties" : { - "name": {"type" : "string"} - }, - "required": ["name"], - # Protect against random properties being added to the object - "additionalProperties": False, - } - # If a user attempted to add "'is_admin': True" it would cause a validation error - intermediary_object = {'name': 'test user'} - - try: - # Validate the user supplied intermediary object against our schema - jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) - user_object = {'user': - { - # Assign the deserialized data from intermediary object - 'name': intermediary_object['name'], - # Add in protected data in object definition (or set it from a class constructor) - 'is_admin': False, - } - } - # Work with the user_object - except jsonschema.exceptions.ValidationError as ex: - # Gracefully handle validation errors - # ... - ``` - - For more details on deserialization attacks in general, see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + message: Detected Flask route directly returning a formatted string. This is subject to cross-site scripting if user input can reach the string. Consider using the template engine instead and rendering pages with 'render_template()'. metadata: category: security - cwe: CWE-502 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: High - shortDescription: Deserialization of untrusted data - patterns: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - flask + mode: taint + pattern-sinks: + - patterns: + - pattern-not-inside: return "..." + - pattern-either: + - pattern: return "...".format(...) + - pattern: return "..." % ... + - pattern: return "..." + ... + - pattern: return ... + "..." + - pattern: return f"...{...}..." + - patterns: + - pattern: return $X + - pattern-either: + - pattern-inside: | + $X = "...".format(...) + ... + - pattern-inside: | + $X = "..." % ... + ... + - pattern-inside: | + $X = "..." + ... + ... + - pattern-inside: | + $X = ... + "..." + ... + - pattern-inside: | + $X = f"...{...}..." + ... + - pattern-not-inside: | + $X = "..." + ... + pattern-sources: - pattern-either: - patterns: - - pattern: pickle.$METHOD(...) - - pattern-not: pickle.$METHOD("...") - - patterns: - - pattern: _pickle.$METHOD(...) - - pattern-not: _pickle.$METHOD("...") - - metavariable-regex: - metavariable: $METHOD - regex: (load|loads|Unpickler) + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $PARAM, ...): + ... + - pattern: $PARAM + - pattern: | + request.$FUNC.get(...) + - pattern: | + request.$FUNC(...) + - pattern: request.$FUNC[...] severity: WARNING - - id: python_deserialization_rule-shelve + - id: python.flask.security.hashids-with-flask-secret.hashids-with-flask-secret languages: - python - message: | - The application was found using `shelve` which is vulnerable to deserialization attacks as - it calls `pickle` internally. - Deserialization attacks exploit the process of reading serialized data and turning it back - into an object. By constructing malicious objects and serializing them, an adversary may - attempt to: - - - Inject code that is executed upon object construction, which occurs during the - deserialization process. - - Exploit mass assignment by including fields that are not normally a part of the serialized - data but are read in during deserialization. - - Consider safer alternatives such as serializing data in the JSON format. Ensure any format - chosen allows - the application to specify exactly which object types are allowed to be deserialized. - - To protect against mass assignment, only allow deserialization of the specific fields that are - required. If this is not easily done, consider creating an intermediary type that - can be serialized with only the necessary fields exposed. - - Example JSON deserializer using an intermediary type that is validated against a schema to - ensure - it is safe from mass assignment: - ``` - import jsonschema - - # Create a schema to validate our user-supplied input against - # an intermediary object - intermediary_schema = { - "type" : "object", - "properties" : { - "name": {"type" : "string"} - }, - "required": ["name"], - # Protect against random properties being added to the object - "additionalProperties": False, - } - # If a user attempted to add "'is_admin': True" it would cause a validation error - intermediary_object = {'name': 'test user'} - - try: - # Validate the user supplied intermediary object against our schema - jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) - user_object = {'user': - { - # Assign the deserialized data from intermediary object - 'name': intermediary_object['name'], - # Add in protected data in object definition (or set it from a class constructor) - 'is_admin': False, - } - } - # Work with the user_object - except jsonschema.exceptions.ValidationError as ex: - # Gracefully handle validation errors - # ... - ``` - - For more details on deserialization attacks in general, see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + 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 - cwe: CWE-502 + confidence: HIGH + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: HIGH + likelihood: LOW owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: High - shortDescription: Deserialization of untrusted data + - 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 + subcategory: + - vuln + technology: + - flask pattern-either: - - pattern: shelve.$FUNC(...) - severity: WARNING - - id: python_deserialization_rule-yaml-load + - 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 + - id: python.flask.security.injection.csv-writer-injection.csv-writer-injection languages: - python - message: | - The application was found using an unsafe version of `yaml` load which is vulnerable to - deserialization attacks. Deserialization attacks exploit the process of reading serialized - data and turning it back - into an object. By constructing malicious objects and serializing them, an adversary may - attempt to: - - - Inject code that is executed upon object construction, which occurs during the - deserialization process. - - Exploit mass assignment by including fields that are not normally a part of the serialized - data but are read in during deserialization. - - To remediate this issue, use `safe_load()` or call `yaml.load()` with the `Loader` argument - set to - `yaml.SafeLoader`. - - Example loading YAML using `safe_load`: - ``` - import yaml - - # Use safe_load to load data into an intermediary object - intermediary_object = yaml.safe_load("""user: - name: 'test user'""" - ) - # Create our real object, copying over only the necessary fields - user_object = {'user': { - # Assign the deserialized data from intermediary object - 'name': intermediary_object['user']['name'], - # Add in protected data in object definition (or set it from a class constructor) - 'is_admin': False, - } - } - # Work with user_object - # ... - ``` - - For more details on deserialization attacks in general, see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + message: Detected user input into a generated CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs. metadata: category: security - cwe: CWE-502 + confidence: MEDIUM + cwe: + - 'CWE-1236: Improper Neutralization of Formula Elements in a CSV File' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: High - shortDescription: Deserialization of untrusted data - patterns: - - pattern-inside: | - import yaml - ... - - pattern-not-inside: | - from ruamel.yaml import YAML - ... - - pattern-either: - - pattern: yaml.unsafe_load(...) - - pattern: yaml.$LD(..., Loader=yaml.$LOADER, ...) - - pattern: yaml.$LD($DATA) - - metavariable-regex: - metavariable: $LOADER - regex: (Loader|UnsafeLoader|CLoader|FullLoader) - - metavariable-regex: - metavariable: $LD - regex: (load|load_all) + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/raphaelm/defusedcsv + - https://owasp.org/www-community/attacks/CSV_Injection + - https://web.archive.org/web/20220516052229/https://www.contextis.com/us/blog/comma-separated-vulnerabilities + subcategory: + - vuln + technology: + - python + - flask + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + $WRITER = csv.writer(...) + + ... + + $WRITER.$WRITE(...) + - pattern: $WRITER.$WRITE(...) + - metavariable-regex: + metavariable: $WRITE + regex: ^(writerow|writerows|writeheader)$ + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR severity: ERROR - - id: python_django_rule-django-extra-used + - id: python.flask.security.injection.nan-injection.nan-injection languages: - python - message: | - SQL Injection is a critical vulnerability that can lead to data or system compromise. By - dynamically generating SQL query strings, user input may be able to influence the logic of - the SQL statement. This could lead to an adversary accessing information they should - not have access to, or in some circumstances, being able to execute OS functionality or code. - - Replace all dynamically generated SQL queries with parameterized queries. In situations where - dynamic queries must be created, never use direct user input, but instead use a map or - dictionary of valid values and resolve them using a user supplied key. - - For example, some database drivers do not allow parameterized queries for `>` or `<` comparison - operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the - user - supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` - values to be used in the construction of the dynamic query. The same goes for other queries - where - column or table names are required but cannot be parameterized. - - The `QuerySet.extra` API method will be deprecated as it a source of SQL Injection - vulnerabilities and other problems. This method is especially risky as callers - will need to do their own escaping of any parameters that come from user-supplied - information. - - To remediate this issue, do not use `extra` but use other `QuerySet` methods to achieve - the same goals. If for some reason this is not feasible, consider using the `RawSQL` method - and making sure that all arguments, including user-supplied ones, are only used in - `params` - - - While not recommended due to [potential SQL - Injection](https://docs.djangoproject.com/en/4.2/ref/models/expressions/#raw-sql-expressions), - below is an example using `RawSQL`, - passing in user-supplied data as a `param` which will escape the input: - ``` - # If dealing with integer based user input, restrict the values to integers only using the - # path configuration: path('/someview/', views.some_view, - name='someview'), - - # views.py - def some_view(request, user_supplied_id): - # Never use string interpolation in the `sql` parameter. - # Never quote the `%s` string format such as `... where id='%s'` as this could lead to SQL - Injection. - # Pass the user supplied data only in the `params` parameter. - for obj in DBObject.objects.all().annotate( - val=RawSQL(sql="select id from some_secondary_table where id=%s", - params=[user_supplied_id])): - # Work with the results from the query - # ... - ``` - - For more information on QuerySet see: - - https://docs.djangoproject.com/en/4.2/ref/models/querysets/#queryset-api - - For more information on SQL Injection see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + message: Found user input going directly into typecast for bool(), float(), or complex(). This allows an attacker to inject Python's not-a-number (NaN) into the typecast. This results in undefind behavior, particularly when doing comparisons. Either cast to a different type, or add a guard checking for all capitalizations of the string 'nan'. metadata: category: security - cwe: CWE-89 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an SQL Command ('SQL Injection') - patterns: - - pattern: $X.objects. ... .extra(..., $K = $V, ...) - - pattern-not-inside: | - $V = ['...'] - ... - - metavariable-pattern: - metavariable: $V - patterns: - - pattern: $V - - pattern-not: '[..., ''...'', ...]' - - pattern-not: '{..., ''...'': ''...'', ...}' - - pattern-not: '"..."' - - pattern-not: '[..., "..." % "...", ...]' - - pattern-not: '{..., $L: "..." % "...", ...}' - - pattern-not: '{..., $L: "...".format("..."), ...}' - - pattern-not: '[..., "...".format("..."), ...]' - severity: WARNING - - id: python_escaping_rule-jinja2-autoescape-false + confidence: MEDIUM + cwe: + - 'CWE-704: Incorrect Type Conversion or Cast' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://discuss.python.org/t/nan-breaks-min-max-and-sorting-functions-a-solution/2868 + - https://blog.bitdiscovery.com/2021/12/python-nan-injection/ + subcategory: + - vuln + technology: + - flask + mode: taint + pattern-sanitizers: + - not_conflicting: true + pattern: $ANYTHING(...) + pattern-sinks: + - pattern-either: + - pattern: float(...) + - pattern: bool(...) + - pattern: complex(...) + pattern-sources: + - pattern-either: + - pattern: flask.request.$SOMETHING.get(...) + - pattern: flask.request.$SOMETHING[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR + severity: ERROR + - id: python.flask.security.injection.os-system-injection.os-system-injection languages: - python - message: | - The application was found using Jinja2 `Environment` without autoescaping enabled. If using in - the context of HTML this could lead to Cross-Site Scripting (XSS) attacks when rendering with - user-supplied input. - - Unfortunately, Jinja2 does not support context-aware escaping, meaning it is insufficient to - protect against - XSS for the various web contexts. It is important to encode the data depending on the specific - context - it - is used in. There are at least six context types: - - - Inside HTML tags `
    context 1
    ` - - Inside attributes: `
    ` - - Inside event attributes `` - - Inside script blocks: `` - - Unsafe element HTML assignment: `element.innerHTML = "context 5"` - - Inside URLs: `link` - - Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if - user input - is ever output inside of script tags. - - User input that is displayed within the application must be encoded, sanitized or validated - to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be - taken - to not mix server-side templating with client-side templating, as the server-side templating - will - not encode things like {{ 7*7 }} which may execute client-side templating features. - - It is _NOT_ advised to encode user input prior to inserting into a data store. The data will - need to be - encoded depending on context of where it is output. It is much safer to force the displaying - system to - handle the encoding and not attempt to guess how it should be encoded. - - To handle different contexts, one approach would be to write custom Jinja2 filters. Below is - an example - that escapes or encodes links and potentially malicious script, note this does not include - other contexts - such as CSS or attributes: - ``` - from jinja2 import Environment, select_autoescape, FileSystemLoader - from jinja2 import pass_eval_context - from markupsafe import Markup, escape - - @pass_eval_context - def escape_link(eval_ctx, value): - bad_link = "#JinjatmplZ" - # Block any values that start with // as that could be used to inject - # links to third party pages see: - https://en.wikipedia.org/wiki/Wikipedia:Protocol-relative_URL - if value.startswith('//'): - return bad_link - - # Only allow relative links - # if you want to allow links that start with http or ws replace with below: - # if not value.startswith('/'): and not value.startswith('http') and not - value.startswith('ws') - if not value.startswith('/'): - return bad_link - - # Alternatively, you could only call escape if autoescape is true - # if eval_ctx.autoescape: - # return escape(value) - # else - # return value - - return escape(value) - - # Create a replacement table - js_replacement = str.maketrans({ - '"': "\\u0022", - '`': "\\u0060", - '&': "\\u0026", - '\'': "\\u0027", - '+': "\\u002b", - '/': "\\/", - '<': "\\u003c", - '>': "\\u003e", - '\\': "\\\\", - '(': "\\u0028", - ')': "\\u0029", - }) - - @pass_eval_context - def escape_js(eval_ctx, value): - """ - Escape the input for use in ", - script_context="alert(1);alert`1`",) - ) - - # Sample template: - """ - - - - My Webpage - - -

    My Webpage

    - {{ html_context }} - link - - - - """ - ``` - - For more information on autoescape see: - - https://jinja.palletsprojects.com/en/3.1.x/api/#autoescaping - - For more information on XSS see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + message: User data detected in os.system. This could be vulnerable to a command injection and should be avoided. If this must be done, use the 'subprocess' module instead and pass the arguments as a list. metadata: category: security - cwe: CWE-116 + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper encoding or escaping of output - patterns: - - pattern-inside: | - import jinja2 - ... - - pattern-not: jinja2.Environment(..., autoescape=True, ...) - - pattern-not: jinja2.Environment(..., autoescape=jinja2.select_autoescape(...),...) - - pattern-not: jinja2.Environment(..., autoescape=select_autoescape(...), ...) - - pattern: jinja2.Environment(...) - severity: WARNING - - id: python_escaping_rule-use-of-mako-templates + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/Command_Injection + subcategory: + - audit + technology: + - flask + pattern-either: + - patterns: + - pattern: os.system(...) + - pattern-either: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + os.system(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + $INTERM = <... $ROUTEVAR ...> + ... + os.system(..., <... $INTERM ...>, ...) + - pattern: os.system(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: os.system(..., <... flask.request.$W[...] ...>, ...) + - pattern: os.system(..., <... flask.request.$W(...) ...>, ...) + - pattern: os.system(..., <... flask.request.$W ...>, ...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + os.system(<... $INTERM ...>) + - pattern: os.system(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + os.system(<... $INTERM ...>) + - pattern: os.system(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + os.system(<... $INTERM ...>) + - pattern: os.system(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + os.system(<... $INTERM ...>) + - pattern: os.system(...) + severity: ERROR + - id: python.flask.security.injection.path-traversal-open.path-traversal-open languages: - python - message: "The application was found using mako templates without `default_filters`\nbeing passed to the `Template` or `TemplateLookup` constructors. If using \nin the context of HTML, this could lead to Cross-Site Scripting (XSS) attacks \nwhen rendering with user-supplied input.\n\nUnfortunately, Jinja2 does not support context-aware escaping, meaning it\nis insufficient to protect against XSS for the various web contexts. It is \nimportant to encode the data depending on the specific context it is used in. \nThere are at least six context types:\n\n- Inside HTML tags `
    context 1
    `\n- Inside attributes: `
    `\n- Inside event attributes ``\n- Inside script blocks: ``\n- Unsafe element HTML assignment: `element.innerHTML = \"context 5\"`\n- Inside URLs: \n`link`\n\nScript blocks alone have multiple ways they need to be encoded. Extra care\nmust be taken if user input is ever output inside of script tags.\n\nUser input that is displayed within the application must be encoded,\nsanitized or validated to ensure it cannot be treated as HTML or executed \nas Javascript code. Care must also be taken to not mix server-side templating \nwith client-side templating, as the server-side templating will not encode things \nlike {{ 7*7 }} which may execute client-side templating features.\n\nIt is _NOT_ advised to encode user input prior to inserting into a data\nstore. The data will need to be encoded depending on context of where it is output. \nIt is much safer to force the displaying system to handle the encoding and \nnot attempt to guess how it should be encoded.\n\nTo handle different contexts, one approach would be to write custom mako\nfilters. Below is an example that escapes or encodes links and \npotentially malicious script, note this does not include other contexts \nsuch as CSS or attributes:\n```\n# filters.py module:\n\ndef escape_link(value):\n bad_link = \"#JinjatmplZ\"\n # Block any values that start with // as that could be used to inject\n # links to third party pages see:\nhttps://en.wikipedia.org/wiki/Wikipedia:Protocol-relative_URL\n if value.startswith('//'):\n return bad_link\n\n # Only allow relative links\n # if you want to allow links that start with http or ws replace with below:\n # if not value.startswith('/'): and not value.startswith('http') and not\nvalue.startswith('ws')\n if not value.startswith('/'):\n return bad_link\n\n return value\n\n# Create a replacement table\njs_replacement = str.maketrans({\n '\\0': \"\\\\u0000\",\n '\\t': \"\\\\t\",\n '\\n': \"\\\\n\",\n '\\v': \"\\\\u000b\",\n '\\f': \"\\\\f`\",\n '\\r': \"\\\\r\",\n '\"': \"\\\\u0022\",\n '`': \"\\\\u0060\",\n '&': \"\\\\u0026\",\n '\\'': \"\\\\u0027\",\n '+': \"\\\\u002b\",\n '/': \"\\\\/\",\n '<': \"\\\\u003c\",\n '>': \"\\\\u003e\",\n '\\\\': \"\\\\\\\\\",\n '(': \"\\\\u0028\",\n ')': \"\\\\u0029\",\n})\n\ndef escape_js(value):\n # Escape the input for use in \n\n\n\"\"\"\n\n# Load our template with default filters and our imported filters for\n# usage in template files\nt = Template(template_text,\n # By default enable the html filter with 'h'\n default_filters=['h'],\n # Import our custom filters\n imports=[\"from filters import escape_link, escape_js\"])\n\n# Render our template\nprint(t.render(html_context=\"\",\n link_context=\"/# onclick=alert(1)\",\n script_context=\"alert(1)\",)\n)\n```\n" + message: Found request data in a call to 'open'. Ensure the request data is validated or sanitized, otherwise it could result in path traversal attacks. metadata: category: security - cwe: CWE-79 + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - patterns: - - pattern-either: - - pattern: mako.template.Template(...) - - pattern: mako.lookup.TemplateLookup(...) - - pattern-not: mako.lookup.TemplateLookup(..., default_filters=["..."]) - - pattern-not: mako.template.Template(..., default_filters=["..."]) - severity: WARNING - - id: python_exec_rule-exec-used + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + subcategory: + - audit + technology: + - flask + pattern-either: + - patterns: + - pattern: open(...) + - pattern-either: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + open(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + with open(..., <... $ROUTEVAR ...>, ...) as $FD: + ... + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + $INTERM = <... $ROUTEVAR ...> + ... + open(..., <... $INTERM ...>, ...) + - pattern: open(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: open(..., <... flask.request.$W[...] ...>, ...) + - pattern: open(..., <... flask.request.$W(...) ...>, ...) + - pattern: open(..., <... flask.request.$W ...>, ...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + open(<... $INTERM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + open(<... $INTERM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + open(<... $INTERM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + open(<... $INTERM ...>, ...) + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + with open(<... $INTERM ...>, ...) as $F: + ... + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + with open(<... $INTERM ...>, ...) as $F: + ... + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + with open(<... $INTERM ...>, ...) as $F: + ... + - pattern: open(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + with open(<... $INTERM ...>, ...) as $F: + ... + - pattern: open(...) + severity: ERROR + - id: python.flask.security.injection.raw-html-concat.raw-html-format languages: - python - message: "The application was found calling the `exec` function with a non-literal variable. If the\nvariable comes from user-supplied input, an adversary could compromise the entire system by\nexecuting arbitrary python code.\n\nTo remediate this issue, remove all calls to `exec` and consider alternative methods for\nexecuting the necessary business logic. There is almost no safe method of calling `eval` \nwith user-supplied input.\n\nIf the application only needs to convert strings into objects, consider using `json.loads`.\nIn some cases `ast.literal_eval` is recommended, but this should be avoided as it can still\nsuffer from other issues such as the ability for malicious code to crash the python\ninterpreter or application.\n\nExample using `json.loads`` to load in arbitrary data to create data structures:\n```\n# User supplied data as a blob of JSON\nuser_supplied_data = \"\"\"{\"user\": \"test\", \"metadata\": [1,2,3]}\"\"\"\n# Load the JSON\nuser_object = json.loads(user_supplied_data)\n# Manually add protected properties _after_ loading, never before\nuser_object[\"is_admin\"] = False\n# Work with the object\n```\n" + message: Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. Otherwise, use templates (`flask.render_template`) which will safely render HTML instead. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') - patterns: - - pattern: exec(...) - - pattern-not: exec("...") + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://flask.palletsprojects.com/en/2.0.x/security/#cross-site-scripting-xss + subcategory: + - vuln + technology: + - flask + mode: taint + pattern-sanitizers: + - pattern: jinja2.escape(...) + - pattern: flask.escape(...) + - pattern: flask.render_template("~=/.*\.html", ...) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: '"$HTMLSTR" % ...' + - pattern: '"$HTMLSTR".format(...)' + - pattern: '"$HTMLSTR" + ...' + - pattern: f"$HTMLSTR{...}..." + - patterns: + - pattern-inside: | + $HTML = "$HTMLSTR" + ... + - pattern-either: + - pattern: $HTML % ... + - pattern: $HTML.format(...) + - pattern: $HTML + ... + - metavariable-pattern: + language: generic + metavariable: $HTMLSTR + pattern: <$TAG ... + pattern-sources: + - patterns: + - pattern-either: + - pattern: flask.request.$ANYTHING + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR severity: WARNING - - id: python_exec_rule-os-path + - id: python.flask.security.injection.ssrf-requests.ssrf-requests languages: - python - message: | - Starting a process with a shell; seems safe, but may be changed in the future, consider - rewriting without shell + message: Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF). To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery + subcategory: + - vuln + technology: + - flask pattern-either: - - pattern: os.system("...", ...) - - pattern: $OS.popen("...", ...) - - pattern: $OS.popen2("...", ...) - - pattern: $OS.popen3("...", ...) - - pattern: $OS.popen4("...", ...) - - pattern: commands.getoutput("...", ...) - - pattern: commands.getstatusoutput("...", ...) - severity: INFO - - id: python_exec_rule-os-popen2 + - patterns: + - pattern: requests.$FUNC(...) + - pattern-either: + - pattern-inside: | + @$APP.$ROUTE_METHOD($ROUTE, ...) + def $ROUTE_FUNC(..., $ROUTEVAR, ...): + ... + requests.$FUNC(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.$ROUTE_METHOD($ROUTE, ...) + def $ROUTE_FUNC(..., $ROUTEVAR, ...): + ... + $INTERM = <... $ROUTEVAR ...> + ... + requests.$FUNC(..., <... $INTERM ...>, ...) + - metavariable-regex: + metavariable: $ROUTE_METHOD + regex: ^(route|get|post|put|delete|patch)$ + - pattern: requests.$FUNC(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: requests.$FUNC(..., <... flask.request.$W[...] ...>, ...) + - pattern: requests.$FUNC(..., <... flask.request.$W(...) ...>, ...) + - pattern: requests.$FUNC(..., <... flask.request.$W ...>, ...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + requests.$FUNC(<... $INTERM ...>, ...) + - pattern: requests.$FUNC(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + requests.$FUNC(<... $INTERM ...>, ...) + - pattern: requests.$FUNC(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + requests.$FUNC(<... $INTERM ...>, ...) + - pattern: requests.$FUNC(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + requests.$FUNC(<... $INTERM ...>, ...) + - pattern: requests.$FUNC(...) + severity: ERROR + - id: python.flask.security.injection.subprocess-injection.subprocess-injection languages: - python - message: | - Starting a process with a shell; seems safe, but may be changed in the future, consider - rewriting without shell + message: Detected user input entering a `subprocess` call unsafely. This could result in a command injection vulnerability. An attacker could use this vulnerability to execute arbitrary commands on the host, which allows them to download malware, scan sensitive data, or run any command they wish on the server. Do not let users choose the command to run. In general, prefer to use Python API versions of system commands. If you must use subprocess, use a dictionary to allowlist a set of commands. metadata: category: security - cwe: CWE-78 + confidence: HIGH + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') - patterns: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - flask + mode: taint + options: + symbolic_propagation: true + pattern-sanitizers: + - patterns: + - pattern: $DICT[$KEY] + - focus-metavariable: $KEY + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: subprocess.$FUNC(...) + - pattern-not: subprocess.$FUNC("...", ...) + - pattern-not: subprocess.$FUNC(["...", ...], ...) + - pattern-not-inside: | + $CMD = ["...", ...] + ... + subprocess.$FUNC($CMD, ...) + - patterns: + - pattern: subprocess.$FUNC(["$SHELL", "-c", ...], ...) + - metavariable-regex: + metavariable: $SHELL + regex: ^(sh|bash|ksh|csh|tcsh|zsh)$ + - patterns: + - pattern: subprocess.$FUNC(["$INTERPRETER", ...], ...) + - metavariable-regex: + metavariable: $INTERPRETER + regex: ^(python|python\d)$ + pattern-sources: - pattern-either: - - pattern: os.system(...) - - pattern: os.popen(...) - - pattern: os.popen2(...) - - pattern: os.popen3(...) - - pattern: os.popen4(...) - - pattern: popen2.popen2(...) - - pattern: popen2.popen3(...) - - pattern: popen2.popen4(...) - - pattern: popen2.Popen3(...) - - pattern: popen2.Popen4(...) - - pattern: commands.getoutput(...) - - pattern: commands.getstatusoutput("") - severity: INFO - - id: python_exec_rule-start-process-with-no-shell + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + severity: ERROR + - id: python.flask.security.injection.tainted-sql-string.tainted-sql-string languages: - python - message: | - Found dynamic content when spawning a process. This is dangerous if externaldata can reach this - function call because it allows a malicious actor toexecute commands. Ensure no external data - reaches here. + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as SQLAlchemy which will protect your queries. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-704: Incorrect Type Conversion or Cast' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') - patterns: - - pattern-either: - - patterns: - - pattern-not: os.$W("...", ...) - - pattern-either: - - pattern: os.execl(...) - - pattern: os.execle(...) - - pattern: os.execlp(...) - - pattern: os.execlpe(...) - - pattern: os.execv(...) - - pattern: os.execve(...) - - pattern: os.execvp(...) - - pattern: os.execvpe(...) - - pattern: os.startfile(...) - - patterns: - - pattern-either: - - pattern: os.spawnl(...) - - pattern: os.spawnle(...) - - pattern: os.spawnlp(...) - - pattern: os.spawnlpe(...) - - pattern: os.spawnv(...) - - pattern: os.spawnve(...) - - pattern: os.spawnvp(...) - - pattern: os.spawnvpe(...) - severity: WARNING - - id: python_exec_rule-subprocess-call + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql + - https://www.tutorialspoint.com/sqlalchemy/sqlalchemy_quick_guide.htm + - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-more-specific-text-with-table-expression-literal-column-and-expression-column + subcategory: + - vuln + technology: + - sqlalchemy + - flask + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR" % ... + - pattern: | + "$SQLSTR".format(...) + - pattern: | + f"$SQLSTR{...}..." + - metavariable-regex: + metavariable: $SQLSTR + regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.* + pattern-sources: + - patterns: + - pattern-either: + - pattern: flask.request.$ANYTHING + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR + severity: ERROR + - id: python.flask.security.injection.tainted-url-host.tainted-url-host languages: - python - message: | - Python possesses many mechanisms to invoke an external executable. However, - doing so may present a security issue if appropriate care is not taken to - sanitize any user provided or variable input. This plugin test is part of a - family of tests built to check for process spawning and warn appropriately. - Specifically, this test looks for the spawning of a subprocess without the - use of a command shell. This type of subprocess invocation is not - vulnerable to shell injection attacks, but care should still be taken to - ensure validity of input. + message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') - patterns: - - pattern-not: subprocess.$FUNC($ARG, shell=<... True ...>) - - pattern-not: subprocess.$FUNC($ARG, shell=<... 'True' ...>) - - pattern-not: subprocess.$FUNC($ARG, shell=<... "True" ...>) - - pattern-either: - - pattern: | - subprocess.$FUNC($ARG, shell=False) - - pattern: | - subprocess.$FUNC($ARG, shell=0) - - pattern: | - subprocess.$FUNC($ARG, shell={...}) - - pattern: | - subprocess.$FUNC($ARG, shell=[...]) - - pattern: | - subprocess.$FUNC($ARG) + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - flask + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: '"$URLSTR" % ...' + - metavariable-pattern: + language: generic + metavariable: $URLSTR + patterns: + - pattern-either: + - pattern: $SCHEME://%s + - pattern: $SCHEME://%r + - patterns: + - pattern: '"$URLSTR".format(...)' + - metavariable-pattern: + language: generic + metavariable: $URLSTR + pattern: $SCHEME:// { ... } + - patterns: + - pattern: '"$URLSTR" + ...' + - metavariable-regex: + metavariable: $URLSTR + regex: .*://$ + - patterns: + - pattern: f"$URLSTR{...}..." + - metavariable-regex: + metavariable: $URLSTR + regex: .*://$ + - patterns: + - pattern-inside: | + $URL = "$URLSTR" + ... + - pattern: $URL += ... + - metavariable-regex: + metavariable: $URLSTR + regex: .*://$ + pattern-sources: + - patterns: + - pattern-either: + - pattern: flask.request.$ANYTHING + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR severity: WARNING - - id: python_exec_rule-subprocess-popen-shell-true + - id: python.flask.security.injection.user-eval.eval-injection languages: - python - message: | - Found `subprocess` function `$FUNC` with `shell=True`. This is dangerous because this call will - spawn the command using a shell process. Doing so propagates current shell settings and - variables, - which makes it much easier for a malicious actor to execute commands. Use `shell=False` - instead. + message: Detected user data flowing into eval. This is code injection and should be avoided. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') - patterns: + - A03:2021 - Injection + references: + - https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html + subcategory: + - vuln + technology: + - flask + pattern-either: - patterns: - - pattern-not-inside: | + - pattern: eval(...) + - pattern-either: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + eval(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + $INTERM = <... $ROUTEVAR ...> + ... + eval(..., <... $INTERM ...>, ...) + - pattern: eval(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: eval(..., <... flask.request.$W[...] ...>, ...) + - pattern: eval(..., <... flask.request.$W(...) ...>, ...) + - pattern: eval(..., <... flask.request.$W ...>, ...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> ... - $ARG = '...'.format('...') + eval(..., <... $INTERM ...>, ...) + - pattern: eval(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> ... - - pattern: subprocess.$FUNC($ARG, ...) - - pattern-not: subprocess.$FUNC('...', ...) - - pattern-not: subprocess.$FUNC('...' % '...', ...) - - pattern-not: subprocess.$FUNC('...'.format('...'), ...) - - pattern-either: - - pattern: subprocess.$FUNC(..., shell=True, ...) - - pattern: subprocess.$FUNC(..., shell=[$V, ...], ...) - - pattern: 'subprocess.$FUNC(..., shell={$K: $V, ...}, ...)' - - patterns: - - pattern: subprocess.$FUNC(..., shell=$INTVAL, ...) - - pattern-not: subprocess.$FUNC(..., shell=0, ...) - - metavariable-regex: - metavariable: $INTVAL - regex: ^[0-9]+$ - - patterns: - - pattern: subprocess.$FUNC(..., shell='$STRVAL', ...) - - pattern-not: subprocess.$FUNC(..., shell='', ...) + eval(..., <... $INTERM ...>, ...) + - pattern: eval(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + eval(..., <... $INTERM ...>, ...) + - pattern: eval(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + eval(..., <... $INTERM ...>, ...) + - pattern: eval(...) severity: ERROR - - id: python_exec_rule-subprocess-shell-TRUE + - id: python.flask.security.injection.user-exec.exec-injection languages: - python - message: | - subprocess call - check for execution of untrusted input + message: Detected user data flowing into exec. This is code injection and should be avoided. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') - patterns: - - pattern-not: subprocess.$FUNC(..., shell=True, ...) - - pattern: $FOO(..., shell=True, ...) - severity: WARNING - - id: python_file-permissions_rule-general-bad-permission + - A03:2021 - Injection + references: + - https://nedbatchelder.com/blog/201206/exec_really_is_dangerous.html + subcategory: + - vuln + technology: + - flask + pattern-either: + - patterns: + - pattern: exec(...) + - pattern-either: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + exec(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + $INTERM = <... $ROUTEVAR ...> + ... + exec(..., <... $INTERM ...>, ...) + - pattern: exec(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: exec(..., <... flask.request.$W[...] ...>, ...) + - pattern: exec(..., <... flask.request.$W(...) ...>, ...) + - pattern: exec(..., <... flask.request.$W ...>, ...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W.get(...) ...> + ... + exec(..., <... $INTERM ...>, ...) + - pattern: exec(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W[...] ...> + ... + exec(..., <... $INTERM ...>, ...) + - pattern: exec(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W(...) ...> + ... + exec(..., <... $INTERM ...>, ...) + - pattern: exec(...) + - patterns: + - pattern-inside: | + $INTERM = <... flask.request.$W ...> + ... + exec(..., <... $INTERM ...>, ...) + - pattern: exec(...) + severity: ERROR + - fix: | + True + id: python.jinja2.security.audit.autoescape-disabled-false.incorrect-autoescape-disabled languages: - python - message: | - The application was found setting file permissions to overly permissive values. Consider - using the following values if the application user is the only process to access - the file: - - - 0400 - read only access to the file - - 0200 - write only access to the file - - 0600 - read/write access to the file - - Example creating a file with read/write permissions for the application user: - ``` - # Use octal values to set 0o600 (read/write access to the file) for the current - # user - os.chmod('somefile.txt', 0o600) - ``` - - For all other values please see: - https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation + message: Detected a Jinja2 environment with 'autoescaping' disabled. This is dangerous if you are rendering to a browser because this allows for cross-site scripting (XSS) attacks. If you are in a web context, enable 'autoescaping' by setting 'autoescape=True.' You may also consider using 'jinja2.select_autoescape()' to only enable automatic escaping for certain file extensions. metadata: category: security - cwe: CWE-732 + confidence: MEDIUM + cwe: + - 'CWE-116: Improper Encoding or Escaping of Output' + impact: MEDIUM + likelihood: LOW owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Incorrect permission assignment for critical resource + - A03:2021 - Injection + references: + - https://jinja.palletsprojects.com/en/2.11.x/api/#basics + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html + subcategory: + - vuln + technology: + - jinja2 patterns: - - pattern: os.chmod(...,$MASK) - - metavariable-regex: - metavariable: $MASK - regex: (0x..f|0o..[2,3,7]|stat.S_IXGRP|stat.S_IWOTH) + - pattern: jinja2.Environment(... , autoescape=$VAL, ...) + - pattern-not: jinja2.Environment(... , autoescape=True, ...) + - pattern-not: jinja2.Environment(... , autoescape=jinja2.select_autoescape(...), ...) + - focus-metavariable: $VAL severity: WARNING - - id: python_files_rule-tarfile-unsafe-members + - fix-regex: + regex: (.*)\) + replacement: \1, autoescape=True) + id: python.jinja2.security.audit.missing-autoescape-disabled.missing-autoescape-disabled languages: - python - message: | - The application may be vulnerable to a path traversal if it extracts untrusted archive files. - This vulnerability is colloquially known as 'Zip Slip'. Archive files may contain folders - which, - when extracted, may write outside of the intended directory. This is exploited by including - path traversal characters such as `../../other/directory` to overwrite or place files in system - or application directories. - - Extra care must be taken when extracting archive files as there are numerous concerns: - - - If possible, generate unique filenames instead of using the archives file names, as it may be - possible for users to overwrite files if the filenames are the same. - - Validate file paths are written with a prefixed, known trusted directory. - - Only process regular files and not symbolic links, as some applications may attempt to - read/follow - the symbolic link, leading to arbitrary file read / write vulnerabilities. - - Example of securely processing an archive file: - ``` - import tarfile - import uuid - # import os - - tar = tarfile.open('some.tar') - - # Max number of allowed files in our archive - max_files = 10 - # Max size for all files in archive - max_size = 1024 * 1024 * 10 # 10MB - # Max size per file in archive - max_file_size = 1024 * 1024 # 1MB - - # Validate number of files in archive - if len(tar.getmembers()) > max_files: - raise Exception("Too many files in archive") - - total_size = 0 - # Loop over all files to see if we exceed max size - # if so, do not process any of them. - for f in tar.getmembers(): - total_size += f.size - if total_size >= max_size: - raise Exception("Archive files exceeded max file size") - - # Iterate over files now that we know the total size is within limits - for f in tar.getmembers(): - # Internally this calls TarInfo.isreg() which ensures - # the file is a regular file and not a sym link or directory - if not f.isfile(): - continue - - # Optional, set a limit on each file size - if f.size > max_file_size: - raise Exception(f"File {f.name} too large: {f.size}") - - # If original names are required, ensure that only the - # filename is used: - # filename = os.path.basename(f.name) - - # More secure, generate a UUID4 value instead - filename = uuid.uuid4().hex - - # Reset the archive filename to the basename - # Newer versions of python (3.11.4+) should use: - # new_tar = old_tar.replace(name=...new name...) - f.name = filename - - # Extract the file into a restricted directory, with our - # own user's attributes, not the file from the archive - tar.extract(f, '/opt/app/restricted/', set_attrs=False) - ``` - - For more information on tarfile see: - - https://docs.python.org/3/library/tarfile.html + message: Detected a Jinja2 environment without autoescaping. Jinja2 does not autoescape by default. This is dangerous if you are rendering to a browser because this allows for cross-site scripting (XSS) attacks. If you are in a web context, enable autoescaping by setting 'autoescape=True.' You may also consider using 'jinja2.select_autoescape()' to only enable automatic escaping for certain file extensions. metadata: category: security - cwe: CWE-22 + confidence: MEDIUM + cwe: + - 'CWE-116: Improper Encoding or Escaping of Output' + impact: MEDIUM + likelihood: LOW owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + - A03:2021 - Injection + references: + - https://jinja.palletsprojects.com/en/2.11.x/api/#basics + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html + subcategory: + - vuln + technology: + - jinja2 patterns: - - pattern-inside: | - import tarfile - ... - - pattern-either: - - patterns: - - pattern-inside: | - $TAR = tarfile.open(...) - ... - - pattern-either: - - pattern: $TAR.extractall(...) - - pattern: tarfile.extractall(..., members=$TAR) - - pattern: $TAR.extractall(..., members=[]) - - patterns: - - pattern: tarfile.extractall(...) - - pattern: tarfile.extractall(..., members=[]) + - pattern-not: jinja2.Environment(..., autoescape=$VAL, ...) + - pattern: jinja2.Environment(...) severity: WARNING - - id: python_flask_rule-app-debug + - id: python.jwt.security.jwt-hardcode.jwt-python-hardcoded-secret languages: - python - message: | - The Flask application is running with `debug=True` configured. By enabling this option, certain - exceptions or errors could cause sensitive information to be leaked in HTTP responses. - - Additionally, it is not recommended to run a Flask application using `Flask.run(...)` in - production. Instead, a WSGI server such as - [gunicorn](https://flask.palletsprojects.com/en/2.3.x/deploying/gunicorn/) - or [waitress](https://flask.palletsprojects.com/en/2.3.x/deploying/waitress/) be used instead. - - For more information on deployment options for Flask applications see: - - https://flask.palletsprojects.com/en/2.3.x/deploying/ + message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' metadata: category: security - cwe: CWE-489 + confidence: HIGH + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Medium - shortDescription: Active debug code + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - vuln + technology: + - jwt patterns: - - pattern-inside: | - import flask - ... - - pattern: $APP.run(..., debug=True, ...) - severity: WARNING - - id: python_ftp_rule-ftplib + - pattern: | + jwt.encode($X, $SECRET, ...) + - focus-metavariable: $SECRET + - pattern: | + "..." + severity: ERROR + - id: python.jwt.security.jwt-none-alg.jwt-python-none-alg languages: - python - message: | - The application was found using an FTP library. As FTP does not provide encryption, it is - strongly recommended that any file transfers be done over a more secure transport such as - SSH. - - The [paramiko](https://www.paramiko.org/) library can be used with an SCP module to allow - secure file transfers. - - Example using `paramiko` SSH client and the `scp` module: - ``` - import paramiko - import scp - - # Create an SSH client - with paramiko.SSHClient() as ssh: - # Load the system host keys so we can confirm the - # host we are connecting to is legitimate - ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts') - - # Connect to the remote host using our SSH private key - ssh.connect(hostname='example.org', - port=22, - username='appuser', - key_filename='/home/appuser/.ssh/private_key') - - # Create an SCP client with the ssh transport and copy files - with scp.SCPClient(ssh.get_transport()) as secure_copy: - secure_copy.get('remote/test.file', 'local/test.file') - secure_copy.put('local/some.file', 'remote/some.file') - ``` - - For more information on the paramiko module see: - - https://www.paramiko.org/ - - For more information on the scp module see: - - https://github.com/jbardin/scp.py + message: Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'. metadata: category: security - cwe: CWE-319 + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Cleartext transmission of sensitive information - pattern: ftplib.$ANYTHING(...) - severity: WARNING - - id: python_log_rule-logging-config-insecure-listen + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - vuln + technology: + - jwt + pattern-either: + - pattern: | + jwt.encode(...,algorithm="none",...) + - pattern: jwt.decode(...,algorithms=[...,"none",...],...) + severity: ERROR + - fix: | + True + id: python.jwt.security.unverified-jwt-decode.unverified-jwt-decode languages: - python - message: | - The application was found calling the `logging.config.listen`` function, which provides the - ability to listen for - external configuration files over a socket server. This listen socket parses part of the - configuration and calls - `eval` on the supplied configuration file. A local user, or an adversary who is able to - exploit - a Server Side Request Forgery (SSRF) attack to communicate over localhost, would be able to - execute arbitrary - code by passing in a logging config that contains python code. - - To remediate the issue, remove the call to `logging.config.listen` method. - - For more information on the listen functionality see: - - https://docs.python.org/3/library/logging.config.html#logging.config.listen + message: Detected JWT token decoded with 'verify=False'. This bypasses any integrity checks for the token which means the token could be tampered with by malicious actors. Ensure that the JWT token is verified. metadata: category: security - cwe: CWE-94 + confidence: MEDIUM + cwe: + - 'CWE-287: Improper Authentication' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper control of generation of code ('Code Injection') + - A02:2017 - Broken Authentication + - A07:2021 - Identification and Authentication Failures + references: + - https://github.com/we45/Vulnerable-Flask-App/blob/752ee16087c0bfb79073f68802d907569a1f0df7/app/app.py#L96 + subcategory: + - audit + technology: + - jwt patterns: - - pattern: logging.config.listen(...) - severity: WARNING - - id: python_random_rule-random - languages: - - python - message: | - Depending on the context, generating weak random numbers may expose cryptographic functions, - which rely on these numbers, to be exploitable. When generating numbers for sensitive values - such as tokens, nonces, and cryptographic keys, it is recommended that the `secrets` module - be used instead. - - Example using the secrets module: - ``` - import secrets - - # Generate a secure random 64 byte array - random_bytes = secrets.token_bytes(64) - print(random_bytes) - - # Generate a secure random 64 byte array as a hex string - random_bytes_hex = secrets.token_hex(64) - - # Generate a secure random 64 byte array base64 encoded for use in URLs - random_string = secrets.token_urlsafe(64) - ``` - - For more information on the `secrets` module see: - - https://docs.python.org/3/library/secrets.html - metadata: - category: security - cwe: CWE-338 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Low - shortDescription: Use of cryptographically weak pseudo-random number generator (PRNG) - pattern-either: - - pattern: random.random(...) - - pattern: random.randrange(...) - - pattern: random.randint(...) - - pattern: random.choice(...) - - pattern: random.uniform(...) - - pattern: random.triangular(...) - severity: WARNING - - id: python_requests_rule-request-without-timeout + - pattern-either: + - patterns: + - pattern: | + jwt.decode(..., options={..., "verify_signature": $BOOL, ...}, ...) + - metavariable-pattern: + metavariable: $BOOL + pattern: | + False + - focus-metavariable: $BOOL + - patterns: + - pattern: | + $OPTS = {..., "verify_signature": $BOOL, ...} + ... + jwt.decode(..., options=$OPTS, ...) + - metavariable-pattern: + metavariable: $BOOL + pattern: | + False + - focus-metavariable: $BOOL + severity: ERROR + - id: python.lang.security.audit.dangerous-asyncio-exec-tainted-env-args.dangerous-asyncio-exec-tainted-env-args languages: - python - message: | - The application was found using the `requests` module without configuring a timeout value for - connections. This could lead to uncontrolled resource consumption where the application could - run out of - socket descriptors, effectively causing a Denial of Service (DoS). - - To remediate this issue, pass in a `timeout=` argument to each `requests` call. - - Example using a timeout for an HTTP GET request: - ``` - # Issue a GET request to https://example.com with a timeout of 10 seconds - response = requests.get('https://example.com', timeout=10) - # Work with the response object - # ... - ``` - - For more information on using the requests module see: - - https://requests.readthedocs.io/en/latest/api/ + message: Detected subprocess function '$LOOP.subprocess_exec' with user controlled data. You may consider using 'shlex.escape()'. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - cwe: CWE-770 + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Medium - shortDescription: Allocation of resources without limits or throttling - patterns: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: - pattern-either: - patterns: - - pattern: requests.$METHOD(..., timeout=$VAL, ...) - - metavariable-comparison: - comparison: $VAL <= 0 - metavariable: $VAL + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "...", ...) + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["...",...], ...) + - pattern: $LOOP.subprocess_exec(...) - patterns: - - pattern: requests.$METHOD(..., timeout=$VAL, ...) - - metavariable-regex: - metavariable: $VAL - regex: (^None) + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...) + - pattern: $LOOP.subprocess_exec($PROTOCOL, "=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c",...) - patterns: - - pattern-not: requests.$METHOD(..., timeout=$VAL, ...) - - pattern-either: - - pattern: requests.$METHOD(..., ...) - - pattern: requests.$METHOD(...) - - metavariable-regex: - metavariable: $METHOD - regex: (get|put|delete|post|options|head|patch) - severity: WARNING - - id: python_snmp_rule-insecure-snmp-version + - pattern-not: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", "...", ...], ...) + - pattern: $LOOP.subprocess_exec($PROTOCOL, ["=~/(sh|bash|ksh|csh|tcsh|zsh)/", "-c", ...], ...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.audit.dangerous-asyncio-shell-tainted-env-args.dangerous-asyncio-shell-tainted-env-args languages: - python - message: | - Pysnmp was detected using versions SNMPv1 or SNMPv2. SNPMv1 and SNMPv2 are insecure - and should no longer be used as they do not offer encryption. - - If possible, query SNMP devices using SNMPv3 instead. - - Example querying a device using SNMPv3 with SHA-AES: - ``` - from pysnmp.hlapi import * - # Create the snpm iterator - iterator = getCmd( - SnmpEngine(), - # Configure using SHA AES - UsmUserData('usr-sha-aes', 'authkey1', 'privkey1', - authProtocol=USM_AUTH_HMAC96_SHA, - privProtocol=USM_PRIV_CFB128_AES), - UdpTransportTarget(('demo.snmplabs.com', 161)), - ContextData(), - ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)) - ) - ``` - - For more information on using SNMPv3 with `Pysnmp` see: - - https://pysnmp.readthedocs.io/en/latest/examples/hlapi/v3arch/asyncore/sync/manager/cmdgen/snmp-versions.html#snmpv3-auth-sha-privacy-aes128 + message: Detected asyncio subprocess function with user controlled data. You may consider using 'shlex.escape()'. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - cwe: CWE-319 + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Cleartext transmission of sensitive information - pattern-either: - - pattern: pysnmp.hlapi.CommunityData(..., mpModel=0, ...) - - pattern: pysnmp.hlapi.CommunityData(..., mpModel=1, ...) - severity: WARNING - - id: python_snmp_rule-snmp-weak-cryptography + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.python.org/3/library/asyncio-subprocess.html + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: $LOOP.subprocess_shell($PROTOCOL, $CMD) + - pattern-inside: asyncio.subprocess.create_subprocess_shell($CMD, ...) + - pattern-inside: asyncio.create_subprocess_shell($CMD, ...) + - focus-metavariable: $CMD + - pattern-not-inside: | + $CMD = "..." + ... + - pattern-not: $LOOP.subprocess_shell($PROTOCOL, "...") + - pattern-not: asyncio.subprocess.create_subprocess_shell("...", ...) + - pattern-not: asyncio.create_subprocess_shell("...", ...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.audit.dangerous-code-run-tainted-env-args.dangerous-interactive-code-run-tainted-env-args languages: - python - message: "Pysnmp was detected using SNMPv3 without authentication or encryption\nprotections enabled.\n\n- Use of `usmNoAuthProtocol` or `usmNoPrivProtocol` indicates that\neither authentication or privacy, respectively, is not being used. \n- The absence of `authKey` (or `authKey=None`) implies no authentication, \nwhich is equivalent to using `usmNoAuthProtocol`. \n- The absence of `privKey` (or `privKey=None`) implies no privacy (encryption), \nwhich is equivalent to using `usmNoPrivProtocol`.\n\nTo enhance the security of your SNMP communications, it is recommended to use both\nauthentication and privacy features in SNMPv3:\n\n- Use SHA for Authentication: SHA (Secure Hash Algorithm) is a more secure option \nfor SNMP message authentication. To use SHA, set the `authProtocol` to \n`usmHMACSHAAuthProtocol` and provide a strong `authKey`.\n- Use AES for Privacy: AES (Advanced Encryption Standard) is recommended for \nencrypting SNMP messages. Set the `privProtocol` to `usmAesCfb128Protocol`\nor a similar AES-based protocol and specify a strong `privKey`.\n\nExample of secure `UsmUserData` configuration:\n``` \n from pysnmp.hlapi import UsmUserData, usmHMACSHAAuthProtocol, usmAesCfb128Protocol\n \n user_data = UsmUserData('username','authKey', 'privKey', \n authProtocol=usmHMACSHAAuthProtocol,\n privProtocol=usmAesCfb128Protocol)\n```\n" + message: Found user controlled data inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. metadata: category: security - cwe: CWE-319 + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Cleartext transmission of sensitive information - pattern-either: - - pattern-regex: UsmUserData(.*usmNoAuthProtocol.*) - - pattern-regex: UsmUserData(.*usmNoPrivProtocol.*) - - pattern: | - UsmUserData(..., authKey=None, ...) - - pattern: | - UsmUserData(..., privKey=None, ...) - - pattern: | - UsmUserData(..., authProtocol=(1,3,6,1,6,3,10,1,1,1), ...) - - pattern: | - UsmUserData(..., privProtocol=(1,3,6,1,6,3,10,1,2,1), ...) + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: - patterns: + - pattern-either: + - pattern-inside: | + $X = code.InteractiveConsole(...) + ... + - pattern-inside: | + $X = code.InteractiveInterpreter(...) + ... + - pattern-either: + - pattern-inside: | + $X.push($PAYLOAD,...) + - pattern-inside: | + $X.runsource($PAYLOAD,...) + - pattern-inside: | + $X.runcode(code.compile_command($PAYLOAD),...) + - pattern-inside: | + $PL = code.compile_command($PAYLOAD,...) + ... + $X.runcode($PL,...) + - pattern: $PAYLOAD - pattern-not: | - UsmUserData($NAME,$AUTHKEY,"...", ...) + $X.push("...",...) - pattern-not: | - UsmUserData(..., privKey=$PRIVKEY, ...) + $X.runsource("...",...) - pattern-not: | - UsmUserData(..., privProtocol=$PRIVPROT, ...) - - pattern: | - UsmUserData(...) + $X.runcode(code.compile_command("..."),...) + - pattern-not: | + $PL = code.compile_command("...",...) + ... + $X.runcode($PL,...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS severity: WARNING - - id: python_sql_rule-hardcoded-sql-expression + - id: python.lang.security.audit.dangerous-os-exec-tainted-env-args.dangerous-os-exec-tainted-env-args languages: - python - message: | - SQL Injection is a critical vulnerability that can lead to data or system compromise. By - dynamically generating SQL query strings, user input may be able to influence the logic of - the SQL statement. This could lead to an adversary accessing information they should - not have access to, or in some circumstances, being able to execute OS functionality or code. - - Replace all dynamically generated SQL queries with parameterized queries. In situations where - dynamic queries must be created, never use direct user input, but instead use a map or - dictionary of valid values and resolve them using a user supplied key. - - For example, some database drivers do not allow parameterized queries for `>` or `<` comparison - operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the - user - supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` - values to be used in the construction of the dynamic query. The same goes for other queries - where - column or table names are required but cannot be parameterized. - - Example using `PreparedStatement` queries: - ``` - import sqlite3 - - # Create a new database (in memory) - con = sqlite3.connect(":memory:") - # Get a cursor from the connection - cur = con.cursor() - # Create a tuple of the value to be used in the parameterized query - params = ('user-input',) - # execute the statement, passing in the params for the value - cur.execute("select name from sqlite_master where name = ?", params) - # work with the result - result = cur.fetchall() - ``` - - For more information on SQL Injection see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - cwe: CWE-89 + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an SQL Command ('SQL Injection') + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python mode: taint + options: + symbolic_propagation: true pattern-sinks: - patterns: - - pattern: $DB.execute(...) - - pattern-not: - pattern-either: - - pattern: $DB.execute("...") - - pattern: $DB.execute("$QUERY" % "...") - - pattern: $DB.execute("$QUERY" + "...") + - pattern-either: + - patterns: + - pattern-not: os.$METHOD("...", ...) + - pattern: os.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (execl|execle|execlp|execlpe|execv|execve|execvp|execvpe) + - patterns: + - pattern-not: os.$METHOD("...", [$PATH,"...","...",...],...) + - pattern-inside: os.$METHOD($BASH,[$PATH,"-c",$CMD,...],...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (execv|execve|execvp|execvpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-not: os.$METHOD("...", $PATH, "...", "...",...) + - pattern-inside: os.$METHOD($BASH, $PATH, "-c", $CMD,...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (execl|execle|execlp|execlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) pattern-sources: - patterns: - pattern-either: - - pattern: | - "$QUERY" % ... - - pattern: | - "$QUERY".format(...) - - pattern: | - f"$QUERY{...}..." - - pattern: | - "$QUERY" + ... - - pattern: | - $TMP = "$QUERY" - ... - $SQL = $TMP + "..." % ... - - pattern: "$SQL = \"$QUERY\"\n...\n$SQL += ... \n" - - metavariable-regex: - metavariable: $QUERY - regex: (?i)^(SELECT|INSERT|UPDATE|DELETE)\s - severity: WARNING - - id: python_ssh_rule-ssh-nohost-key-verification - languages: - - python - message: | - The application was found to ignore host keys. Host keys are important as - they provide assurance that the client can prove that the host is trusted. - By ignoring these host keys, it is impossible for the client to validate the - connection is to a trusted host. - - To remediate this issue, remove the call to `set_missing_host_key_policy(...)` which - sets the host key policy. Instead, load key files using either `load_system_host_keys` - or `load_host_keys` to only allow known good hosts. By not setting a host key policy - for unknown hosts, `paramiko`'s default policy is to use `RejectPolicy`. - - Example configuration connecting to a known, trusted host, and not allowing connections - to unknown hosts: - ``` - import paramiko - - # Create an SSH client - with paramiko.SSHClient() as ssh: - # Load the system host keys so we can confirm the - # host we are connecting to is legitimate - ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts') - - # Connect to the remote host using our SSH private key - ssh.connect(hostname='example.org', - port=22, - username='appuser', - key_filename='/home/appuser/.ssh/private_key') - ``` - - For more information on `set_missing_host_key_policy` see: - - https://docs.paramiko.org/en/stable/api/client.html#paramiko.client.SSHClient.set_missing_host_key_policy - metadata: - category: security - cwe: CWE-322 - owasp: - - A5:2017-Broken Access Control - - A07:2021-Identification and Authentication Failures - security-severity: Medium - shortDescription: Key exchange without entity authentication - patterns: - - pattern-inside: | - $CLIENT = paramiko.client.SSHClient(...) - ... - $CLIENT.set_missing_host_key_policy(...) - - pattern-either: - - pattern: paramiko.client.AutoAddPolicy - - pattern: paramiko.client.WarningPolicy - severity: ERROR - - id: python_ssl_rule-req-no-certvalid - languages: - - python - message: | - The application was found using the `requests` module without configuring a timeout value for - connections. The `verify=False` argument has been set, which effectively disables the - validation - of server certificates. - - This allows for an adversary who is in between the application and the target host to intercept - potentially sensitive information or transmit malicious data. - - To remediate this issue either remove the `verify=False` argument, or set `verify=True`to each - `requests` call. - - Example verifying server certificates for an HTTP GET request: - ``` - # Issue a GET request to https://example.com with a timeout of 10 seconds and verify the - # server certificate explicitly. - response = requests.get('https://example.com', timeout=10, verify=True) - # Work with the response object - # ... - ``` - - For more information on using the requests module see: - - https://requests.readthedocs.io/en/latest/api/ - metadata: - category: security - cwe: CWE-295 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: Medium - shortDescription: Improper certificate validation - patterns: - - pattern-either: - - pattern: requests.put(..., verify=False, ...) - - pattern: requests.patch(..., verify=False, ...) - - pattern: requests.delete(..., verify=False, ...) - - pattern: requests.head(..., verify=False, ...) - - pattern: requests.options(..., verify=False, ...) - - pattern: requests.request(..., verify=False, ...) - - pattern: requests.get(..., verify=False, ...) - - pattern: requests.post(..., verify=False, ...) - severity: ERROR - - id: python_ssl_rule-ssl-no-version - languages: - - python - message: | - The application was found calling `ssl.wrap_socket` without a TLS protocol version specified. - Additionally, `ssl.wrap_socket` has been deprecated since Python 3.7. It is strongly - recommended - that newer applications use TLS 1.2 or 1.3 and `SSLContext.wrap_socket`. - - To remediate this issue, create a new TLS context and pass in `ssl.PROTOCOL_TLS_CLIENT` - for clients or `ssl.PROTOCOL_TLS_SERVER` for servers to the `ssl.SSLContext(...)` `protocol=` - argument. When converting the socket to a TLS socket, use the new `SSLContext.wrap_socket` - method instead. - - - Example creating a TLS 1.3 client socket connection by using a newer version of Python - (3.11.4) and - the SSL module: - ``` - import ssl - import socket - - # Create our initial socket - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: - # Connect the socket - sock.connect(('www.example.org', 443)) - - # Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT - # This will auto-select the highest grade TLS protocol version (1.3) - context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) - # Load our a certificates for server certificate authentication - context.load_verify_locations('cert.pem') - # Create our TLS socket, and validate the server hostname matches - with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock: - # Send some bytes over the socket (HTTP request in this case)\ - data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8') - sent_bytes = tls_sock.send(data) - # Validate number of sent bytes - # ... - # Read the response - resp = tls_sock.recv() - # Work with the response - # ... - ``` - - For more information on the ssl module see: - - https://docs.python.org/3/library/ssl.html - metadata: - category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Inadequate encryption strength - patterns: - - pattern: ssl.wrap_socket() - severity: WARNING - - id: python_ssl_rule-ssl-with-bad-version - languages: - - python - message: | - The application was found calling an SSL module with SSL or TLS protocols that have known - deficiencies. - It is strongly recommended that newer applications use TLS 1.2 or 1.3 and - `SSLContext.wrap_socket`. - - If using the `pyOpenSSL` module, please note that it has been deprecated and the Python - Cryptographic Authority - strongly suggests moving to use the [pyca/cryptography](https://github.com/pyca/cryptography) - module instead. - - To remediate this issue for the `ssl` module, create a new TLS context and pass in - `ssl.PROTOCOL_TLS_CLIENT` for clients or `ssl.PROTOCOL_TLS_SERVER` for servers to the - `ssl.SSLContext(...)` `protocol=` - argument. When converting the socket to a TLS socket, use the new `SSLContext.wrap_socket` - method instead. - - Example creating a TLS 1.3 client socket connection by using a newer version of Python - (3.11.4) and - the SSL module: - ``` - import ssl - import socket - - # Create our initial socket - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: - # Connect the socket - sock.connect(('www.example.org', 443)) - - # Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT - # This will auto-select the highest grade TLS protocol version (1.3) - context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) - # Load our a certificates for server certificate authentication - context.load_verify_locations('cert.pem') - # Create our TLS socket, and validate the server hostname matches - with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock: - # Send some bytes over the socket (HTTP request in this case)\ - data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8') - sent_bytes = tls_sock.send(data) - # Validate number of sent bytes - # ... - # Read the response - resp = tls_sock.recv() - # Work with the response - # ... - ``` - - For more information on the ssl module see: - - https://docs.python.org/3/library/ssl.html - - For more information on pyca/cryptography and openssl see: - - https://cryptography.io/en/latest/openssl/ - metadata: - category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Inadequate Encryption Strength - patterns: - - pattern-either: - - pattern: ssl.PROTOCOL_SSLv2 - - pattern: ssl.PROTOCOL_SSLv3 - - pattern: ssl.PROTOCOL_TLSv1 - - pattern: ssl.PROTOCOL_TLSv1_1 - - pattern: pyOpenSSL.SSL.SSLv2_METHOD - - pattern: pyOpenSSL.SSL.SSLv23_METHOD - - pattern: pyOpenSSL.SSL.SSLv3_METHOD - - pattern: pyOpenSSL.SSL.TLSv1_METHOD - - pattern: pyOpenSSL.SSL.TLSv1_1_METHOD - severity: ERROR - - id: python_ssl_rule-unverified-context - languages: - - python - message: | - The application was found creating a SSL context using the `_create_unverified_context`. - This effectively disables the validation of server certificates. - - This allows for an adversary who is in between the application and the target host to intercept - potentially sensitive information or transmit malicious data. - - To remediate this issue remove the call to `_create_unverified_context` and either create a - default - context using `ssl.create_default_context` or create a context with TLS 1.3. - - Example creating a TLS 1.3 client socket connection by using a newer version of Python - (3.11.4) and - the SSL module: - ``` - import ssl - import socket - - # Create our initial socket - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: - # Connect the socket - sock.connect(('www.example.org', 443)) - - # Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT - # This will auto-select the highest grade TLS protocol version (1.3) - context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) - # Load our a certificates for server certificate authentication - context.load_verify_locations('cert.pem') - # Create our TLS socket, and validate the server hostname matches - with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock: - # Send some bytes over the socket (HTTP request in this case)\ - data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8') - sent_bytes = tls_sock.send(data) - # Validate number of sent bytes - # ... - # Read the response - resp = tls_sock.recv() - # Work with the response - # ... - ``` - - Unverified SSL context detected. This will permit insecure connections without `verifyingSSL` - certificates. Use `ssl.create_default_context()` instead. - metadata: - category: security - cwe: CWE-295 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: Medium - shortDescription: Improper certificate validation - pattern: ssl._create_unverified_context(...) + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS severity: ERROR - - id: python_telnet_rule-import-telnib + - id: python.lang.security.audit.dangerous-spawn-process-tainted-env-args.dangerous-spawn-process-tainted-env-args languages: - python - message: | - The application was found using a telnet library. As telnet does not provide encryption, it is - strongly recommended that communications use a more secure transport such as - SSH. - - The [paramiko](https://www.paramiko.org/) library can be used to initiate SSH connections. - - Example using `paramiko` SSH client: - ``` - import paramiko - import scp - - # Create an SSH client - with paramiko.SSHClient() as ssh: - # Load the system host keys so we can confirm the - # host we are connecting to is legitimate - ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts') - - # Connect to the remote host using our SSH private key - ssh.connect(hostname='example.org', - port=22, - username='appuser', - key_filename='/home/appuser/.ssh/private_key') - # Work with the connection - ``` - - For more information on the paramiko module see: - - https://www.paramiko.org/ + message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - cwe: CWE-319 + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Cleartext transmission of sensitive information - patterns: - - pattern: import telnetlib + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-not: os.$METHOD($MODE, "...", ...) + - pattern-inside: os.$METHOD($MODE, $CMD, ...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) + - patterns: + - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...) + - pattern-inside: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...) + - pattern-inside: os.$METHOD($MODE, $BASH, "-c", $CMD,...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS severity: ERROR - - id: python_tmpdir_rule-hardcodedtmp + - id: python.lang.security.audit.dangerous-subinterpreters-run-string-tainted-env-args.dangerous-subinterpreters-run-string-tainted-env-args languages: - python - message: | - The application was found creating files in shared system temporary directories - (`/tmp` or `/var/tmp`) without using the `tempfile.TemporaryFile` function. Depending - on how the application uses this temporary file, an attacker may be able to create - symlinks that point to other files prior to the application creating or writing - to the target file, leading to unintended files being created or overwritten. - - Example using `tempfile.TemporaryFile` to write a file: - ``` - import tempfile - - # Open a new temporary file using a context manager - with tempfile.TemporaryFile() as fp: - # Write some data to the temporary file - fp.write(b'Some data') - # Seek back to beginning of file - fp.seek(0) - # Read it - data = fp.read() - # File is automatically closed/removed once we exit the with context - ``` - - For more information on alternative tempfile functions see: - - https://docs.python.org/3/library/tempfile.html + message: Found user controlled content in `run_string`. This is dangerous because it allows a malicious actor to run arbitrary Python code. metadata: category: security - cwe: CWE-377 + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Insecure temporary file - pattern: $CALL("=~/^\/tmp.*/", ...) + - A03:2021 - Injection + references: + - https://bugs.python.org/issue43472 + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-inside: | + _xxsubinterpreters.run_string($ID, $PAYLOAD, ...) + - pattern-not: | + _xxsubinterpreters.run_string($ID, "...", ...) + - pattern: $PAYLOAD + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS severity: WARNING - - id: python_tmpdir_rule-mktemp-q + - id: python.lang.security.audit.dangerous-subprocess-use-tainted-env-args.dangerous-subprocess-use-tainted-env-args languages: - python - message: | - The application was found creating temporary files with the insecure `mktemp` method. - Depending on how the application uses this temporary file, an attacker may be able to create - symlinks that point to other files prior to the application creating or writing - to the target file, leading to unintended files being created or overwritten. - - To remediate this issue consider using `tempfile.TemporaryFile` instead. - - Example using `tempfile.TemporaryFile` to write a file: - ``` - import tempfile - - # Open a new temporary file using a context manager - with tempfile.TemporaryFile() as fp: - # Write some data to the temporary file - fp.write(b'Some data') - # Seek back to beginning of file - fp.seek(0) - # Read it - data = fp.read() - # File is automatically closed/removed once we exit the with context - ``` - - For more information on alternative tempfile functions see: - - https://docs.python.org/3/library/tempfile.html + message: Detected subprocess function '$FUNC' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.escape()'. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - cwe: CWE-377 + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Insecure temporary file - pattern: tempfile.mktemp(...) + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess + - https://docs.python.org/3/library/subprocess.html + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-not: subprocess.$FUNC("...", ...) + - pattern-not: subprocess.$FUNC(["...",...], ...) + - pattern-not: subprocess.$FUNC(("...",...), ...) + - pattern-not: subprocess.CalledProcessError(...) + - pattern-not: subprocess.SubprocessError(...) + - pattern: subprocess.$FUNC($CMD, ...) + - patterns: + - pattern-not: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...) + - pattern: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD) + - patterns: + - pattern-not: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...],...) + - pattern-not: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...),...) + - pattern-either: + - pattern: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD], ...) + - pattern: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD), ...) + - patterns: + - pattern-not: subprocess.$FUNC("=~/(python)/","...",...) + - pattern: subprocess.$FUNC("=~/(python)/", $CMD) + - patterns: + - pattern-not: subprocess.$FUNC(["=~/(python)/","...",...],...) + - pattern-not: subprocess.$FUNC(("=~/(python)/","...",...),...) + - pattern-either: + - pattern: subprocess.$FUNC(["=~/(python)/", $CMD],...) + - pattern: subprocess.$FUNC(("=~/(python)/", $CMD),...) + - focus-metavariable: $CMD + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS severity: ERROR - - id: python_urlopen_rule-urllib-urlopen - languages: - - python - message: | - The application was found passing in a non-literal value to the `urllib` methods which issue - requests. `urllib` supports the `file://` scheme, which may allow an adversary who can control - the URL value to read arbitrary files on the file system. - - To remediate this issue either hardcode the URLs being used in urllib or use the `requests` - module instead. - - Example using the `requests` module to issue an HTTPS request: - ``` - import requests - # Issue a GET request to https://example.com with a timeout of 10 seconds - response = requests.get('https://example.com', timeout=10) - # Work with the response object - # ... - ``` - metadata: - category: security - cwe: CWE-939 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper authorization in handler for custom URL scheme - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: urllib.$METHOD(...) - - pattern: urllib.request.$METHOD(...) - - pattern-not: urllib.$METHOD("...") - - pattern-not: urllib.request.$METHOD("...") - - pattern-not: urllib.$METHOD("...", ...) - - pattern-not: urllib.request.$METHOD("...", ...) - - metavariable-regex: - metavariable: $METHOD - regex: (urlopen|urlretrieve) - - patterns: - - pattern-either: - - pattern-inside: | - $OPENER = urllib.URLopener(...) - ... - - pattern-inside: | - $OPENER = urllib.request.URLopener(...) - ... - - pattern-inside: | - $OPENER = urllib.FancyURLopener(...) - ... - - pattern-inside: | - $OPENER = urllib.request.FancyURLopener(...) - ... - - pattern-either: - - pattern: $OPENER.open(...) - - pattern: $OPENER.retrieve(...) - - pattern-not: $OPENER.open("...") - - pattern-not: $OPENER.retrieve("...") - severity: WARNING - - id: python_xml_rule-celement + - id: python.lang.security.audit.dangerous-system-call-tainted-env-args.dangerous-system-call-tainted-env-args languages: - python - message: | - The application was found using the `xml.etree` package for processing XML. - Pythons default xml processors suffer from various XML parsing vulnerabilities - and care must be taken when handling XML data. Additionally, depending on the - version of Python, more critical vulnerabilities such as eXternal XML Entity - injection maybe exploitable. - - The `etree` package suffers from the following security risks as of Python 3.7.1: - * Billion laughs / exponential entity expansion - May allow an adversary to cause - a Denial of Service (DoS) against the application parsing arbitrary XML. - * Quadratic blowup entity expansion - Similar to above, but requires a larger input - to cause the Denial of Service. - - To remediate the above issues, consider using the - [defusedxml](https://pypi.org/project/defusedxml/) - library when processing untrusted XML. - - Example parsing an XML document using defusedxml: - ``` - from defusedxml.ElementTree import parse - - # Parse the inventory.xml file - et = parse('inventory.xml') - # Get the root element - root = et.getroot() - # Work with the root element - # ... - ``` - - For more information on the various XML parsers and their vulnerabilities please see: - - https://docs.python.org/3/library/xml.html#xml-vulnerabilities - - For more information on XML security see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python + message: Found user-controlled data used in a system call. This could allow a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. metadata: + asvs: + control_id: 5.2.4 Dyanmic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - cwe: CWE-611 + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A4:2017-XML External Entities (XXE) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper restriction of XML external entity reference - pattern-either: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: - patterns: - - pattern: xml.etree.cElementTree.fromstring(...) - - pattern-not: xml.etree.cElementTree.fromstring("...") - - pattern: xml.etree.cElementTree.parse(...) - - pattern: xml.etree.cElementTree.iterparse(...) - - pattern: xml.etree.cElementTree.XMLParser(...) - severity: WARNING - - id: python_xml_rule-element - languages: - - python - message: | - The application was found using the `xml.etree` package for processing XML. - Pythons default xml processors suffer from various XML parsing vulnerabilities - and care must be taken when handling XML data. Additionally, depending on the - version of Python, more critical vulnerabilities such as eXternal XML Entity - injection maybe exploitable. - - The `etree` package suffers from the following security risks as of Python 3.7.1: - * Billion laughs / exponential entity expansion - May allow an adversary to cause - a Denial of Service (DoS) against the application parsing arbitrary XML. - * Quadratic blowup entity expansion - Similar to above, but requires a larger input - to cause the Denial of Service. - - To remediate the above issues, consider using the - [defusedxml](https://pypi.org/project/defusedxml/) - library when processing untrusted XML. - - Example parsing an XML document using defusedxml: - ``` - from defusedxml.ElementTree import parse - - # Parse the inventory.xml file - et = parse('inventory.xml') - # Get the root element - root = et.getroot() - # Work with the root element - # ... - ``` - - For more information on the various XML parsers and their vulnerabilities please see: - - https://docs.python.org/3/library/xml.html#xml-vulnerabilities - - For more information on XML security see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python - metadata: - category: security - cwe: CWE-611 - owasp: - - A4:2017-XML External Entities (XXE) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper restriction of XML external entity reference - pattern-either: + - pattern-not: os.$W("...", ...) + - pattern-either: + - pattern: os.system(...) + - pattern: | + $X = __import__("os") + ... + $X.system(...) + - pattern: | + $X = __import__("os") + ... + getattr($X, "system")(...) + - pattern: | + $X = getattr(os, "system") + ... + $X(...) + - pattern: | + $X = __import__("os") + ... + $Y = getattr($X, "system") + ... + $Y(...) + - pattern: os.popen(...) + - pattern: os.popen2(...) + - pattern: os.popen3(...) + - pattern: os.popen4(...) + pattern-sources: - patterns: - - pattern: xml.etree.ElementTree.fromstring(...) - - pattern-not: xml.etree.ElementTree.fromstring("...") - - pattern: xml.etree.ElementTree.parse(...) - - pattern: xml.etree.ElementTree.iterparse(...) - - pattern: xml.etree.ElementTree.XMLParser(...) - severity: WARNING - - id: python_xml_rule-etree - languages: - - python - message: | - The application was found using the `lxml.etree` package for processing XML. - Python's default XML processors suffer from various XML parsing vulnerabilities - and care must be taken when handling XML data. Additionally, depending on the - version of Python, more critical vulnerabilities such as eXternal XML Entity - injection maybe exploitable. - - The `etree` package suffers from the following security risks as of Python 3.7.1: - * Billion laughs / exponential entity expansion - May allow an adversary to cause - a Denial of Service (DoS) against the application parsing arbitrary XML. - * Quadratic blowup entity expansion - Similar to above, but requires a larger input - to cause the Denial of Service. - - To remediate the above issues, consider using the - [defusedxml](https://pypi.org/project/defusedxml/) - library when processing untrusted XML. - - Example parsing an XML document using defusedxml: - ``` - from defusedxml.ElementTree import parse - - # Parse the inventory.xml file - et = parse('inventory.xml') - # Get the root element - root = et.getroot() - # Work with the root element - # ... - ``` - - For more information on the various XML parsers and their vulnerabilities please see: - - https://docs.python.org/3/library/xml.html#xml-vulnerabilities - - For more information on XML security see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python - metadata: - category: security - cwe: CWE-611 - owasp: - - A4:2017-XML External Entities (XXE) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper restriction of XML external entity reference - pattern-either: - - pattern: lxml.etree.parse(...) - - patterns: - - pattern: lxml.etree.fromstring(...) - - pattern-not: lxml.etree.fromstring("...") - - pattern: lxml.etree.RestrictedElement(...) - - pattern: lxml.etree.GlobalParserTLS(...) - - pattern: lxml.etree.getDefaultParser(...) - - pattern: lxml.etree.check_docinfo(...) - severity: WARNING - - id: python_xml_rule-expatbuilder + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.audit.dangerous-testcapi-run-in-subinterp-tainted-env-args.dangerous-testcapi-run-in-subinterp-tainted-env-args languages: - python - message: | - The application was found using the `xml.dom.expatbuilder` which calls the `xml.dom.minidom` - package for processing XML. Python's default XML processors suffer from various XML parsing - vulnerabilities - and care must be taken when handling XML data. Additionally, depending on the - version of Python, more critical vulnerabilities such as eXternal XML Entity - injection maybe exploitable. - - The `xml.dom.minidom` package suffers from the following security risks as of Python 3.7.1: - * Billion laughs / exponential entity expansion - May allow an adversary to cause - a Denial of Service (DoS) against the application parsing arbitrary XML. - * Quadratic blowup entity expansion - Similar to above, but requires a larger input - to cause the Denial of Service. - - To remediate the above issues, consider using the - [defusedxml](https://pypi.org/project/defusedxml/) - library when processing untrusted XML. - - Example parsing an XML document using defusedxml: - ``` - from defusedxml.ElementTree import parse - - # Parse the inventory.xml file - et = parse('inventory.xml') - # Get the root element - root = et.getroot() - # Work with the root element - # ... - ``` - - For more information on the various XML parsers and their vulnerabilities please see: - - https://docs.python.org/3/library/xml.html#xml-vulnerabilities - - For more information on XML security see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python + message: Found user controlled content in `run_in_subinterp`. This is dangerous because it allows a malicious actor to run arbitrary Python code. metadata: category: security - cwe: CWE-611 + confidence: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: MEDIUM owasp: - - A4:2017-XML External Entities (XXE) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper restriction of XML external entity reference - pattern-either: + - A03:2021 - Injection + references: + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + subcategory: + - vuln + technology: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + _testcapi.run_in_subinterp($PAYLOAD, ...) + - pattern-inside: | + test.support.run_in_subinterp($PAYLOAD, ...) + - pattern: $PAYLOAD + - pattern-not: | + _testcapi.run_in_subinterp("...", ...) + - pattern-not: | + test.support.run_in_subinterp("...", ...) + pattern-sources: - patterns: - - pattern: xml.dom.expatbuilder.parse(...) - - pattern-not: xml.dom.expatbuilder.parse("...") - - pattern: xml.dom.expatbuilder.parseString(...) + - pattern-either: + - patterns: + - pattern-either: + - pattern: os.environ + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv + - pattern: sys.orig_argv + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS severity: WARNING - - id: python_xml_rule-expatreader + - id: python.lang.security.audit.insecure-file-permissions.insecure-file-permissions languages: - python - message: | - The application was found using the `xml.sax.expatreader` package for processing XML. Python's - default XML processors suffer from various XML parsing vulnerabilities - and care must be taken when handling XML data. Additionally, depending on the - version of Python, more critical vulnerabilities such as eXternal XML Entity - injection maybe exploitable. - - The `xml.sax` package suffers from the following security risks as of Python 3.7.1: - * Billion laughs / exponential entity expansion - May allow an adversary to cause - a Denial of Service (DoS) against the application parsing arbitrary XML. - * Quadratic blowup entity expansion - Similar to above, but requires a larger input - to cause the Denial of Service. - - To remediate the above issues, consider using the - [defusedxml](https://pypi.org/project/defusedxml/) - library when processing untrusted XML. - - Example parsing an XML document using defusedxml: - ``` - from defusedxml.ElementTree import parse - - # Parse the inventory.xml file - et = parse('inventory.xml') - # Get the root element - root = et.getroot() - # Work with the root element - # ... - ``` - - For more information on the various XML parsers and their vulnerabilities please see: - - https://docs.python.org/3/library/xml.html#xml-vulnerabilities - - For more information on XML security see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python + message: These permissions `$BITS` are widely permissive and grant access to more people than may be necessary. A good default is `0o644` which gives read and write access to yourself and read access to everyone else. metadata: category: security - cwe: CWE-611 + confidence: MEDIUM + cwe: + - 'CWE-276: Incorrect Default Permissions' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A4:2017-XML External Entities (XXE) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper restriction of XML external entity reference - pattern-either: - - pattern: xml.dom.expatreader.parse(...) - - patterns: - - pattern: xml.dom.expatreader.parseString(...) - - pattern-not: xml.dom.expatreader.parseString("...") - - pattern: xml.dom.expatreader.parseString(...) - - pattern: xml.dom.expatreader.create_parser(...) + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - python + patterns: + - pattern-inside: os.$METHOD(...) + - metavariable-pattern: + metavariable: $METHOD + patterns: + - pattern-either: + - pattern: chmod + - pattern: lchmod + - pattern: fchmod + - pattern-either: + - patterns: + - pattern: os.$METHOD($FILE, $BITS, ...) + - metavariable-comparison: + comparison: $BITS >= 0o650 and $BITS < 0o100000 + metavariable: $BITS + - patterns: + - pattern: os.$METHOD($FILE, $BITS) + - metavariable-comparison: + comparison: $BITS >= 0o100650 + metavariable: $BITS + - patterns: + - pattern: os.$METHOD($FILE, $BITS, ...) + - metavariable-pattern: + metavariable: $BITS + patterns: + - pattern-either: + - pattern: <... stat.S_IWGRP ...> + - pattern: <... stat.S_IXGRP ...> + - pattern: <... stat.S_IWOTH ...> + - pattern: <... stat.S_IXOTH ...> + - pattern: <... stat.S_IRWXO ...> + - pattern: <... stat.S_IRWXG ...> + - patterns: + - pattern: os.$METHOD($FILE, $EXPR | $MOD, ...) + - metavariable-comparison: + comparison: $MOD == 0o111 + metavariable: $MOD severity: WARNING - - id: python_xml_rule-minidom + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.requests.request-session-http-in-with-context.request-session-http-in-with-context languages: - python - message: | - The application was found using the `xml.dom.minidom` package for processing XML. Python's - default XML processors suffer from various XML parsing vulnerabilities - and care must be taken when handling XML data. Additionally, depending on the - version of Python, more critical vulnerabilities such as eXternal XML Entity - injection maybe exploitable. - - The `xml.dom.minidom` package suffers from the following security risks as of Python 3.7.1: - * Billion laughs / exponential entity expansion - May allow an adversary to cause - a Denial of Service (DoS) against the application parsing arbitrary XML. - * Quadratic blowup entity expansion - Similar to above, but requires a larger input - to cause the Denial of Service. - - To remediate the above issues, consider using the - [defusedxml](https://pypi.org/project/defusedxml/) - library when processing untrusted XML. - - Example parsing an XML document using defusedxml: - ``` - from defusedxml.ElementTree import parse - - # Parse the inventory.xml file - et = parse('inventory.xml') - # Get the root element - root = et.getroot() - # Work with the root element - # ... - ``` - - For more information on the various XML parsers and their vulnerabilities please see: - - https://docs.python.org/3/library/xml.html#xml-vulnerabilities - - For more information on XML security see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python + message: Detected a request using 'http://'. This request will be unencrypted. Use 'https://' instead. metadata: + asvs: + control_id: 9.2.1 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" category: security - cwe: CWE-611 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW owasp: - - A4:2017-XML External Entities (XXE) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper restriction of XML external entity reference - pattern-either: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - requests + mode: taint + options: + symbolic_propagation: true + pattern-sinks: - patterns: - - pattern: xml.dom.minidom.parseString(...) - - pattern-not: xml.dom.minidom.parseString("...") - - pattern: xml.dom.minidom.parse(...) - severity: WARNING - - id: python_xml_rule-pulldom - languages: - - python - message: | - The application was found using the `xml.dom.pulldom` package for processing XML. Python's - default XML processors suffer from various XML parsing vulnerabilities - and care must be taken when handling XML data. Additionally, depending on the - version of Python, more critical vulnerabilities such as eXternal XML Entity - injection maybe exploitable. - - The `xml.dom.pulldom` package suffers from the following security risks as of Python 3.7.1: - * Billion laughs / exponential entity expansion - May allow an adversary to cause - a Denial of Service (DoS) against the application parsing arbitrary XML. - * Quadratic blowup entity expansion - Similar to above, but requires a larger input - to cause the Denial of Service. - - To remediate the above issues, consider using the - [defusedxml](https://pypi.org/project/defusedxml/) - library when processing untrusted XML. - - Example parsing an XML document using defusedxml: - ``` - from defusedxml.ElementTree import parse - - # Parse the inventory.xml file - et = parse('inventory.xml') - # Get the root element - root = et.getroot() - # Work with the root element - # ... - ``` - - For more information on the various XML parsers and their vulnerabilities please see: - - https://docs.python.org/3/library/xml.html#xml-vulnerabilities - - For more information on XML security see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python - metadata: - category: security - cwe: CWE-611 - owasp: - - A4:2017-XML External Entities (XXE) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper restriction of XML external entity reference - pattern-either: + - pattern-inside: | + with requests.Session(...) as $SESSION: + ... + - pattern-either: + - pattern: $SESSION.$W($SINK, ...) + - pattern: $SESSION.request($METHOD, $SINK, ...) + - focus-metavariable: $SINK + pattern-sources: - patterns: - - pattern: xml.dom.pulldom.parseString(...) - - pattern-not: xml.dom.pulldom.parseString("...") - - pattern: xml.dom.pulldom.parse(...) - severity: WARNING - - id: python_xml_rule-sax + - pattern: | + "$URL" + - metavariable-pattern: + language: regex + metavariable: $URL + patterns: + - pattern-regex: http:// + - pattern-not-regex: .*://localhost + - pattern-not-regex: .*://127\.0\.0\.1 + severity: INFO + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.requests.request-session-with-http.request-session-with-http languages: - python - message: | - The application was found using the `xml.sax` package for processing XML. - Python's default XML processors suffer from various XML parsing vulnerabilities - and care must be taken when handling XML data. Additionally, depending on the - version of Python, more critical vulnerabilities such as eXternal XML Entity - injection maybe exploitable. - - The `xml.sax` package suffers from the following security risks as of Python 3.7.1: - * Billion laughs / exponential entity expansion - May allow an adversary to cause - a Denial of Service (DoS) against the application parsing arbitrary XML. - * Quadratic blowup entity expansion - Similar to above, but requires a larger input - to cause the Denial of Service. - - To remediate the above issues, consider using the - [defusedxml](https://pypi.org/project/defusedxml/) - library when processing untrusted XML. - - Example parsing an XML document using defusedxml: - ``` - from defusedxml.ElementTree import parse - - # Parse the inventory.xml file - et = parse('inventory.xml') - # Get the root element - root = et.getroot() - # Work with the root element - # ... - ``` - - For more information on the various XML parsers and their vulnerabilities please see: - - https://docs.python.org/3/library/xml.html#xml-vulnerabilities - - For more information on XML security see OWASP's guide: - - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python - metadata: - category: security - cwe: CWE-611 - owasp: - - A4:2017-XML External Entities (XXE) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper restriction of XML external entity reference - pattern-either: - - pattern: xml.sax.parse(...) - - patterns: - - pattern: xml.sax.parseString(...) - - pattern-not: xml.sax.parseString("...") - - pattern: xml.sax.make_parser(...) - severity: WARNING - - id: generic_injection_rule-BiDiTrojanSource - languages: - - generic - message: "Unicode bidirectional (BiDi) control characters were detected in source code.\nThese characters can be used to reorder text and hide malicious code \n(CVE-2021-42574).\n\nBiDi override characters can make code appear different from its actual logic:\n- Text that appears as a comment might actually be executable code\n- Code that appears harmless might contain hidden malicious logic\n- Variable names and string literals may not reflect their true content\n\nMitigation Steps:\n- Remove any BiDi override characters\n- Only use standard ASCII characters in source code\n- If BiDi characters are required, thoroughly review the code\n\nSecure Code Example:\n```java\npublic class DataProcessor {\n // Use standard ASCII characters only\n public void processData(String data) {\n String cleanInput = data.trim(); // Clean the input\n System.out.println(\"Processing: \" + cleanInput); // Clear, readable code\n }\n}\n```\n\nReferences:\n- https://nvd.nist.gov/vuln/detail/CVE-2021-42574\n- https://trojansource.codes/\n" - metadata: - category: security - cwe: CWE-94 - owasp: - - A03:2021-Injection - - A1:2017-Injection - security-severity: Low - shortDescription: Improper control of generation of code ('Code Injection') - paths: - include: - - '*.py' - - '*.js' - - '*.java' - - '*.c' - - '*.cpp' - - '*.cs' - - '*.go' - - '*.rs' - - '*.php' - - '*.rb' - - '*.scala' - - '*.ts' - - '*.kt' - - '*.m' - - '*.swift' - pattern-regex: '[\x{202A}-\x{202E}\x{2066}-\x{2069}\x{200E}\x{200F}\x{061C}]' - severity: WARNING - - id: java_deserialization_rule-InsecureDeserialization - languages: - - java - message: | - Deserialization attacks exploit the process of reading serialized data and turning it back into an - object. By constructing malicious objects and serializing them, an adversary may attempt to: - - - Inject code that is executed upon object construction, which occurs during the deserialization process. - - Exploit mass assignment by including fields that are not normally a part of the serialized data but are - read in during deserialization. - - Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows - the application to specify exactly which object types are allowed to be deserialized. Additionally, when - deserializing, never deserialize to base object types like `Object` and only cast to the exact object - type that is expected. - - To protect against mass assignment, only allow deserialization of the specific fields that are required. - If this is not easily done, consider creating an intermediary type that can be serialized with only the - necessary fields exposed. - - For more details on deserialization attacks in general, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html + message: Detected a request using 'http://'. This request will be unencrypted. Use 'https://' instead. metadata: + asvs: + control_id: 9.1.1 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" category: security - cwe: CWE-502 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: Medium - shortDescription: Deserialization of Untrusted Data + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit technology: - - java + - requests mode: taint - pattern-propagators: - - from: $X - pattern: $V = new ObjectInputStream($X) - to: $V + options: + symbolic_propagation: true pattern-sinks: - - pattern: $V.readObject(...) + - patterns: + - pattern-either: + - pattern: requests.Session(...).$W($SINK, ...) + - pattern: requests.Session(...).request($METHOD, $SINK, ...) + - focus-metavariable: $SINK pattern-sources: - patterns: - - pattern-inside: "$FUNC (..., byte[] $X, ...) { \n ... \n}\n" - - focus-metavariable: $X - severity: WARNING - - id: javascript_crypto_rule-NodeLibcurlSSLVerificationDisable + - pattern: | + "$URL" + - metavariable-pattern: + language: regex + metavariable: $URL + patterns: + - pattern-regex: http:// + - pattern-not-regex: .*://localhost + - pattern-not-regex: .*://127\.0\.0\.1 + severity: INFO + - fix-regex: + count: 1 + regex: '[Hh][Tt][Tt][Pp]://' + replacement: https:// + id: python.lang.security.audit.insecure-transport.requests.request-with-http.request-with-http languages: - - javascript - message: "The application was identified disabling the `SSL_VERIFYPEER` and/or the \n`SSL_VERIFYHOST` options of the node-libcurl library. These options control \nthe verification process of SSL/TLS certificates and hostnames. \n\n- SSL_VERIFYPEER: This option, when enabled, ensures that the SSL certificate \npresented by the server is valid and trusted by a Certificate Authority (CA) \nthat the client also trusts. This is crucial for verifying that the server with \nwhich the client is connecting is authenticated and its certificate is not forged.\n- SSL_VERIFYHOST: This option, when enabled, makes sure that the certificate's \ncommon name (CN) or one of its subject alternative names (SANs) matches the \nhost name in the URL being connected . This is essential for ensuring that \nthe client is communicating with the correct server and not another server \npresenting a valid certificate.\n\nDisabling these options compromises the security of SSL/TLS connections. It \nexposes the application to MITM attacks, where an attacker could intercept, \nread, or modify the data sent and received over what is assumed to be a secure \nconnection.\n\nMitigation Strategy:\nTo mitigate this vulnerability and ensure secure communication, enable SSL/TLS \ncertificate and hostname verification by setting `SSL_VERIFYPEER` to `1` or \n`true` and `SSL_VERIFYHOST` to `2`. These options are enabled by default as \nwell. This configuration ensures that the server's SSL certificate is validated \nagainst trusted CAs and that the hostname in the certificate matches the hostname \nthe client intends to communicate with.\n\nSecure Code Example:\n```\nconst { Curl } = require('node-libcurl')\nconst curl = new Curl()\ncurl.setOpt('SSL_VERIFYPEER', 1)\ncurl.setOpt('SSL_VERIFYHOST', 2)\ncurl.setOpt('URL', 'https://yourserver.com:443')\n```\n" + - python + message: Detected a request using 'http://'. This request will be unencrypted, and attackers could listen into traffic on the network and be able to obtain sensitive information. Use 'https://' instead. metadata: + asvs: + control_id: 9.1.1 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v92-server-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" category: security - cwe: CWE-599 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: LOW + likelihood: LOW owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Missing validation of OpenSSL certificate + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - requests mode: taint + options: + symbolic_propagation: true pattern-sinks: - patterns: - pattern-either: - - pattern: | - $X.setOpt($SSL, 0) - - pattern: | - $X.setOpt($SSL, false) - - metavariable-pattern: - metavariable: $SSL - pattern-either: - - pattern: | - "SSL_VERIFYHOST" - - pattern: | - "SSL_VERIFYPEER" - - pattern: | - $Y.option.SSL_VERIFYHOST - - pattern: | - $Y.option.SSL_VERIFYPEER + - pattern: requests.$W($SINK, ...) + - pattern: requests.request($METHOD, $SINK, ...) + - pattern: requests.Request($METHOD, $SINK, ...) + - focus-metavariable: $SINK pattern-sources: - patterns: - - pattern-either: - - pattern-inside: | - $Y = require('node-libcurl') - ... - - pattern-inside: | - import { $Y } from 'node-libcurl' - ... - - pattern-inside: | - import { $K as $Y } from 'node-libcurl' - ... - pattern: | - $X = new $Y() - severity: WARNING - - id: python_exec_rule-start-process-partial-path + "$URL" + - metavariable-pattern: + language: regex + metavariable: $URL + patterns: + - pattern-regex: http:// + - pattern-not-regex: .*://localhost + - pattern-not-regex: .*://127\.0\.0\.1 + severity: INFO + - id: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure languages: - python - message: | - Starting a process with a partial executable path + message: Detected a python logger call with a potential hardcoded secret $FORMAT_STRING being logged. This may lead to secret credentials being exposed. Make sure that the logger is not logging sensitive information. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-532: Insertion of Sensitive Information into Log File' + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures + subcategory: + - vuln + technology: + - python patterns: - - pattern-either: - - patterns: - - pattern: os.popen(...) - - pattern-not: os.popen("...", ...) - - patterns: - - pattern: os.system(...) - - pattern-not: os.system("...", ...) - - patterns: - - pattern: os.popen2(...) - - pattern-not: os.popen2("...", ...) - - patterns: - - pattern: os.popen3(...) - - pattern-not: os.popen3("...", ...) - - patterns: - - pattern: os.popen4(...) - - pattern-not: os.popen4("...", ...) - - patterns: - - pattern: popen2.popen2(...) - - pattern-not: popen2.popen2("...", ...) - - patterns: - - pattern: popen2.popen3(...) - - pattern-not: popen2.popen3("...", ...) - - patterns: - - pattern: popen2.popen4(...) - - pattern-not: popen2.popen4("...", ...) - - patterns: - - pattern: popen2.Popen3(...) - - pattern-not: popen2.Popen3("...", ...) - - patterns: - - pattern: popen2.Popen4(...) - - pattern-not: popen2.Popen4("...", ...) - - patterns: - - pattern: commands.getoutput(...) - - pattern-not: commands.getoutput("...", ...) - - patterns: - - pattern: commands.getstatusoutput(...) - - pattern-not: commands.getstatusoutput("...", ...) - severity: INFO - - id: python_exec_rule-start-process-path + - pattern: | + $LOGGER_OBJ.$LOGGER_CALL($FORMAT_STRING,...) + - metavariable-regex: + metavariable: $LOGGER_OBJ + regex: (?i)(_logger|logger|self.logger|log) + - metavariable-regex: + metavariable: $LOGGER_CALL + regex: (debug|info|warn|warning|error|exception|critical) + - metavariable-regex: + metavariable: $FORMAT_STRING + regex: (?i).*(api.key|secret|credential|token|password).*\%s.* + severity: WARNING + - id: python.lang.security.audit.md5-used-as-password.md5-used-as-password languages: - python - message: | - Starting a process with a partial executable path + message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as scrypt. You can use `hashlib.scrypt`. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: LOW + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') - patterns: - - pattern-either: - - pattern: subprocess.Popen($BIN, shell=False) - - pattern: subprocess.Popen([$BIN, ...], shell=False) - - pattern: os.system($BIN, shell=False) - - pattern: os.system([$BIN, ...], shell=False) - - pattern: popen2.Popen3($BIN, shell=False) - - pattern: popen2.Popen3([$BIN, ...], shell=False) - - pattern: popen2.Popen4($BIN, shell=False) - - pattern: popen2.Popen4([$BIN, ...], shell=False) - - pattern: commands.getoutput($BIN, shell=False) - - pattern: commands.getoutput([$BIN, ...], shell=False) - - pattern: commands.getstatusoutput($BIN, shell=False) - - pattern: commands.getstatusoutput([$BIN, ...], shell=False) - - metavariable-regex: - metavariable: $BIN - regex: ^['"][^/\.][^:].*['"] - severity: ERROR - - id: python_exec_rule-subprocess-call-array + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://tools.ietf.org/html/rfc6151 + - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords + - https://github.com/returntocorp/semgrep-rules/issues/1609 + - https://docs.python.org/3/library/hashlib.html#hashlib.scrypt + subcategory: + - vuln + technology: + - pycryptodome + - hashlib + - md5 + mode: taint + pattern-sinks: + - patterns: + - pattern: $FUNCTION(...) + - metavariable-regex: + metavariable: $FUNCTION + regex: (?i)(.*password.*) + pattern-sources: + - patterns: + - pattern-either: + - pattern: hashlib.md5 + - pattern: hashlib.new(..., name="MD5", ...) + - pattern: Cryptodome.Hash.MD5 + - pattern: Crypto.Hash.MD5 + - pattern: cryptography.hazmat.primitives.hashes.MD5 + severity: WARNING + - id: python.lang.security.audit.network.bind.avoid-bind-to-all-interfaces languages: - python - message: | - subprocess call - check for execution of untrusted input + message: Running `socket.bind` to 0.0.0.0, or empty string could unexpectedly expose the server publicly as it binds to all available interfaces. Consider instead getting correct address from an environment variable or configuration file. metadata: category: security - cwe: CWE-78 + confidence: HIGH + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an OS Command ('OS Command Injection') - patterns: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - python + pattern-either: - pattern: | - subprocess.$FUNC([..., $ARG, ...]) - - metavariable-pattern: - metavariable: $ARG - patterns: - - pattern-not: | - "..." - - pattern-not: | - '...' - severity: WARNING - - id: scala_unsafe_rule-InformationExposureVariant2 + $S = socket.socket(...) + ... + $S.bind(("0.0.0.0", ...)) + - pattern: | + $S = socket.socket(...) + ... + $S.bind(("::", ...)) + - pattern: | + $S = socket.socket(...) + ... + $S.bind(("", ...)) + severity: INFO + - id: python.lang.security.audit.network.disabled-cert-validation.disabled-cert-validation languages: - - scala - message: | - The sensitive information may be valuable information on its own (such as a password), or it - may be useful for launching other, more deadly attacks. If an attack fails, an attacker may use - error information provided by the server to launch another more focused attack. For example, an - attempt to exploit a path traversal weakness (CWE-22) might yield the full pathname of the - installed application. + - python + message: certificate verification explicitly disabled, insecure connections possible metadata: category: security - cwe: CWE-209 - security-severity: Info - shortDescription: Information Exposure Through an Error Message + confidence: MEDIUM + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + subcategory: + - vuln technology: - - scala + - python patterns: - pattern-either: - - pattern: $E.printStackTrace - - patterns: - - pattern: $E.printStackTrace($OUT) - - metavariable-pattern: - metavariable: $OUT - pattern-either: - - pattern: '($PS: java.io.PrintStream)' - - pattern: '($PW: java.io.PrintWriter)' - - pattern: java.lang.System.out - - pattern: '($O: java.io.OutputStream)' - - pattern: '($SOS: javax.servlet.ServletOutputStream)' - severity: WARNING - - id: java_cookie_rule-CookieHTTPOnly + - pattern: urllib3.PoolManager(..., cert_reqs=$REQS, ...) + - pattern: urllib3.ProxyManager(..., cert_reqs=$REQS, ...) + - pattern: urllib3.HTTPSConnectionPool(..., cert_reqs=$REQS, ...) + - pattern: urllib3.connectionpool.HTTPSConnectionPool(..., cert_reqs=$REQS, ...) + - pattern: urllib3.connection_from_url(..., cert_reqs=$REQS, ...) + - pattern: urllib3.proxy_from_url(..., cert_reqs=$REQS, ...) + - pattern: $CONTEXT.wrap_socket(..., cert_reqs=$REQS, ...) + - pattern: ssl.wrap_socket(..., cert_reqs=$REQS, ...) + - metavariable-regex: + metavariable: $REQS + regex: (NONE|CERT_NONE|CERT_OPTIONAL|ssl\.CERT_NONE|ssl\.CERT_OPTIONAL|\'NONE\'|\"NONE\"|\'OPTIONAL\'|\"OPTIONAL\") + severity: ERROR + - id: python.lang.security.audit.network.http-not-https-connection.http-not-https-connection languages: - - java - message: | - The `HttpOnly` attribute when set to `true` protects the cookie value from being accessed by - client side JavaScript such - as reading the `document.cookie` values. By enabling this protection, a website that is - vulnerable to - Cross-Site Scripting (XSS) will be able to block malicious scripts from accessing the cookie - value from JavaScript. - - Example of protecting a `Cookie`: - ``` - // Create an HttpOnly cookie. - Cookie someCookie = new Cookie("SomeCookieName", "SomeValue"); - // Set HttpOnly flag to true - someCookie.setHttpOnly(true); - ``` - - For more information see: - https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/http/cookie#setHttpOnly-boolean- - - Session cookies should be configured with the following security directives: - - - [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - - [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - - [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) + - python + message: Detected HTTPConnectionPool. This will transmit data in cleartext. It is recommended to use HTTPSConnectionPool instead for to encrypt communications. metadata: category: security - cwe: CWE-1004 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: Low - shortDescription: Sensitive cookie without 'HttpOnly' flag + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://urllib3.readthedocs.io/en/1.2.1/pools.html#urllib3.connectionpool.HTTPSConnectionPool + subcategory: + - audit technology: - - java - patterns: - - pattern-either: - - pattern: ($X.servlet.http.Cookie $COOKIE).setHttpOnly(false); - - patterns: - - pattern-not-inside: ($X.servlet.http.Cookie $COOKIE).setHttpOnly(...); ... - - pattern: $RESPONSE.addCookie($COOKIE); - severity: WARNING - - id: java_crypto_rule-DisallowOldTLSVersion - languages: - - java - message: "This application sets the `jdk.tls.client.protocols` system property to\ninclude insecure TLS or SSL versions (SSLv3, TLSv1, TLSv1.1), which are\ndeprecated due to serious security vulnerabilities like POODLE attacks and\nsusceptibility to man-in-the-middle attacks. Continuing to use these\nprotocols can expose data to interception or manipulation. \n\nTo mitigate the issue, upgrade to TLSv1.2 or higher, which provide stronger \nencryption and improved security. Refrain from using any SSL versions as they \nare entirely deprecated.\n\nSecure Code Example:\n```\npublic void safe() {\n java.lang.System.setProperty(\"jdk.tls.client.protocols\", \"TLSv1.3\");\n}\n```\n" + - python + pattern-either: + - pattern: urllib3.HTTPConnectionPool(...) + - pattern: urllib3.connectionpool.HTTPConnectionPool(...) + severity: ERROR + - id: python.lang.security.audit.ssl-wrap-socket-is-deprecated.ssl-wrap-socket-is-deprecated + languages: + - python + message: '''ssl.wrap_socket()'' is deprecated. This function creates an insecure socket without server name indication or hostname matching. Instead, create an SSL context using ''ssl.SSLContext()'' and use that to wrap a socket.' metadata: category: security confidence: MEDIUM - cwe: CWE-326 + cwe: + - 'CWE-326: Inadequate Encryption Strength' impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://stackoverflow.com/questions/26504653/is-it-possible-to-disable-sslv3-for-all-java-applications - security-severity: MEDIUM - shortDescription: Inadequate encryption strength + - https://docs.python.org/3/library/ssl.html#ssl.wrap_socket + - https://docs.python.org/3/library/ssl.html#ssl.SSLContext.wrap_socket subcategory: - vuln technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information - patterns: - - pattern: $VALUE. ... .setProperty("jdk.tls.client.protocols", "$PATTERNS"); - - metavariable-pattern: - language: generic - metavariable: $PATTERNS - patterns: - - pattern-either: - - pattern-regex: ^(.*TLSv1|.*SSLv.*)$ - - pattern-regex: ^(.*TLSv1,.*|.*TLSv1.1.*) - severity: WARNING - - id: java_crypto_rule-GCMNonceReuse - languages: - - java - message: "GCM is a mode of operation for symmetric-key cryptographic block ciphers. GCM allows the usage of\nan initialization vector or nonce used to provide the initial state. The IV is an arbitrary number \nthat can be used just once in a cryptographic communication. Re use of initialization vectors \nnullifies their usage, as the initial state of all GCMs with the same vector will effectively be\nthe same.\n\nInstead of hard coding an initialization vector, it is recommended to use nextBytes() method from\njava.security.SecureRandom. This generates a user specified number of random bytes.\n\nExample using `java.security.SecureRandom`:\n```\nCipher cipher = Cipher.getInstance(\"AES/GCM/NoPadding\");\nSecretKeySpec keySpec = new SecretKeySpec(secretKey.getEncoded(), \"AES\");\n\n// Generate a new, random IV for each encryption operation\nSecureRandom secureRandom = new SecureRandom();\n// GCM standard recommends a 12-byte (96-bit) IV\nbyte[] iv = new byte[12];\nsecureRandom.nextBytes(iv);\n\nGCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);\ncipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);\n```\n\nFor more information on Java Cryptography see:\nhttps://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html\n" - metadata: - category: security - cwe: CWE-323 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Reuse of cryptographic initialization vector - technology: - - java - mode: taint - pattern-sinks: - - pattern: new GCMParameterSpec(...,$NONCE, ...) - pattern-sources: - - pattern-either: - - pattern: new byte[]{...}; - - pattern: $STRING.getBytes(); + - python + pattern: ssl.wrap_socket(...) severity: WARNING - - id: java_crypto_rule-HTTPUrlConnectionHTTPRequest + - fix-regex: + regex: (shell\s*=\s*)True + replacement: \1False + id: python.lang.security.audit.subprocess-shell-true.subprocess-shell-true languages: - - java - message: "Detected an HTTP request sent via HttpURLConnection or URLConnection.\nThis could lead to sensitive information being sent over an insecure \nchannel, as HTTP does not encrypt data. Transmitting data over HTTP \nexposes it to potential interception by attackers, risking data \nintegrity and confidentiality. Using HTTP for transmitting sensitive \ndata such as passwords, personal information, or financial details can \nlead to information disclosure.\n\nTo mitigate the issue, switch to HTTPS to ensure all data transmitted \nis securely encrypted. This helps protect against eavesdropping and \nman-in-the-middle attacks. Modify the URL in your code from HTTP to \nHTTPS and ensure the server supports HTTPS.\n\nSecure Code Example:\n```\nprivate static void safe() {\n try {\n URL url = new URL(\"https://example.com/api/data\"); // Changed to HTTPS\n HttpURLConnection con = (HttpURLConnection) url.openConnection();\n con.setRequestMethod(\"GET\");\n\n int status = con.getResponseCode();\n if (status == HttpURLConnection.HTTP_OK) { \n BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n String inputLine;\n StringBuilder response = new StringBuilder();\n while ((inputLine = in.readLine()) != null) {\n response.append(inputLine);\n }\n in.close();\n System.out.println(\"Response: \" + response.toString());\n } else {\n System.out.println(\"HTTP error code: \" + status);\n }\n con.disconnect();\n } catch (Exception e) {\n e.printStackTrace();\n }\n}\n```\n" + - python + message: Found 'subprocess' function '$FUNC' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead. metadata: category: security confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: HIGH owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess + - https://docs.python.org/3/library/subprocess.html + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html subcategory: - vuln technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information + - python patterns: - - pattern: | - "=~/[Hh][Tt][Tt][Pp]://.*/" - - pattern-either: - - pattern-inside: | - URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); - ... - $CON = (HttpURLConnection) $URL.openConnection(...); - ... - $CON.$FUNC(...); - - pattern-inside: | - URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); - ... - $CON = $URL.openConnection(...); - ... - $CON.$FUNC(...); - severity: WARNING - - id: java_crypto_rule-HttpComponentsRequest + - pattern: subprocess.$FUNC(..., shell=True, ...) + - pattern-not: subprocess.$FUNC("...", shell=True, ...) + severity: ERROR + - id: python.lang.security.audit.weak-ssl-version.weak-ssl-version languages: - - java - message: "Detected an HTTP GET request sent via Apache HTTP Components. Sending data\nover HTTP can expose sensitive information to interception or modification\nby attackers, as HTTP does not encrypt the data transmitted. It is critical\nto use HTTPS, which encrypts the communication, to protect the confidentiality\nand integrity of data in transit.\n\nTo mitigate the issue, ensure all data transmitted between the client and \nserver is sent over HTTPS. Update all HTTP URLs to HTTPS and configure your \nserver to redirect HTTP requests to HTTPS. Additionally, implement HSTS \n(HTTP Strict Transport Security) to enforce secure connections.\nSecure Code Example:\n```\nprivate static void safe() {\n CloseableHttpClient httpclient = HttpClients.createDefault();\n CloseableHttpResponse response = httpclient.execute(new HttpPost(\"https://example.com\"));\n}\n```\n" + - python + message: An insecure SSL version was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use 'ssl.PROTOCOL_TLSv1_2' or higher. metadata: + asvs: + control_id: 9.1.3 Weak TLS + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x17-V9-Communications.md#v91-client-communications-security-requirements + section: V9 Communications Verification Requirements + version: "4" category: security confidence: MEDIUM - cwe: CWE-319 + cwe: + - 'CWE-326: Inadequate Encryption Strength' impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://hc.apache.org/httpcomponents-client-ga/quickstart.html - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://tools.ietf.org/html/rfc7568 + - https://tools.ietf.org/id/draft-ietf-tls-oldversions-deprecate-02.html + - https://docs.python.org/3/library/ssl.html#ssl.PROTOCOL_TLSv1_2 + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/insecure_ssl_tls.py#L30 subcategory: - - vuln + - audit technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information - mode: taint - pattern-sinks: - - pattern: (org.apache.http.impl.client.CloseableHttpClient $A).execute($HTTPREQ); - pattern-sources: - - pattern: | - "=~/^http://.+/i" + - python + pattern-either: + - pattern: ssl.PROTOCOL_SSLv2 + - pattern: ssl.PROTOCOL_SSLv3 + - pattern: ssl.PROTOCOL_TLSv1 + - pattern: ssl.PROTOCOL_TLSv1_1 + - pattern: pyOpenSSL.SSL.SSLv2_METHOD + - pattern: pyOpenSSL.SSL.SSLv23_METHOD + - pattern: pyOpenSSL.SSL.SSLv3_METHOD + - pattern: pyOpenSSL.SSL.TLSv1_METHOD + - pattern: pyOpenSSL.SSL.TLSv1_1_METHOD severity: WARNING - - id: java_crypto_rule-HttpGetHTTPRequest + - id: python.lang.security.dangerous-code-run.dangerous-interactive-code-run languages: - - java - message: "Detected an HTTP GET request sent via HttpGet. Sending data over HTTP can\nexpose sensitive information to interception or modification by attackers,\nas HTTP does not encrypt the data transmitted. It is critical to use\nHTTPS, which encrypts the communication, to protect the confidentiality\nand integrity of data in transit.\n\nTo mitigate the issue, ensure all data transmitted between the client and \nserver is sent over HTTPS. Update all HTTP URLs to HTTPS and configure your \nserver to redirect HTTP requests to HTTPS. Additionally, implement HSTS \n(HTTP Strict Transport Security) to enforce secure connections.\n\nSecure Code Example:\n```\nprivate static void safe() throws IOException {\n HttpGet httpGet = new HttpGet(\"https://example.com\");\n HttpClients.createDefault().execute(httpGet);\n}\n```\n" + - python + message: Found user controlled data inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. metadata: category: security confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A03:2021 - Injection references: - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ subcategory: - vuln technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information + - python mode: taint + options: + symbolic_propagation: true pattern-sinks: - patterns: - - pattern: | - $R = new org.apache.http.client.methods.HttpGet($PROT); + - pattern-either: + - pattern-inside: | + $X = code.InteractiveConsole(...) + ... + - pattern-inside: | + $X = code.InteractiveInterpreter(...) + ... + - pattern-either: + - pattern: | + $X.push($PAYLOAD,...) + - pattern: | + $X.runsource($PAYLOAD,...) + - pattern: | + $X.runcode(code.compile_command($PAYLOAD),...) + - pattern: | + $PL = code.compile_command($PAYLOAD,...) + ... + $X.runcode($PL,...) + - focus-metavariable: $PAYLOAD + - pattern-not: | + $X.push("...",...) + - pattern-not: | + $X.runsource("...",...) + - pattern-not: | + $X.runcode(code.compile_command("..."),...) + - pattern-not: | + $PL = code.compile_command("...",...) ... - $CLIENT. ... .execute($R, ...); - - focus-metavariable: $PROT + $X.runcode($PL,...) pattern-sources: - - pattern: | - "=~/^http:\/\/.+/i" - severity: WARNING - - id: java_crypto_rule_JwtDecodeWithoutVerify - languages: - - java - message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token. - metadata: - category: security - confidence: MEDIUM - cwe: CWE-347 - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW - owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - references: https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures - security-severity: MEDIUM - shortDescription: Improper verification of cryptographic signature - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - subcategory: vuln - technology: jwt - vulnerability_class: Improper Authentication - patterns: - - pattern: | - com.auth0.jwt.JWT.decode(...); - - pattern-not-inside: |- - class $CLASS { - ... - $RETURNTYPE $FUNC (...) { - ... - $VERIFIER.verify(...); - ... - } - } + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession severity: WARNING - - id: java_crypto_rule_JwtNoneAlgorithm + - id: python.lang.security.dangerous-os-exec.dangerous-os-exec languages: - - java - message: | - Detected use of the 'none' algorithm in a JWT token. The 'none' - algorithm assumes the integrity of the token has already been verified. - This would allow a malicious actor to forge a JWT token that will - automatically be verified. Do not explicitly use the 'none' algorithm. - Instead, use an algorithm such as 'HS256'. - - For more information on how to securely use JWT please see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html + - python + message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. metadata: asvs: - control_id: 3.5.3 Insecue Stateless Session Tokens - control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management - section: 'V3: Session Management Verification Requirements' + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' version: "4" category: security - confidence: LOW - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - security-severity: CRITICAL - shortDescription: Use of a broken or risky cryptographic algorithm - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ subcategory: - - audit + - vuln technology: - - jwt - vulnerability_class: - - Cryptographic Issues - pattern-either: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: - patterns: - - pattern: | - io.jsonwebtoken.Jwts.builder() - - pattern-not-inside: | - $RETURNTYPE $FUNC(...) { - ... - $JWTS.signWith(...); - ... - } - - pattern: | - $J.sign(com.auth0.jwt.algorithms.Algorithm.none()) - - pattern: | - new com.nimbusds.jose.PlainHeader(...); - - pattern: | - new com.nimbusds.jose.PlainHeader.Builder(). ... .build(); + - pattern-either: + - patterns: + - pattern-not: os.$METHOD("...", ...) + - pattern: os.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (execl|execle|execlp|execlpe|execv|execve|execvp|execvpe) + - patterns: + - pattern-not: os.$METHOD("...", [$PATH,"...","...",...],...) + - pattern-inside: os.$METHOD($BASH,[$PATH,"-c",$CMD,...],...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (execv|execve|execvp|execvpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-not: os.$METHOD("...", $PATH, "...", "...",...) + - pattern-inside: os.$METHOD($BASH, $PATH, "-c", $CMD,...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (execl|execle|execlp|execlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession severity: ERROR - - id: java_crypto_rule-SocketRequestUnsafeProtocols + - id: python.lang.security.dangerous-spawn-process.dangerous-spawn-process languages: - - java - message: | - This code establishes a network connection using an insecure protocol - (HTTP, FTP, or Telnet). These protocols transmit data in cleartext, which - can be intercepted and read by malicious actors. This exposure of - sensitive information violates security best practices and can lead to - data breaches. - - To mitigate the vulnerability, consider using secure protocols that encrypt - the transmission of data. For web traffic, replace HTTP with HTTPS, which - uses SSL/TLS to protect the data in transit. For file transfers, use SFTP - or FTPS instead of FTP. For remote terminal access, use SSH instead of Telnet. - - Secure Code Example: - ``` - public void safe() { - BufferedReader in = null; - PrintWriter out = null; - Socket pingSocket = null; - try{ - pingSocket = new Socket("ssh://example.com", 22); - out = new PrintWriter(pingSocket.getOutputStream(), true); - in = new BufferedReader(new InputStreamReader(pingSocket.getInputStream())); - out.println("ping"); - System.out.println(in.readLine()); - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - if (in != null) in.close(); - if (pingSocket != null) pingSocket.close(); - } catch (IOException e) { - System.out.println("Failed to close resources: " + e.getMessage()); - } - } - } - ``` + - python + message: Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security - confidence: LOW - cwe: CWE-319 + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html + subcategory: + - vuln technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information - pattern-either: - - pattern: | - $SOCKET = new java.net.Socket("=~/^ftp://.+/i", ...); - - pattern: | - $SOCKET = new java.net.Socket("=~/^http://.+/i", ...); - - pattern: | - $SOCKET = new java.net.Socket("=~/^telnet://.+/i", ...); + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: - patterns: - - pattern: | - $SOCKET = new java.net.Socket("...", $PORT); - - metavariable-comparison: - comparison: $PORT in [23,21,80] - metavariable: $PORT - severity: WARNING - - id: java_crypto_rule-SpringFTPRequest + - pattern-either: + - patterns: + - pattern-not: os.$METHOD($MODE, "...", ...) + - pattern-inside: os.$METHOD($MODE, $CMD, ...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe|spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp|startfile) + - patterns: + - pattern-not: os.$METHOD($MODE, "...", ["...","...",...], ...) + - pattern-inside: os.$METHOD($MODE, $BASH, ["-c",$CMD,...],...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnv|spawnve|spawnvp|spawnvp|spawnvpe|posix_spawn|posix_spawnp) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + - patterns: + - pattern-not: os.$METHOD($MODE, "...", "...", "...", ...) + - pattern-inside: os.$METHOD($MODE, $BASH, "-c", $CMD,...) + - pattern: $CMD + - metavariable-regex: + metavariable: $METHOD + regex: (spawnl|spawnle|spawnlp|spawnlpe) + - metavariable-regex: + metavariable: $BASH + regex: (.*)(sh|bash|ksh|csh|tcsh|zsh) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - pattern: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + - patterns: + - pattern-either: + - pattern: os.environ['$ANYTHING'] + - pattern: os.environ.get('$FOO', ...) + - pattern: os.environb['$ANYTHING'] + - pattern: os.environb.get('$FOO', ...) + - pattern: os.getenv('$ANYTHING', ...) + - pattern: os.getenvb('$ANYTHING', ...) + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: sys.argv[...] + - pattern: sys.orig_argv[...] + - patterns: + - pattern-inside: | + $PARSER = argparse.ArgumentParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-inside: | + $PARSER = optparse.OptionParser(...) + ... + - pattern-inside: | + $ARGS = $PARSER.parse_args() + - pattern: <... $ARGS ...> + - patterns: + - pattern-either: + - pattern-inside: | + $OPTS, $ARGS = getopt.getopt(...) + ... + - pattern-inside: | + $OPTS, $ARGS = getopt.gnu_getopt(...) + ... + - pattern-either: + - patterns: + - pattern-inside: | + for $O, $A in $OPTS: + ... + - pattern: $A + - pattern: $ARGS + severity: ERROR + - id: python.lang.security.dangerous-subinterpreters-run-string.dangerous-subinterpreters-run-string languages: - - java - message: "This pattern detects configurations where the Spring Integration FTP plugin \nis used to set up connections to FTP servers. FTP is an insecure protocol \nthat transmits data, including potentially sensitive information, in plaintext. \nThis can expose personal identifiable information (PII) or other sensitive data \nto interception by attackers during transmission. \n\nTo mitigate the vulnerability, switch to a secure protocol such as SFTP or FTPS \nthat encrypts the connection to prevent data exposure. Ensure that any method \nused to set the host for an FTP session does not use plaintext FTP. \n\nSecure Code Example:\n```\npublic SessionFactory safe(FtpSessionFactoryProperties properties) {\n DefaultFtpSessionFactory ftpSessionFactory = new DefaultFtpSessionFactory();\n ftpSessionFactory.setHost(\"sftp://example.com\");\n ftpSessionFactory.setPort(properties.getPort());\n ftpSessionFactory.setUsername(properties.getUsername());\n ftpSessionFactory.setPassword(properties.getPassword());\n ftpSessionFactory.setClientMode(properties.getClientMode().getMode());\n return ftpSessionFactory;\n}\n```\n" + - python + message: Found user controlled content in `run_string`. This is dangerous because it allows a malicious actor to run arbitrary Python code. metadata: category: security confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A03:2021 - Injection references: - - https://docs.spring.io/spring-integration/api/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.html#setClientMode-int- - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://bugs.python.org/issue43472 + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ subcategory: - vuln technology: - - spring - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information + - python mode: taint + options: + symbolic_propagation: true pattern-sinks: - patterns: - pattern: | - (org.springframework.integration.ftp.session.DefaultFtpSessionFactory - $SF).setHost($URL); - - focus-metavariable: $URL + _xxsubinterpreters.run_string($ID, $PAYLOAD, ...) + - pattern-not: | + _xxsubinterpreters.run_string($ID, "...", ...) + - focus-metavariable: $PAYLOAD pattern-sources: - - pattern: | - "=~/^ftp://.+/i" + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession severity: WARNING - - id: java_crypto_rule-SpringHTTPRequestRestTemplate + - id: python.lang.security.dangerous-subprocess-use.dangerous-subprocess-use languages: - - java - message: "This rule detects instances where Java Spring's RestTemplate API sends \nrequests to non-secure (http://) URLs. Sending data over HTTP is vulnerable \nas it does not use TLS encryption, exposing the data to interception, \nmodification, or redirection by attackers. \n\nTo mitigate this vulnerability, modify the request URLs to use HTTPS instead, \nwhich ensures that the data is encrypted during transit and prevents from\nMITM attacks. \n\nSecure Code Example:\n```\npublic void safe(Object obj) throws Exception {\n RestTemplate restTemplate = new RestTemplate();\n restTemplate.put(URI.create(\"https://example.com\"), obj);\n}\n``` \n" + - python + message: Detected subprocess function '$FUNC' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.escape()'. metadata: + asvs: + control_id: 5.3.8 OS Command Injection + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#delete-java.lang.String-java.util.Map- - - https://www.baeldung.com/rest-template - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess + - https://docs.python.org/3/library/subprocess.html + - https://docs.python.org/3/library/shlex.html + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ subcategory: - vuln technology: - - spring - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information + - python mode: taint + options: + symbolic_propagation: true pattern-sinks: - patterns: - - pattern: | - (org.springframework.web.client.RestTemplate $RESTTEMP).$FUNC($URL, ...); - - focus-metavariable: $URL - - metavariable-regex: - metavariable: $FUNC - regex: (delete|doExecute|exchange|getForEntity|getForObject|headForHeaders|optionsForAllow|patchForObject|postForEntity|postForLocation|postForObject|put|execute) + - pattern-either: + - patterns: + - pattern-not: subprocess.$FUNC("...", ...) + - pattern-not: subprocess.$FUNC(["...",...], ...) + - pattern-not: subprocess.$FUNC(("...",...), ...) + - pattern-not: subprocess.CalledProcessError(...) + - pattern-not: subprocess.SubprocessError(...) + - pattern: subprocess.$FUNC($CMD, ...) + - patterns: + - pattern-not: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...) + - pattern: subprocess.$FUNC("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD) + - patterns: + - pattern-not: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...],...) + - pattern-not: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c","...",...),...) + - pattern-either: + - pattern: subprocess.$FUNC(["=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD], ...) + - pattern: subprocess.$FUNC(("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c", $CMD), ...) + - patterns: + - pattern-not: subprocess.$FUNC("=~/(python)/","...",...) + - pattern: subprocess.$FUNC("=~/(python)/", $CMD) + - patterns: + - pattern-not: subprocess.$FUNC(["=~/(python)/","...",...],...) + - pattern-not: subprocess.$FUNC(("=~/(python)/","...",...),...) + - pattern-either: + - pattern: subprocess.$FUNC(["=~/(python)/", $CMD],...) + - pattern: subprocess.$FUNC(("=~/(python)/", $CMD),...) + - focus-metavariable: $CMD pattern-sources: - - pattern: | - "=~/^http:\/\/.+/i" - severity: WARNING - - id: java_crypto_rule-TLSUnsafeRenegotiation + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: ERROR + - id: python.lang.security.dangerous-system-call.dangerous-system-call languages: - - java - message: "This code enables unsafe renegotiation in SSL/TLS connections, which is\nvulnerable to man-in-the-middle attacks. In such attacks, an attacker\ncould inject chosen plaintext at the beginning of the secure\ncommunication, potentially compromising the security of data transmission. If \nexploited, this vulnerability can lead to unauthorized access to sensitive \ndata, data manipulation, and potentially full system compromise depending on \nthe data and operations protected by the TLS session.\n\nTo mitigate this vulnerability, disable unsafe renegotiation in the Java \napplication. Ensure that only secure renegotiation is allowed by setting the \nsystem property `sun.security.ssl.allowUnsafeRenegotiation` to `false`. \n\nSecure code example:\n```\npublic void safe() {\n java.lang.System.setProperty(\"sun.security.ssl.allowUnsafeRenegotiation\", false);\n}\n```\n" + - python + message: Found user-controlled data used in a system call. This could allow a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability. metadata: + asvs: + control_id: 5.2.4 Dyanmic Code Execution Features + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing-requirements + section: 'V5: Validation, Sanitization and Encoding Verification Requirements' + version: "4" category: security confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: LOW + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: HIGH owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://www.oracle.com/java/technologies/javase/tlsreadme.html - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ + source-rule-url: https://bandit.readthedocs.io/en/latest/plugins/b605_start_process_with_a_shell.html subcategory: - vuln technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information - patterns: - - pattern: | - java.lang.System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", $TRUE); - - metavariable-pattern: - metavariable: $TRUE - pattern-either: + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-not: os.$W("...", ...) + - pattern-either: + - pattern: os.system(...) + - pattern: getattr(os, "system")(...) + - pattern: __import__("os").system(...) + - pattern: getattr(__import__("os"), "system")(...) - pattern: | - true + $X = __import__("os") + ... + $X.system(...) - pattern: | - "true" + $X = __import__("os") + ... + getattr($X, "system")(...) - pattern: | - Boolean.TRUE - severity: WARNING - - id: java_crypto_rule-TelnetRequest + $X = getattr(os, "system") + ... + $X(...) + - pattern: | + $X = __import__("os") + ... + $Y = getattr($X, "system") + ... + $Y(...) + - pattern: os.popen(...) + - pattern: os.popen2(...) + - pattern: os.popen3(...) + - pattern: os.popen4(...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: ERROR + - id: python.lang.security.dangerous-testcapi-run-in-subinterp.dangerous-testcapi-run-in-subinterp languages: - - java - message: "Checks for attempts to connect through telnet. Telnet is an outdated\nprotocol that transmits all data, including sensitive information like\npasswords, in clear text. This exposes it to interception and\neavesdropping on unsecured networks.\n\nTo mitigate this issue, replace Telnet usage with more secure protocols \nsuch as SSH (Secure Shell), which provides encrypted communication. Use \nthe SSH functionality provided by libraries like JSch or Apache MINA SSHD \nfor secure data transmission.\n\nSecure Code Example:\n```\nimport com.jcraft.jsch.JSch;\nimport com.jcraft.jsch.Session;\n\npublic class SecureConnector {\n public static void main(String[] args) {\n try {\n JSch jsch = new JSch();\n Session session = jsch.getSession(\"username\", \"hostname\", 22);\n session.setPassword(\"password\");\n session.setConfig(\"StrictHostKeyChecking\", \"no\");\n session.connect();\n System.out.println(\"Connected securely.\");\n } catch (Exception e) {\n System.err.println(\"Secure connection failed: \" + e.getMessage());\n }\n }\n}\n```\n" + - python + message: Found user controlled content in `run_in_subinterp`. This is dangerous because it allows a malicious actor to run arbitrary Python code. metadata: category: security confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + cwe: + - 'CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (''Eval Injection'')' + impact: HIGH + likelihood: HIGH owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A03:2021 - Injection references: - - https://commons.apache.org/proper/commons-net/javadocs/api-3.6/org/apache/commons/net/telnet/TelnetClient.html - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://semgrep.dev/docs/cheat-sheets/python-command-injection/ subcategory: - vuln technology: - - java - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information - pattern: | - (org.apache.commons.net.telnet.TelnetClient $TELNETCLIENT).connect(...); + - python + mode: taint + options: + symbolic_propagation: true + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + _testcapi.run_in_subinterp($PAYLOAD, ...) + - pattern: | + test.support.run_in_subinterp($PAYLOAD, ...) + - focus-metavariable: $PAYLOAD + - pattern-not: | + _testcapi.run_in_subinterp("...", ...) + - pattern-not: | + test.support.run_in_subinterp("...", ...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: flask.request.form.get(...) + - pattern: flask.request.form[...] + - pattern: flask.request.args.get(...) + - pattern: flask.request.args[...] + - pattern: flask.request.values.get(...) + - pattern: flask.request.values[...] + - pattern: flask.request.cookies.get(...) + - pattern: flask.request.cookies[...] + - pattern: flask.request.stream + - pattern: flask.request.headers.get(...) + - pattern: flask.request.headers[...] + - pattern: flask.request.data + - pattern: flask.request.full_path + - pattern: flask.request.url + - pattern: flask.request.json + - pattern: flask.request.get_json() + - pattern: flask.request.view_args.get(...) + - pattern: flask.request.view_args[...] + - patterns: + - pattern-inside: | + @$APP.route(...) + def $FUNC(..., $ROUTEVAR, ...): + ... + - focus-metavariable: $ROUTEVAR + - patterns: + - pattern-inside: | + def $FUNC(request, ...): + ... + - pattern-either: + - pattern: request.$PROPERTY.get(...) + - pattern: request.$PROPERTY[...] + - patterns: + - pattern-either: + - pattern-inside: | + @rest_framework.decorators.api_view(...) + def $FUNC($REQ, ...): + ... + - patterns: + - pattern-either: + - pattern-inside: | + class $VIEW(..., rest_framework.views.APIView, ...): + ... + - pattern-inside: "class $VIEW(..., rest_framework.generics.GenericAPIView, ...):\n ... \n" + - pattern-inside: | + def $METHOD(self, $REQ, ...): + ... + - metavariable-regex: + metavariable: $METHOD + regex: (get|post|put|patch|delete|head) + - pattern-either: + - pattern: $REQ.POST.get(...) + - pattern: $REQ.POST[...] + - pattern: $REQ.FILES.get(...) + - pattern: $REQ.FILES[...] + - pattern: $REQ.DATA.get(...) + - pattern: $REQ.DATA[...] + - pattern: $REQ.QUERY_PARAMS.get(...) + - pattern: $REQ.QUERY_PARAMS[...] + - pattern: $REQ.data.get(...) + - pattern: $REQ.data[...] + - pattern: $REQ.query_params.get(...) + - pattern: $REQ.query_params[...] + - pattern: $REQ.content_type + - pattern: $REQ.content_type + - pattern: $REQ.stream + - pattern: $REQ.stream + - patterns: + - pattern-either: + - pattern-inside: | + class $SERVER(..., http.server.BaseHTTPRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.StreamRequestHandler, ...): + ... + - pattern-inside: | + class $SERVER(..., http.server.DatagramRequestHandler, ...): + ... + - pattern-either: + - pattern: self.requestline + - pattern: self.path + - pattern: self.headers[...] + - pattern: self.headers.get(...) + - pattern: self.rfile + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession severity: WARNING - - id: java_crypto_rule-UnirestHTTPRequest + - fix-regex: + count: 1 + regex: unsafe_load + replacement: safe_load + id: python.lang.security.deserialization.avoid-pyyaml-load.avoid-pyyaml-load languages: - - java - message: "This application uses the Unirest library to send\nnetwork requests to URLs starting with 'http://'. Communicating over HTTP\nis considered insecure because it does not encrypt traffic with TLS\n(Transport Layer Security), exposing data to potential interception or\nmanipulation by attackers.\n\nTo mitigate the issue, modify the request URL to begin with 'https://' \ninstead of 'http://'. Using HTTPS ensures that the data is encrypted and \nsecure during transmission. Review all instances where HTTP is used and \nupdate them to use HTTPS to prevent security risks.\n\nSecure Code Example:\n```\nimport kong.unirest.core.Unirest;\n\npublic void safe() {\n Unirest.get(\"https://httpbin.org\")\n .queryString(\"fruit\", \"apple\")\n .queryString(\"droid\", \"R2D2\")\n .asString();\n}\n```\n" + - python + message: Detected a possible YAML deserialization vulnerability. `yaml.unsafe_load`, `yaml.Loader`, `yaml.CLoader`, and `yaml.UnsafeLoader` are all known to be unsafe methods of deserializing YAML. An attacker with control over the YAML input could create special YAML input that allows the attacker to run arbitrary Python code. This would allow the attacker to steal files, download and install malware, or otherwise take over the machine. Use `yaml.safe_load` or `yaml.SafeLoader` instead. metadata: category: security confidence: MEDIUM - cwe: CWE-319 + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures references: - - https://kong.github.io/unirest-java/#requests - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation + - https://nvd.nist.gov/vuln/detail/CVE-2017-18342 subcategory: - - vuln + - audit technology: - - unirest - vulnerability: Insecure Transport - vulnerability_class: - - Mishandled Sensitive Information + - pyyaml patterns: - - pattern: | - Unirest.$METHOD("=~/[hH][tT][tT][pP]://.*/") - severity: WARNING - - id: java_crypto_rule-UseOfRC2 + - pattern-inside: | + import yaml + ... + - pattern-not-inside: | + $YAML = ruamel.yaml.YAML(...) + ... + - pattern-either: + - pattern: yaml.unsafe_load(...) + - pattern: yaml.load(..., Loader=yaml.Loader, ...) + - pattern: yaml.load(..., Loader=yaml.UnsafeLoader, ...) + - pattern: yaml.load(..., Loader=yaml.CLoader, ...) + - pattern: yaml.load_all(..., Loader=yaml.Loader, ...) + - pattern: yaml.load_all(..., Loader=yaml.UnsafeLoader, ...) + - pattern: yaml.load_all(..., Loader=yaml.CLoader, ...) + severity: ERROR + - id: python.lang.security.deserialization.avoid-unsafe-ruamel.avoid-unsafe-ruamel languages: - - java - message: "Use of RC2, a deprecated cryptographic algorithm vulnerable to related-key\nattacks, was detected. Modern cryptographic standards recommend the\nadoption of algorithms that integrate message integrity to ensure the\nciphertext remains unaltered.\n\nTo mitigate the issue, use any of the below algorithms instead:\n1. `ChaCha20Poly1305` - Preferred for its simplicity and speed, suitable for \nenvironments where cryptographic acceleration is absent.\n2. `AES-256-GCM` - Highly recommended when hardware support is available, \ndespite being somewhat slower than `ChaCha20Poly1305`. It is crucial to avoid \nnonce reuse with AES-256-GCM to prevent security compromises.\n\nSecure code example using `ChaCha20Poly1305` in Java:\n```\npublic void encryptAndDecrypt() throws Exception {\n SecureRandom random = new SecureRandom();\n byte[] secretKey = new byte[32]; // 256-bit key\n byte[] nonce = new byte[12]; // 96-bit nonce\n random.nextBytes(secretKey);\n random.nextBytes(nonce);\n\n Cipher cipher = Cipher.getInstance(\"ChaCha20-Poly1305/None/NoPadding\");\n SecretKeySpec keySpec = new SecretKeySpec(secretKey, \"ChaCha20\");\n GCMParameterSpec spec = new GCMParameterSpec(128, nonce);\n\n cipher.init(Cipher.ENCRYPT_MODE, keySpec, spec);\n byte[] plaintext = \"Secret text\".getBytes(StandardCharsets.UTF_8);\n byte[] ciphertext = cipher.doFinal(plaintext);\n System.out.println(\"Encrypted: \" + Base64.getEncoder().encodeToString(ciphertext));\n\n cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);\n byte[] decrypted = cipher.doFinal(ciphertext);\n System.out.println(\"Decrypted: \" + new String(decrypted, StandardCharsets.UTF_8));\n}\n```\nFor more on Java Cryptography, refer:\nhttps://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html\n" + - python + message: Avoid using unsafe `ruamel.yaml.YAML()`. `ruamel.yaml.YAML` can create arbitrary Python objects. A malicious actor could exploit this to run arbitrary code. Use `YAML(typ='rt')` or `YAML(typ='safe')` instead. metadata: category: security - confidence: HIGH - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - security-severity: MEDIUM - shortDescription: Use of a broken or risky cryptographic algorithm + - https://yaml.readthedocs.io/en/latest/basicuse.html?highlight=typ subcategory: - - vuln + - audit technology: - - java + - ruamel.yaml pattern-either: - - pattern: | - javax.crypto.Cipher.getInstance("RC2") - - patterns: - - pattern-inside: | - class $CLS{ - ... - String $ALG = "RC2"; - ... - } - - pattern: | - javax.crypto.Cipher.getInstance($ALG); - severity: WARNING - - id: java_crypto_rule-UseOfRC4 + - pattern: ruamel.yaml.YAML(..., typ='unsafe', ...) + - pattern: ruamel.yaml.YAML(..., typ='base', ...) + severity: ERROR + - id: python.lang.security.deserialization.pickle.avoid-shelve languages: - - java - message: "Use of RC4 was detected. RC4 is vulnerable to several types of attacks,\nincluding stream cipher attacks where attackers can recover plaintexts by\nanalyzing a large number of encrypted messages, and bit-flipping attacks\nthat can alter messages without knowing the encryption key.\n\nTo mitigate the issue, use any of the below algorithms instead:\n1. `ChaCha20Poly1305` - Preferred for its simplicity and speed, suitable for \nenvironments where cryptographic acceleration is absent.\n2. `AES-256-GCM` - Highly recommended when hardware support is available, \ndespite being somewhat slower than `ChaCha20Poly1305`. It is crucial to avoid \nnonce reuse with AES-256-GCM to prevent security compromises.\n\nSecure code example using `ChaCha20Poly1305` in Java:\n```\npublic void encryptAndDecrypt() throws Exception {\n SecureRandom random = new SecureRandom();\n byte[] secretKey = new byte[32]; // 256-bit key\n byte[] nonce = new byte[12]; // 96-bit nonce\n random.nextBytes(secretKey);\n random.nextBytes(nonce);\n\n Cipher cipher = Cipher.getInstance(\"ChaCha20-Poly1305/None/NoPadding\");\n SecretKeySpec keySpec = new SecretKeySpec(secretKey, \"ChaCha20\");\n GCMParameterSpec spec = new GCMParameterSpec(128, nonce);\n\n cipher.init(Cipher.ENCRYPT_MODE, keySpec, spec);\n byte[] plaintext = \"Secret text\".getBytes(StandardCharsets.UTF_8);\n byte[] ciphertext = cipher.doFinal(plaintext);\n System.out.println(\"Encrypted: \" + Base64.getEncoder().encodeToString(ciphertext));\n\n cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);\n byte[] decrypted = cipher.doFinal(ciphertext);\n System.out.println(\"Decrypted: \" + new String(decrypted, StandardCharsets.UTF_8));\n}\n```\nFor more information, refer:\nhttps://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions\n" + - python + message: Avoid using `shelve`, which uses `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format. metadata: category: security - confidence: HIGH - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true impact: MEDIUM - likelihood: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html - security-severity: MEDIUM - shortDescription: Use of a broken or risky cryptographic algorithm + - https://docs.python.org/3/library/pickle.html subcategory: - - vuln + - audit technology: - - java - pattern-either: - - pattern: | - javax.crypto.Cipher.getInstance("RC4") - - patterns: - - pattern-inside: | - class $CLS{ - ... - String $ALG = "RC4"; - ... - } - - pattern: | - javax.crypto.Cipher.getInstance($ALG); - severity: WARNING - - id: java_csrf_rule-SpringCSRFDisabled - languages: - - java - message: "The application fails to protect against Cross-Site Request Forgery (CSRF)\ndue to disabling Spring's CSRF protection features.\n\nThis vulnerability may allow attackers to carry out CSRF attacks by crafting \nmalicious links or forms on external websites. Victims who are tricked into \naccessing these links while authenticated in your application could inadvertently \nperform actions that the attacker intends, such as changing user information, \ninitiating transactions, or altering permissions.\n\nTo remediate this issue, remove the call to `HttpSecurity.csrf().disable()` or \nremove the custom `CsrfConfigurer`.\n\nFor more information on CSRF protection in Spring see:\nhttps://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html#servlet-csrf\n\nAdditionally, consider setting all session cookies to have the `SameSite=Strict` \nattribute. It should be noted that this may impact usability when sharing links \nacross other mediums.\nIt is recommended that a two cookie based approach is taken, as outlined in the\n[Top level\nnavigations](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-08#section-8.8.2)\nsection of the SameSite RFC.\n\nFor more information on CSRF see OWASP's guide:\nhttps://owasp.org/www-community/attacks/csrf\n" - metadata: - category: security - cwe: CWE-352 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Cross-Site Request Forgery (CSRF) - pattern-either: - - pattern: (org.springframework.security.config.annotation.web.builders.HttpSecurity $H). ... .csrf(...). ... .requireCsrfProtectionMatcher(...) - - pattern: (org.springframework.security.config.annotation.web.builders.HttpSecurity $H). ... .csrf(...). ... .disable(...) - - pattern: (org.springframework.security.config.annotation.web.configurers.CsrfConfigurer $C). ... .disable(); + - python + pattern: shelve.$FUNC(...) severity: WARNING - - id: java_csrf_rule-UnrestrictedRequestMapping + - id: python.lang.security.insecure-hash-algorithms-md5.insecure-hash-algorithm-md5 languages: - - java - message: "Detected a method annotated with 'RequestMapping' that does not specify\nthe HTTP method. CSRF protections are not enabled for GET, HEAD, TRACE, or\nOPTIONS, and by default all HTTP methods are allowed when the HTTP method\nis not explicitly specified. This means that a method that performs state\nchanges could be vulnerable to CSRF attacks. Cross-Site Request Forgery (CSRF) \nis a security vulnerability where an attacker tricks a user into performing \nunintended actions on a web application where they are authenticated. This \ncan lead to unauthorized actions like changing user settings, transferring \nfunds, or altering passwords, all without the user's knowledge, by exploiting \nthe trust a web application has in the user's browser.\n\nTo mitigate, add the 'method' field and specify the HTTP method (such as \n'RequestMethod.POST').\n\nSecure Code Example:\n```\n@RequestMapping(value = \"/path\", method = RequestMethod.POST)\npublic void safe() {\n // State-changing operations performed within this method.\n}\n```\n" + - python + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: + asvs: + control_id: 6.2.2 Insecure Custom Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + bandit-code: B303 category: security - confidence: LOW - cwe: CWE-352 - cwe2021-top25: "true" - cwe2022-top25: "true" + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING - security-severity: MEDIUM - shortDescription: Cross-site request forgery (CSRF) - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 subcategory: - - audit + - vuln technology: - - spring - vulnerability_class: - - Cross-Site Request Forgery (CSRF) + - python patterns: - - pattern-inside: | - @RequestMapping(...) - $RETURNTYPE $METHOD(...) { ... } - - pattern-not-inside: | - @RequestMapping(..., method = $X, ...) - $RETURNTYPE $METHOD(...) { ... } - - pattern: | - RequestMapping + - pattern: hashlib.md5(...) + - pattern-not: hashlib.md5(..., usedforsecurity=False, ...) severity: WARNING - - id: java_deserialization_rule-InsecureJmsDeserialization + - fix-regex: + regex: sha1 + replacement: sha256 + id: python.lang.security.insecure-hash-algorithms.insecure-hash-algorithm-sha1 languages: - - java - message: "Deserialization of untrusted JMS ObjectMessage can lead to arbitrary \ncode execution. This vulnerability occurs when `ObjectMessage.getObject()` \nis called to deserialize the payload of an ObjectMessage, potentially \nallowing remote attackers to execute arbitrary code with the permissions \nof the JMS MessageListener application. \n\nTo mitigate the issue, avoid deserialization of untrusted data and \nconsider alternative message formats or explicit whitelisting of \nallowable classes for deserialization.\n\nTo implement allowlisting, override the ObjectInputStream#resolveClass() \nmethod to limit deserialization to allowed classes only. This prevents \ndeserialization of any class except those explicitly permitted, such as \nin the following example that restricts deserialization to the Bicycle \nclass only:\n\n```\n// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html\npublic class LookAheadObjectInputStream extends ObjectInputStream {\n public LookAheadObjectInputStream(InputStream inputStream) throws IOException {\n super(inputStream);\n }\n /**\n * Only deserialize instances of our expected Bicycle class\n */\n @Override\n protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {\n if (!desc.getName().equals(Bicycle.class.getName())) {\n throw new InvalidClassException(\"Unauthorized deserialization attempt\", desc.getName());\n }\n return super.resolveClass(desc);\n }\n}\n```\n" + - python + message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: + asvs: + control_id: 6.2.2 Insecure Custom Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" + bandit-code: B303 category: security confidence: MEDIUM - cwe: CWE-502 - cwe2021-top25: "true" - cwe2022-top25: "true" + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] likelihood: LOW owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities-wp.pdf - security-severity: High - shortDescription: Deserialization of untrusted data + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 subcategory: - vuln technology: - - java - vulnerability_class: - - 'Insecure Deserialization ' - patterns: - - pattern-inside: | - class $JMS_LISTENER implements MessageListener { - ... - public void onMessage(Message $JMS_MSG) { - ... - } - } - - pattern: $Y.getObject(...); - severity: ERROR - - id: java_deserialization_rule-ServerDangerousObjectDeserialization + - python + pattern: hashlib.sha1(...) + severity: WARNING + - id: python.lang.security.insecure-hash-function.insecure-hash-function languages: - - java - message: "This application uses Java RMI (Remote Method Invocation) interfaces \nthat declare methods with parameters of arbitrary objects \n('$PARAMTYPE $PARAM') that could lead to insecure deserialization \nvulnerabilities. Insecure deserialization occurs when an application \ndeserializes data from untrusted sources without proper sanitization, \npotentially leading to arbitrary code execution, denial of service attacks, \nand other critical vulnerabilities.\n\nJava RMI allows for remote communication between applications by \ninvoking methods on remote objects. When complex objects are used \nas parameters in RMI method declarations, there is \na risk that a malicious actor could exploit the deserialization \nprocess to execute arbitrary code on the server. This vulnerability \nis especially significant if the parameter types are not among the safe, \nimmutable types like String, Integer, etc.\n\nTo mitigate this vulnerability, use an integer ID to look up your \nobject, or consider alternative serialization schemes such as JSON.\n\nSecure Code Example:\n```\nimport java.rmi.Remote;\nimport java.rmi.RemoteException;\n\npublic interface SafeTicketService extends Remote {\n // Using String, which is a safe, immutable type\n boolean registerTicket(String ticketID) throws RemoteException;\n\n // Using primitive data types and wrappers, which are safe\n void visitTalk(int talkID) throws RemoteException;\n void poke(Integer attendeeID) throws RemoteException;\n}\n```\n" + - python + message: Detected use of an insecure MD4 or MD5 hash function. These functions have known vulnerabilities and are considered deprecated. Consider using 'SHA256' or a similar function instead. metadata: + asvs: + control_id: 6.2.2 Insecure Custom Algorithm + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x14-V6-Cryptography.md#v62-algorithms + section: V6 Stored Cryptography Verification Requirements + version: "4" category: security - confidence: LOW - cwe: CWE-502 - cwe2021-top25: "true" - cwe2022-top25: "true" - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM likelihood: LOW owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://frohoff.github.io/appseccali-marshalling-pickles/ - - https://book.hacktricks.xyz/network-services-pentesting/1099-pentesting-java-rmi - - https://youtu.be/t_aw1mDNhzI - - https://github.com/qtc-de/remote-method-guesser - - https://github.com/openjdk/jdk/blob/master/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java#L303C4-L331 - - https://mogwailabs.de/en/blog/2019/03/attacking-java-rmi-services-after-jep-290/ - security-severity: MEDIUM - shortDescription: Deserialization of untrusted data + - https://tools.ietf.org/html/rfc6151 + - https://crypto.stackexchange.com/questions/44151/how-does-the-flame-malware-take-advantage-of-md5-collision + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/hashlib_new_insecure_functions.py + subcategory: + - audit technology: - - rmi - vulnerability_class: - - 'Insecure Deserialization ' - patterns: - - pattern-inside: | - interface $INTERFACE extends Remote { - ... - } - - pattern: | - $RETURNTYPE $METHOD($PARAMTYPE $PARAM) throws RemoteException; - - metavariable-pattern: - language: generic - metavariable: $PARAMTYPE - patterns: - - pattern-not: String - - pattern-not: java.lang.String - - pattern-not: boolean - - pattern-not: Boolean - - pattern-not: java.lang.Boolean - - pattern-not: byte - - pattern-not: Byte - - pattern-not: java.lang.Byte - - pattern-not: char - - pattern-not: Character - - pattern-not: java.lang.Character - - pattern-not: double - - pattern-not: Double - - pattern-not: java.lang.Double - - pattern-not: float - - pattern-not: Float - - pattern-not: java.lang.Float - - pattern-not: int - - pattern-not: Integer - - pattern-not: java.lang.Integer - - pattern-not: long - - pattern-not: Long - - pattern-not: java.lang.Long - - pattern-not: short - - pattern-not: Short - - pattern-not: java.lang.Short + - python + pattern-either: + - pattern: hashlib.new("=~/[M|m][D|d][4|5]/", ...) + - pattern: hashlib.new(..., name="=~/[M|m][D|d][4|5]/", ...) severity: WARNING - - id: java_deserialization_rule-SnakeYamlConstructor + - fix-regex: + regex: _create_unverified_context + replacement: create_default_context + id: python.lang.security.unverified-ssl-context.unverified-ssl-context languages: - - java - message: "The application uses SnakeYAML org.yaml.snakeyaml.Yaml() constructor \nwith no arguments, which is vulnerable to deserialization attacks. \nWhen Yaml() (no-argument constructor) is used, SnakeYAML uses the \ndefault Constructor which can instantiate any Java object during \ndeserialization. This is risky because an attacker could craft malicious \nYAML files to execute arbitrary code or perform unauthorized actions.\n\nTo mitigate the issue and to safely use SnakeYaml to parse YAML data, \nalways make sure to only ever use a Yaml instance that is constructed \neither with a SafeConstructor or an instance constructed with a \nConstructor specifying a specific class. \n\nPlease note, if you want to use Constructor with a specific target class\nas a mitigation criteria, ensure that snakeyaml version is 2.0 or higher\nas Constructor class is vulnerable in snakeyaml versions lower than 2.0.\nRefer - https://github.com/google/security-research/security/advisories/GHSA-mjmj-j48q-9wg2\n\nSecure Code Examples:\n```\npublic void safeConstructorLoad(String toLoad) {\n // Configure LoaderOptions for safe deserialization\n LoaderOptions loaderOptions = new LoaderOptions();\n loaderOptions.setAllowDuplicateKeys(false);\n loaderOptions.setMaxAliasesForCollections(50);\n\n Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptipon()));\n yaml.load(toLoad);\n}\n\npublic void customConstructorLoad(String toLoad, Class goodClass) {\n // Use Constructor with a specific target class\n LoaderOptions loaderOptions = new LoaderOptions();\n Constructor customConstructor = new Constructor(goodClass, loaderOptions);\n\n Yaml yaml = new Yaml(customConstructor);\n yaml.load(toLoad);\n}\n```\n" + - python + message: Unverified SSL context detected. This will permit insecure connections without verifying SSL certificates. Use 'ssl.create_default_context' instead. metadata: category: security - confidence: LOW - cwe: CWE-502 - impact: HIGH + confidence: MEDIUM + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: MEDIUM likelihood: LOW owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures references: - - https://securitylab.github.com/research/swagger-yaml-parser-vulnerability/#snakeyaml-deserialization-vulnerability - security-severity: HIGH - shortDescription: Deserialization of untrusted data + - https://docs.python.org/3/library/ssl.html#ssl-security + - https://docs.python.org/3/library/http.client.html#http.client.HTTPSConnection + subcategory: + - audit technology: - - snakeyaml + - python patterns: - - pattern: | - $Y = new org.yaml.snakeyaml.Yaml(); - ... - $Y.load(...); + - pattern-either: + - pattern: ssl._create_unverified_context(...) + - pattern: ssl._create_default_https_context = ssl._create_unverified_context severity: ERROR - - id: java_endpoint_rule-ManuallyConstructedURLs + - fix: defusedxml.etree.ElementTree.parse($...ARGS) + id: python.lang.security.use-defused-xml-parse.use-defused-xml-parse languages: - - java - message: | - User data flows into the host portion of this manually-constructed URL. - This could allow an attacker to send data to their own server, potentially - exposing sensitive data such as cookies or authorization information sent - with this request. They could also probe internal servers or other - resources that the server running this code can access. (This is called - server-side request forgery, or SSRF.) Do not allow arbitrary hosts. - Instead, create an allowlist for approved hosts hardcode the correct host, - or ensure that the user data can only affect the path or parameters. - - Example of using allowlist: - ``` - ArrayList allowlist = (ArrayList) - Arrays.asList(new String[] { "https://example.com/api/1", "https://example.com/api/2", "https://example.com/api/3"}); - - if(allowlist.contains(url)){ - ... - } - ``` + - python + message: The native Python `xml` library is vulnerable to XML External Entity (XXE) attacks. These attacks can leak confidential data and "XML bombs" can cause denial of service. Do not use this library to parse untrusted input. Instead the Python documentation recommends using `defusedxml`. metadata: category: security confidence: MEDIUM - cwe: CWE-918 + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' cwe2021-top25: true cwe2022-top25: true impact: MEDIUM - interfile: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A10:2021-Server-Side Request Forgery + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration references: - - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - security-severity: CRITICAL - shortDescription: Detect manually constructed URLs + - https://docs.python.org/3/library/xml.html + - https://github.com/tiran/defusedxml + - https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing subcategory: - vuln technology: - - java - - spring - vulnerability_class: - - Server-Side Request Forgery (SSRF) - mode: taint - options: - interfile: true - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: "if($VALIDATION){\n ...\n new URL($ONEARG);\n ...\n} \n" - - pattern: | - $A = $VALIDATION; - ... - if($A){ - ... - new URL($ONEARG); - ... - } - - metavariable-pattern: - metavariable: $VALIDATION - pattern-either: - - pattern: "$AL.contains(...) \n" - - pattern: | - $AL.indexOf(...) != -1 - pattern-sinks: - - pattern-either: - - pattern: new URL($ONEARG) - - patterns: - - pattern-either: - - pattern: | - "$URLSTR" + ... - - pattern: | - "$URLSTR".concat(...) - - patterns: - - pattern-inside: | - StringBuilder $SB = new StringBuilder("$URLSTR"); - ... - - pattern: $SB.append(...) - - patterns: - - pattern-inside: | - $VAR = "$URLSTR"; - ... - - pattern: $VAR += ... - - patterns: - - pattern: String.format("$URLSTR", ...) - - pattern-not: String.format("$URLSTR", "...", ...) - - patterns: - - pattern-inside: | - String $VAR = "$URLSTR"; - ... - - pattern: String.format($VAR, ...) - - metavariable-regex: - metavariable: $URLSTR - regex: http(s?)://%(v|s|q).* - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE + - python + patterns: + - pattern: xml.etree.ElementTree.parse($...ARGS) + - pattern-not: xml.etree.ElementTree.parse("...") severity: ERROR - - id: java_file_rule_rule-FilePathTraversalHttpServlet + - id: python.pycryptodome.security.insecure-cipher-algorithm-blowfish.insecure-cipher-algorithm-blowfish languages: - - java - message: "Detected a potential path traversal. A malicious actor could control\nthe location of this file, to include going backwards in the directory\nwith '../'. \n\nTo address this, ensure that user-controlled variables in file\npaths are sanitized. You may also consider using a utility method such as\norg.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file\nname from the path.\n\nExample code using FilenameUtils.getName(...)\n\n```\npublic void ok(HttpServletRequest request, HttpServletResponse response)\n throws ServletException, IOException {\n String image = request.getParameter(\"image\");\n File file = new File(\"static/images/\", FilenameUtils.getName(image));\n\n if (!file.exists()) {\n log.info(image + \" could not be created.\");\n response.sendError();\n }\n\n response.sendRedirect(\"/index.html\");\n}\n```\n" + - python + message: Detected Blowfish cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. metadata: + bandit-code: B304 category: security confidence: MEDIUM - cwe: CWE-22 - cwe2021-top25: true - cwe2022-top25: true + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://www.owasp.org/index.php/Path_Traversal - security-severity: CRITICAL - shortDescription: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN + - https://stackoverflow.com/questions/1135186/whats-wrong-with-xor-encryption + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 + subcategory: + - vuln technology: - - java - vulnerability_class: - - Path Traversal - mode: taint - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - (java.io.File $FILE) = ... - - pattern: | - (java.io.FileOutputStream $FOS) = ... - - pattern: | - new java.io.FileInputStream(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); ... - for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { - ... - } - - pattern: | - $COOKIE.getValue(...) - - patterns: - - pattern-inside: | - $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(...); - ... - - pattern: | - $PARAM = $VALS[$INDEX]; - severity: ERROR - - id: java_ftp_rule-FTPInsecureTransport + - pycryptodome + pattern-either: + - pattern: Cryptodome.Cipher.Blowfish.new(...) + - pattern: Crypto.Cipher.Blowfish.new(...) + severity: WARNING + - id: python.pycryptodome.security.insecure-cipher-algorithm-des.insecure-cipher-algorithm-des languages: - - java - message: "This rule identifies instances where the application uses FTP (File\nTransfer Protocol) for transferring files. FTP transmits data in clear\ntext, allowing usernames, passwords, and other sensitive information to be\nintercepted by attackers. Consider using secure alternatives like SFTP\n(SSH File Transfer Protocol) or FTPS (FTP Secure) that provide encryption\nto protect data in transit.\n\nRemediation Strategy: To mitigate the risks associated with using unencrypted\nFTP, the application should switch to a secure file transfer protocol like\nSFTP or FTPS. Below is an example of how to implement FTPS in a Java\napplication.\n\n``` \nimport org.apache.commons.net.ftp.FTPSClient;\n\npublic class FTPSExample {\n public static void main(String[] args) {\n String server = \"ftps.example.com\";\n int port = 21;\n String user = \"your_username\";\n String pass = \"your_password\";\n\n FTPSClient ftpsClient = new FTPSClient();\n try {\n ftpsClient.connect(server, port);\n ftpsClient.login(user, pass);\n // Perform file operations\n\n ftpsClient.logout();\n ftpsClient.disconnect();\n } catch (Exception e) {\n e.printStackTrace();\n }\n }\n} \n```\n" + - python + message: Detected DES cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. metadata: + bandit-code: B304 category: security - cwe: CWE-319 - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://www.codejava.net/java-se/ftp/connect-and-login-to-a-ftp-server - - https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://cwe.mitre.org/data/definitions/326.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 subcategory: - vuln technology: - - java - vulnerability: Insecure Transport + - pycryptodome pattern-either: - - pattern: | - (org.apache.commons.net.ftp.FTPClient $FTPCLIENT).connect(...); - - pattern: | - URL $URL = new URL("=~/^[fF][tT][pP]://.*/"); - ... - URLConnection $CONN = $URL.openConnection(...); + - pattern: Cryptodome.Cipher.DES.new(...) + - pattern: Crypto.Cipher.DES.new(...) severity: WARNING - - id: java_inject_rule-DangerousGroovyShell + - id: python.pycryptodome.security.insecure-cipher-algorithm-rc2.insecure-cipher-algorithm-rc2 languages: - - java - message: "This application implements unsafe invocations of methods within the\n`groovy.lang.GroovyShell` or `groovy.lang.GroovyClassLoader` classes,\nwhich are used to evaluate or compile Groovy code dynamically. When\nuser-controlled input is directly passed to `parse`, `evaluate`, or\n`parseClass` methods, it can lead to Remote Code Execution (RCE), where an\nattacker can execute arbitrary code on the server. This could potentially\nallow an attacker to gain unauthorized access to system resources, modify\ninternal application states, or execute commands on the server depending\non the level of permissions assigned to the application process.\n\nTo mitigate this vulnerability, always validate and sanitize all user inputs \nbefore using them in dynamic code evaluations. Consider using safer alternatives \nto executing dynamic code if possible. If dynamic code execution is absolutely \nnecessary, use strict allowlists of safe inputs and context-specific validation.\n\nSecure Code Example:\n\n```\nimport groovy.lang.GroovyShell;\n\nclass SafeDynamicEvaluation {\n private static final Set ALLOWED_EXPRESSIONS = new HashSet<>(Arrays.asList(\n \"println 'Hello World!'\",\n \"println 'Goodbye World!'\"));\n\n public static void test4(String[] args, ClassLoader loader) throws Exception {\n GroovyShell shell = new GroovyShell();\n String userInput = args[0];\n\n // Validate the user input against the allowlist\n if (ALLOWED_EXPRESSIONS.contains(userInput)) {\n shell.evaluate(userInput);\n // shell.parse(userInput);\n } else {\n throw new IllegalArgumentException(\"Invalid or unauthorized command.\");\n }\n }\n}\n```\n" + - python + message: Detected RC2 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. metadata: + bandit-code: B304 category: security - cwe: CWE-94 - cwe2022-top25: "true" - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A03_2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code ('Code Injection') - source-rule-url: https://find-sec-bugs.github.io/bugs.htm#GROOVY_SHELL + - https://cwe.mitre.org/data/definitions/326.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 + subcategory: + - vuln technology: - - groovy - vulnerability_class: - - Code Injection - patterns: - - pattern-either: - - pattern: | - (groovy.lang.GroovyShell $SHELL).parse(...) - - pattern: | - (groovy.lang.GroovyShell $SHELL).evaluate(...) - - pattern: | - (groovy.lang.GroovyClassLoader $SHELL).parseClass(...) - - pattern-not: | - $SHELL.parse("...",...) - - pattern-not: | - $SHELL.evaluate("...",...) - - pattern-not: | - $SHELL.parseClass("...",...) - - pattern-not-inside: | - if($ALLOWLIST.contains($INPUT)){ - ... - } - severity: ERROR - - id: java_inject_rule-EnvInjection + - pycryptodome + pattern-either: + - pattern: Cryptodome.Cipher.ARC2.new(...) + - pattern: Crypto.Cipher.ARC2.new(...) + severity: WARNING + - id: python.pycryptodome.security.insecure-cipher-algorithm-rc4.insecure-cipher-algorithm-rc4 languages: - - java - message: "Detected input from a HTTPServletRequest going into the environment\nvariables of an 'exec' command. The user input is passed directly to\nthe Runtime.exec() function to set an environment variable. This allows \nmalicious input from the user to modify the command that will be executed.\nTo remediate this, do not pass user input directly to Runtime.exec().\nValidate any user input before using it to set environment variables \nor command arguments. Consider using an allow list of allowed values\nrather than a deny list. If dynamic commands must be constructed, use\na map to look up valid values based on user input instead of using \nthe input directly.\nExample of safely executing an OS command:\n```\npublic void doPost(HttpServletRequest request, HttpServletResponse response)\n throws ServletException, IOException {\n response.setContentType(\"text/html;charset=UTF-8\");\n\n String param = \"\";\n if (request.getHeader(\"UserDefined\") != null) {\n param = request.getHeader(\"UserDefined\");\n }\n\n param = java.net.URLDecoder.decode(param, \"UTF-8\");\n String cmd = \"/bin/cmd\";\n\n String[] allowList = {\"FOO=true\",\"FOO=false\",\"BAR=true\", \"BAR=false\"}\n if(Arrays.asList(allowList).contains(param)){\n String[] argsEnv = {param};\n }\n \n Runtime r = Runtime.getRuntime();\n\n try {\n Process p = r.exec(cmd, argsEnv);\n printOSCommandResults(p, response); \n } catch (IOException e) {\n System.out.println(\"Problem executing command\");\n response.getWriter()\n .println(org.owasp.esapi.ESAPI.encoder().encodeForHTML(e.getMessage()));\n return;\n }\n```\n" + - python + message: Detected ARC4 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. metadata: + bandit-code: B304 category: security confidence: MEDIUM - cwe: CWE-78 + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' impact: MEDIUM - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - likelihood: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A03_2021-Injection - security-severity: HIGH - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + - https://cwe.mitre.org/data/definitions/326.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 subcategory: - vuln technology: - - java - vulnerability_class: - - Other - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: | - if($VALIDATION){ - ... - } - - patterns: - - pattern-inside: | - $A = $VALIDATION; - ... - - pattern: | - if($A){ - ... - } - - metavariable-pattern: - metavariable: $VALIDATION - pattern-either: - - pattern: | - $AL.contains(...) - pattern-sinks: - - pattern-either: - - patterns: - - pattern: (java.lang.Runtime $R).exec($CMD, $ENV_ARGS, ...); - - focus-metavariable: $ENV_ARGS - - patterns: - - pattern: (ProcessBuilder $PB).environment().put($...ARGS); - - focus-metavariable: $...ARGS - - patterns: - - pattern: | - $ENV = (ProcessBuilder $PB).environment(); - ... - $ENV.put($...ARGS); - - focus-metavariable: $...ARGS - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - (HttpServletRequest $REQ) - - patterns: - - pattern-inside: | - $FUNC(..., $VAR, ...) { - ... - } - - pattern: $VAR - severity: ERROR - - id: java_inject_rule-MongodbNoSQLi + - pycryptodome + pattern-either: + - pattern: Cryptodome.Cipher.ARC4.new(...) + - pattern: Crypto.Cipher.ARC4.new(...) + severity: WARNING + - id: python.pycryptodome.security.insecure-cipher-algorithm.insecure-cipher-algorithm-xor languages: - - java - message: | - Detected non-constant data passed into a NoSQL query using the 'where' - evaluation operator. If this data can be controlled by an external user, - this is a NoSQL injection. Ensure data passed to the NoSQL query is not - user controllable, or properly sanitize the data. Ideally, avoid using the - 'where' operator at all and instead use the helper methods provided by - com.mongodb.client.model.Filters with comparative operators such as eq, - ne, lt, gt, etc. - - Secure Code Example: - ``` - MongoDatabase database = mongoClient.getDatabase("mydb"); - MongoCollection collection = database.getCollection("users"); - - // Secure usage with Filters.eq: - String username = request.getParameter("username"); - collection.find(Filters.eq("username", username)); - ``` + - python + message: Detected XOR cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead. metadata: + bandit-code: B304 category: security - confidence: LOW - cwe: CWE-943 - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A03_2021-Injection - - https://www.mongodb.com/docs/manual/tutorial/query-documents/ - - https://www.mongodb.com/docs/manual/reference/operator/query/where/ - security-severity: CRITICAL - shortDescription: Improper neutralization of special elements in data query logic + - https://stackoverflow.com/questions/1135186/whats-wrong-with-xor-encryption + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L84 subcategory: - - audit + - vuln technology: - - nosql - - mongodb - vulnerability_class: - - Improper Validation - patterns: - - pattern-either: - - pattern: (com.mongodb.BasicDBObject $QUERY).put("$where", $INPUT); - - pattern: | - (HashMap $MAP).put("$where", $INPUT); - ... - (com.mongodb.BasicDBObject $QUERY).putAll($MAP); - - pattern: (com.mongodb.BasicDBObject $QUERY).append("$where", $INPUT); - - pattern: new com.mongodb.BasicDBObject("$where", $INPUT); - - pattern: | - (HashMap $MAP).put("$where", $INPUT); - ... - new com.mongodb.BasicDBObject($MAP); - - pattern: | - (HashMap $MAP).put("$where", $INPUT); - ... - String json = new JSONObject($MAP).toString(); - ... - (com.mongodb.BasicDBObject $QUERY).parse((String $JSON)); - - pattern: com.mongodb.BasicDBObjectBuilder.start().add("$where", $INPUT); - - pattern: com.mongodb.BasicDBObjectBuilder.start().append("$where", $INPUT); - - pattern: com.mongodb.BasicDBObjectBuilder.start("$where", $INPUT); - - pattern: | - (HashMap $MAP).put("$where", $INPUT); - ... - com.mongodb.BasicDBObjectBuilder.start($MAP); - - metavariable-pattern: - metavariable: $INPUT - patterns: - - pattern: | - ... - - pattern-not: | - "..." - severity: ERROR - - id: java_inject_rule-SeamLogInjection + - pycryptodome + pattern-either: + - pattern: Cryptodome.Cipher.XOR.new(...) + - pattern: Crypto.Cipher.XOR.new(...) + severity: WARNING + - id: python.pycryptodome.security.insecure-hash-algorithm-md2.insecure-hash-algorithm-md2 + languages: + - python + message: Detected MD2 hash algorithm which is considered insecure. MD2 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Crypto.Hash.MD2.new(...) + - pattern: Cryptodome.Hash.MD2.new (...) + severity: WARNING + - id: python.pycryptodome.security.insecure-hash-algorithm-md4.insecure-hash-algorithm-md4 languages: - - java - message: "The Seam logging API supports an expression language that allows developers to \nintroduce bean properties to log messages. The expression language can also be \nthe source to unwanted code execution. Expressions could be executed by dynamically\ninserting user-controlled input into the various logging calls. \n\nUse the [Seam logging API format specifier](https://docs.jboss.org/seam/2.1.2/reference/en-US/html/concepts.html#d0e4244) to ensure values are logged and expressions\nare not executed dynamically prior to output.\n\nExample logging call that safely logs the unfiltered values.\n```\nlog.info(\"This is a user controlled input = #0\", input);\n```\n" + - python + message: Detected MD4 hash algorithm which is considered insecure. MD4 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: category: security - cwe: CWE-95 - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/Top10/A03_2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of directives in dynamically evaluated code ('Eval Injection') - patterns: - - pattern: | - $LOG.$INFO($X + $Y,...) - - pattern-either: - - pattern-inside: | - import org.jboss.seam.log.Log; - ... - - pattern-inside: | - org.jboss.seam.log.Log $LOG = ...; - ... - - metavariable-regex: - metavariable: $INFO - regex: (debug|error|fatal|info|trace|warn) - severity: ERROR - - id: java_inject_rule-SqlInjection + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Crypto.Hash.MD4.new(...) + - pattern: Cryptodome.Hash.MD4.new (...) + severity: WARNING + - id: python.pycryptodome.security.insecure-hash-algorithm-md5.insecure-hash-algorithm-md5 languages: - - java - message: | - SQL Injection is a critical vulnerability that can lead to data or system compromise. By - dynamically generating SQL query strings, user input may be able to influence the logic of - the SQL statement. This could lead to an adversary accessing information they should - not have access to, or in some circumstances, being able to execute OS functionality or code. - - Replace all dynamically generated SQL queries with parameterized queries. In situations where - dynamic queries must be created, never use direct user input, but instead use a map or - dictionary of valid values and resolve them using a user-supplied key. - - For example, some database drivers do not allow parameterized queries for `>` or `<` comparison - operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the - user - supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` - values to be used in the construction of the dynamic query. The same goes for other queries - where - column or table names are required but cannot be parameterized. - - Example using `PreparedStatement` queries: - ``` - // Some userInput - String userInput = "someUserInput"; - // Your connection string - String url = "..."; - // Get a connection from the DB via the DriverManager - Connection conn = DriverManager.getConnection(url); - // Create a prepared statement - PreparedStatement st = conn.prepareStatement("SELECT name FROM table where name=?"); - // Set each parameters value by the index (starting from 1) - st.setString(1, userInput); - // Execute query and get the result set - ResultSet rs = st.executeQuery(); - // Iterate over results - while (rs.next()) { - // Get result for this row at the provided column number (starting from 1) - String result = rs.getString(1); - // ... - } - // Close the ResultSet - rs.close(); - // Close the PreparedStatement - st.close(); - ``` - - Example on using CriteriaBuilder to build queries - ``` - public List findBySomeCriteria(EntityManager entityManager, String criteriaValue) { - CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); - CriteriaQuery query = criteriaBuilder.createQuery(YourEntity.class); - Root root = query.from(YourEntity.class); - - query.select(root).where(criteriaBuilder.equal(root.get("someProperty"), criteriaValue)); - - return entityManager.createQuery(query).getResultList(); - } - ``` - - For more information on SQL Injection see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html + - python + message: Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: category: security - cwe: CWE-89 + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an SQL command ('SQL Injection') + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + subcategory: + - vuln technology: - - java - mode: taint - options: - taint_assume_safe_booleans: true - taint_assume_safe_numbers: true - pattern-propagators: - - from: $X - pattern: $LIST.add($X) - to: $LIST - - from: $X - pattern: $MAP.put(..., $X) - to: $MAP - - from: $X - pattern: $STR.concat($X) - to: $STR - - from: $X - pattern: $STR = String.format(..., $X, ...) - to: $STR - - from: $X - pattern: $STR = String.join(..., $X, ...) - to: $STR - - from: $X - pattern: $SB.append($X) - to: $SB - pattern-sanitizers: - - pattern: (CriteriaBuilder $CB).$ANY(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: (javax.jdo.PersistenceManager $PM).newQuery($ARG) - - pattern: (javax.jdo.PersistenceManager $PM).newQuery(..., $ARG) - - pattern: (javax.jdo.Query $Q).setFilter($ARG) - - pattern: (javax.jdo.Query $Q).setGrouping($ARG) - - pattern: org.hibernate.criterion.Restrictions.sqlRestriction($ARG, ...) - - pattern: (org.hibernate.Session $S).createQuery((String $ARG), ...) - - pattern: (org.hibernate.Session $S).createSQLQuery($ARG, ...) - - pattern: (org.hibernate.Session $S).connection().prepareStatement($ARG) - - pattern: (java.sql.Statement $S).executeQuery($ARG, ...) - - pattern: (java.sql.Statement $S).execute($ARG, ...) - - pattern: (java.sql.Statement $S).executeUpdate($ARG, ...) - - pattern: (java.sql.Statement $S).executeLargeUpdate($ARG, ...) - - pattern: (java.sql.Statement $S).addBatch($ARG, ...) - - pattern: (java.sql.PreparedStatement $S).executeQuery($ARG, ...) - - pattern: (java.sql.PreparedStatement $S).execute($ARG, ...) - - pattern: (java.sql.PreparedStatement $S).executeUpdate($ARG, ...) - - pattern: (java.sql.PreparedStatement $S).executeLargeUpdate($ARG, ...) - - pattern: (java.sql.PreparedStatement $S).addBatch($ARG, ...) - - pattern: (java.sql.Connection $S).prepareCall($ARG, ...) - - pattern: (java.sql.Connection $S).prepareStatement($ARG, ...) - - pattern: (java.sql.Connection $S).nativeSQL($ARG, ...) - - pattern: new org.springframework.jdbc.core.PreparedStatementCreatorFactory($ARG, ...) - - pattern: (org.springframework.jdbc.core.PreparedStatementCreatorFactory $F).newPreparedStatementCreator($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).batchUpdate($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).execute($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).query($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForList($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForMap($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForObject($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForObject($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForRowSet($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForInt($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).queryForLong($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcOperations $O).update($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).batchUpdate($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).execute($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).query($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForList($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForMap($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForObject($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForRowSet($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForInt($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).queryForLong($ARG, ...) - - pattern: (org.springframework.jdbc.core.JdbcTemplate $O).update($ARG, ...) - - pattern: (io.vertx.sqlclient.SqlClient $O).query($ARG, ...) - - pattern: (io.vertx.sqlclient.SqlClient $O).preparedQuery($ARG, ...) - - pattern: (io.vertx.sqlclient.SqlConnection $O).prepare($ARG, ...) - - pattern: (org.apache.turbine.om.peer.BasePeer $O).executeQuery($ARG, ...) - - pattern: org.apache.torque.util.BasePeer.executeQuery($ARG, ...) - - pattern: org.apache.torque.util.BasePeer.executeStatement($ARG, ...) - - pattern: (javax.persistence.EntityManager $O).createQuery($ARG, ...) - - pattern: (javax.persistence.EntityManager $O).createNativeQuery($ARG, ...) - - pattern: (org.jdbi.v3.core.Handle $H).createQuery($ARG, ...) - - pattern: (org.jdbi.v3.core.Handle $H).createScript($ARG, ...) - - pattern: (org.jdbi.v3.core.Handle $H).createUpdate($ARG, ...) - - pattern: (org.jdbi.v3.core.Handle $H).execute($ARG, ...) - - pattern: (org.jdbi.v3.core.Handle $H).prepareBatch($ARG, ...) - - pattern: (org.jdbi.v3.core.Handle $H).select($ARG, ...) - - pattern: new org.jdbi.v3.core.statement.Script($H, $ARG) - - pattern: new org.jdbi.v3.core.statement.Update($H, $ARG) - - pattern: new org.jdbi.v3.core.statement.PreparedBatch($H, $ARG) - - focus-metavariable: $ARG - - patterns: - - pattern: (java.sql.Connection $S).createStatement(...).$SQLFUNC($ARG, ...) - - pattern-not: (java.sql.Connection $S).createStatement(...).$SQLFUNC("...") - - metavariable-regex: - metavariable: $SQLFUNC - regex: execute|executeQuery|createQuery|query|addBatch|nativeSQL|create|prepare - pattern-sources: - - pattern: (javax.servlet.http.HttpServletRequest $R).$METHOD(...) - - pattern: (java.util.Scanner $S).$METHOD(...) - - pattern: (java.util.stream.Stream).$METHOD(...) - - pattern: (java.util.StringJoiner $SJ).toString(...) - - pattern: (java.sql.ResultSet.getString $R).$METHOD(...) - - pattern: (java.lang.System $S).getProperty(...) - - pattern: (java.lang.System $S).getenv(...) - - pattern: (java.lang.StringBuilder $SB).toString(...) - - pattern: (java.io.FileInputStream $F).read(...) - - pattern: (java.io.FileReader $F).read(...) - - pattern: (java.net.Socket $S).getInputStream(...) - - pattern: (java.net.Socket $S).getOutputStream(...) - - pattern: (java.net.DatagramSocket $S).receive(...) - - pattern: (java.net.DatagramSocket $S).getInputStream(...) - - pattern: java.nio.file.Files.readAllBytes(...) - - pattern: java.nio.file.Files.readAllLines(...) - - pattern: java.nio.file.Files.lines(...) - - pattern: java.nio.file.Files.newBufferedReader(...) - - pattern: org.apache.commons.io.IOUtils.toString(...) - - pattern: org.apache.commons.io.IOUtils.readLines(...) - - pattern: org.apache.commons.io.IOUtils.toByteArray(...) - - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).readValue(...) - - pattern: (com.fasterxml.jackson.databind.ObjectMapper $OM).treeToValue(...) - - pattern: $CLASS.$METHOD(..., (javax.servlet.http.HttpServletRequest $R), ...) - - pattern: $FUNC(..., (javax.servlet.http.HttpServletRequest $R), ...) - - patterns: - - pattern-inside: $FUNC(..., String $X, ...) { ... } - - focus-metavariable: $X - severity: ERROR - - id: java_traversal_rule-RelativePathTraversal + - pycryptodome + pattern-either: + - pattern: Crypto.Hash.MD5.new(...) + - pattern: Cryptodome.Hash.MD5.new (...) + severity: WARNING + - id: python.pycryptodome.security.insecure-hash-algorithm.insecure-hash-algorithm-sha1 languages: - - java - message: "Detected user input controlling a file path. An attacker could control\nthe location of this file, to include going backwards in the directory\nwith '../'. \n\nTo address this, ensure that user-controlled variables in file\npaths are sanitized. You may also consider using a utility method such as\norg.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file\nname from the path.\n\nExample of using `org.apache.commons.io.FilenameUtils.getName(...)` to \nonly retrieve the file name from the path\n```\nString fileName = org.apache.commons.io.FilenameUtils.getName(userControlledInput);\nFile file = new File(\"/path/to/directory/\" + fileName);\n```\n" + - python + message: Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. metadata: category: security - cwe: CWE-23 - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: LOW owasp: - - A01:2021-Broken Access Control - - A5:2017-Broken Access Control + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://owasp.org/www-community/attacks/Path_Traversal - security-severity: CRITICAL - shortDescription: Relative Path Traversal - mode: taint - options: - interfile: true - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: new File(...) - - pattern: new java.io.File(...) - - pattern: new FileReader(...) - - pattern: new java.io.FileReader(...) - - pattern: new FileInputStream(...) - - pattern: new java.io.FileInputStream(...) - - pattern: (Paths $PATHS).get(...) - - patterns: - - pattern: | - $CLASS.$FUNC(...) - - metavariable-regex: - metavariable: $FUNC - regex: ^(getResourceAsStream|getResource)$ - - patterns: - - pattern-either: - - pattern: new ClassPathResource($FILE, ...) - - pattern: ResourceUtils.getFile($FILE, ...) - - pattern: new FileOutputStream($FILE, ...) - - pattern: new java.io.FileOutputStream($FILE, ...) - - pattern: new StreamSource($FILE, ...) - - pattern: new javax.xml.transform.StreamSource($FILE, ...) - - pattern: FileUtils.openOutputStream($FILE, ...) - - focus-metavariable: $FILE - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { - ... - } - - pattern-inside: | - $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { - ... - } - - metavariable-regex: - metavariable: $TYPE - regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) - - metavariable-regex: - metavariable: $REQ - regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) - - focus-metavariable: $SOURCE - severity: ERROR - - id: java_xpathi_rule-XpathInjection + - https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html + - https://www.trendmicro.com/vinfo/us/security/news/vulnerabilities-and-exploits/sha-1-collision-signals-the-end-of-the-algorithm-s-viability + - http://2012.sharcs.org/slides/stevens.pdf + - https://pycryptodome.readthedocs.io/en/latest/src/hash/sha3_256.html + source-rule-url: https://github.com/PyCQA/bandit/blob/d5f8fa0d89d7b11442fc6ec80ca42953974354c8/bandit/blacklists/calls.py#L59 + subcategory: + - vuln + technology: + - pycryptodome + pattern-either: + - pattern: Crypto.Hash.SHA.new(...) + - pattern: Cryptodome.Hash.SHA.new (...) + severity: WARNING + - id: python.pycryptodome.security.insufficient-dsa-key-size.insufficient-dsa-key-size languages: - - java - message: "The application processes `XPath` queries with potentially malicious input.\nAn adversary who is able to control the XPath query could potentially influence the logic\nof how data is retrieved, processed or even bypass protections.\n\nTo mitigate the vulnerability, avoid using user input in XPath queries.\nIf it cannot be avoided, validate the user input against an allowlist\nof expected values before using it in the query. \n\nFollowing is an example that demonstrates how to perform an XPath query \nusing user input validated against an allowlist.\n\nSecure code example:\n```\npublic class SecureXPathWithoutResolver {\n\n private static final List ALLOWED_AUTHORS = List.of(\"Author1\", \"Author2\", \"Author3\");\n\n public static void main(String[] args) {\n try {\n String userInput = \"Author1\"; // Example user input\n if (ALLOWED_AUTHORS.contains(userInput)) {\n // User input is safe to use\n DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n DocumentBuilder builder = factory.newDocumentBuilder();\n Document doc = builder.parse(\"path/to/your/xmlfile.xml\");\n\n XPathFactory xpathFactory = XPathFactory.newInstance();\n XPath xpath = xpathFactory.newXPath();\n\n // Safely embed the validated user input into the XPath expression\n String expression = String.format(\"//books/book[author='%s']\", userInput);\n NodeList nodes = (NodeList) xpath.evaluate(expression, doc, XPathConstants.NODESET);\n\n for (int i = 0; i < nodes.getLength(); i++) {\n System.out.println(nodes.item(i).getTextContent());\n }\n } else {\n throw new IllegalArgumentException(\"Input is not allowed.\");\n }\n } catch (Exception e) {\n e.printStackTrace();\n }\n }\n}\n```\n\nFor more information on XPath Injection see:\n- https://owasp.org/www-community/attacks/XPATH_Injection\n" + - python + message: Detected an insufficient key size for DSA. NIST recommends a key size of 2048 or higher. metadata: category: security - cwe: CWE-643 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of data within XPath expressions ('XPath Injection') - mode: taint - pattern-sanitizers: - - patterns: - - pattern-inside: $MAP.getOrDefault($VAR,"..."); - - pattern: $VAR - - patterns: - - pattern-either: - - pattern: | - if($VALIDATION){ - ... - } - - patterns: - - pattern-inside: | - $A = $VALIDATION; - ... - - pattern: | - if($A){ - ... - } - - metavariable-pattern: - metavariable: $VALIDATION - pattern-either: - - pattern: | - $AL.contains(...) - - pattern: | - $AL.equals(...) - pattern-sinks: - - pattern-either: - - patterns: - - pattern-inside: | - (javax.xml.xpath.XPath $XP). ... .evaluate($EXP, ...); - - pattern: $EXP - - patterns: - - pattern-inside: | - (javax.xml.xpath.XPath $XP). ... .compile($EXP, ...); - - pattern: $EXP - pattern-sources: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py + subcategory: + - vuln + technology: + - pycryptodome + patterns: - pattern-either: - - pattern: | - (HttpServletRequest $REQ).$FUNC(...) - - patterns: - - pattern-inside: | - $FUNC(..., $VAR, ...) { - ... - } - - pattern: $VAR - severity: ERROR - - id: java_xxe_rule-DisallowDoctypeDeclFalse + - pattern: Crypto.PublicKey.DSA.generate(..., bits=$SIZE, ...) + - pattern: Crypto.PublicKey.DSA.generate($SIZE, ...) + - pattern: Cryptodome.PublicKey.DSA.generate(..., bits=$SIZE, ...) + - pattern: Cryptodome.PublicKey.DSA.generate($SIZE, ...) + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE + severity: WARNING + - id: python.pycryptodome.security.insufficient-rsa-key-size.insufficient-rsa-key-size languages: - - java - message: "DOCTYPE declarations are enabled for $DBFACTORY. Without prohibiting\nexternal entity declarations, this is vulnerable to XML external entity\nattacks. In an XXE attack, an attacker can exploit the processing of external \nentity references within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise.\n\nTo mitigate this vulnerability, disable this by setting the feature\n\"http://apache.org/xml/features/disallow-doctype-decl\" to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\nentities declarations. This can be done by setting the features\n\"http://xml.org/sax/features/external-general-entities\" and\n\"http://xml.org/sax/features/external-parameter-entities\" to false.\n\nSecure Code Example: \n``` \npublic void GoodXMLInputFactory() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n} \n```\n" + - python + message: Detected an insufficient key size for RSA. NIST recommends a key size of 2048 or higher. metadata: category: security - confidence: HIGH - cwe: CWE-611 - cwe2021-top25: "true" - cwe2022-top25: "true" - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM likelihood: LOW owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference + - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf + source-rule-url: https://github.com/PyCQA/bandit/blob/b1411bfb43795d3ffd268bef17a839dee954c2b1/bandit/plugins/weak_cryptographic_key.py + subcategory: + - vuln technology: - - java - - xml - vulnerability_class: - - XML Injection + - pycryptodome patterns: - - pattern: | - $DBFACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", - false); - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - ... - } - - pattern-not-inside: | - $RETURNTYPE $METHOD(...){ - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - ... - $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - } + - pattern-either: + - pattern: Crypto.PublicKey.RSA.generate(..., bits=$SIZE, ...) + - pattern: Crypto.PublicKey.RSA.generate($SIZE, ...) + - pattern: Cryptodome.PublicKey.RSA.generate(..., bits=$SIZE, ...) + - pattern: Cryptodome.PublicKey.RSA.generate($SIZE, ...) + - metavariable-comparison: + comparison: $SIZE < 2048 + metavariable: $SIZE severity: WARNING - - id: java_xxe_rule-DocumentBuilderFactoryDisallowDoctypeDeclMissing + - id: python.pycryptodome.security.mode-without-authentication.crypto-mode-without-authentication languages: - - java - message: "DOCTYPE declarations are enabled for this DocumentBuilderFactory. Enabling \nDOCTYPE declarations without proper restrictions can make your application \nvulnerable to XML External Entity (XXE) attacks. \nIn an XXE attack, an attacker can exploit the processing of external entity \nreferences within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise. \n\nTo mitigate this vulnerability, disable this by setting the\nfeature \"http://apache.org/xml/features/disallow-doctype-decl\" to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\nentities declarations. This can be done by setting the features\n\"http://xml.org/sax/features/external-general-entities\" and\n\"http://xml.org/sax/features/external-parameter-entities\" to false.\n\nSecure Code Example (You can do either of the following):\n```\npublic void GoodDocumentBuilderFactory() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n dbf.newDocumentBuilder();\n}\n\npublic void GoodDocumentBuilderFactory2() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n dbf.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n dbf.newDocumentBuilder();\n}\n```\n" + - python + message: 'An encryption mode of operation is being used without proper message authentication. This can potentially result in the encrypted content to be decrypted by an attacker. Consider instead use an AEAD mode of operation like GCM. ' metadata: category: security - confidence: HIGH - cwe: CWE-611 - cwe2021-top25: "true" - cwe2022-top25: "true" - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM likelihood: LOW owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures subcategory: - vuln technology: - - java - - xml - vulnerability_class: - - XML Injection - mode: taint - pattern-sanitizers: - - by-side-effect: true - pattern-either: + - cryptography + patterns: + - pattern-either: - patterns: - pattern-either: - pattern: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); ... $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); ... $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - - focus-metavariable: $FACTORY - - patterns: - - pattern-either: - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", - true); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); - ... - } - ... - } - - pattern: $M($X) - - focus-metavariable: $X - pattern-sinks: - - patterns: - - pattern: | - $FACTORY.newDocumentBuilder(); - pattern-sources: - - by-side-effect: true - patterns: - - pattern: | - $FACTORY - - pattern-inside: | - $FACTORY = DocumentBuilderFactory.newInstance(); - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - ... - static { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - ... - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = DocumentBuilderFactory.newInstance(); - ... - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + AES.new(..., $PYCRYPTODOME_MODE) + - pattern-not-inside: | + AES.new(..., $PYCRYPTODOME_MODE) ... - } - ... - } + HMAC.new + - metavariable-pattern: + metavariable: $PYCRYPTODOME_MODE + patterns: + - pattern-either: + - pattern: AES.MODE_CBC + - pattern: AES.MODE_CTR + - pattern: AES.MODE_CFB + - pattern: AES.MODE_OFB + severity: ERROR + - fix-regex: + regex: MONGODB-CR + replacement: SCRAM-SHA-256 + id: python.pymongo.security.mongodb.mongo-client-bad-auth + languages: + - python + message: Warning MONGODB-CR was deprecated with the release of MongoDB 3.6 and is no longer supported by MongoDB 4.0 (see https://api.mongodb.com/python/current/examples/authentication.html for details). + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-477: Use of Obsolete Function' + impact: LOW + likelihood: LOW + references: + - https://cwe.mitre.org/data/definitions/477.html + subcategory: + - vuln + technology: + - pymongo + pattern: | + pymongo.MongoClient(..., authMechanism='MONGODB-CR') + severity: WARNING + - fix: | + $...PARAMS, httponly=True + id: python.pyramid.audit.authtkt-cookie-httponly-unsafe-default.pyramid-authtkt-cookie-httponly-unsafe-default + languages: + - python + message: Found a Pyramid Authentication Ticket cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern: pyramid.authentication.$FUNC($...PARAMS) + - metavariable-pattern: + metavariable: $FUNC + pattern-either: + - pattern: AuthTktCookieHelper + - pattern: AuthTktAuthenticationPolicy + - pattern-not: pyramid.authentication.$FUNC(..., httponly=$HTTPONLY, ...) + - pattern-not: pyramid.authentication.$FUNC(..., **$PARAMS, ...) + - focus-metavariable: $...PARAMS severity: WARNING - - id: java_xxe_rule-ExternalGeneralEntitiesTrue + - fix: | + True + id: python.pyramid.audit.authtkt-cookie-httponly-unsafe-value.pyramid-authtkt-cookie-httponly-unsafe-value languages: - - java - message: "This rule identifies instances in the code where an XML parser is\nconfigured to allow external general entities. Allowing the processing \nof external general entities without proper validation or restriction \ncan lead to XXE attacks. An attacker can craft an XML document to \nreference sensitive files on the server or external systems under the \nattacker's control, leading to data disclosure, denial of service, or \nserver-side request forgery (SSRF).\n\nTo mitigate this vulnerability, the application should be configured to \ndisable the use of external general entities in XML parsing. This can be \nachieved by setting the feature \n\"http://xml.org/sax/features/external-general-entities\" to false.\n\nSecure Code Example:\n```\nclass GoodSAXBuilder {\n public void GoodSAXBuilder1() throws ParserConfigurationException {\n SAXBuilder saxBuilder = new SAXBuilder();\n saxBuilder.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n }\n}\n```\n" + - python + message: Found a Pyramid Authentication Ticket cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. metadata: category: security - cwe: CWE-611 - cwe2021-top25: "true" - cwe2022-top25: "true" - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration + - A05:2021 - Security Misconfiguration references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln technology: - - java - - xml - vulnerability_class: - - XML Injection - pattern: | - $PARSER.setFeature("http://xml.org/sax/features/external-general-entities", - true); + - pyramid + patterns: + - pattern-either: + - patterns: + - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktCookieHelper(..., httponly=$HTTPONLY, ...) + - patterns: + - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., httponly=$HTTPONLY, ...) + - pattern: $HTTPONLY + - metavariable-pattern: + metavariable: $HTTPONLY + pattern: | + False severity: WARNING - - id: java_xxe_rule-ExternalParameterEntitiesTrue + - fix: | + 'Lax' + id: python.pyramid.audit.authtkt-cookie-samesite.pyramid-authtkt-cookie-samesite languages: - - java - message: "This rule identifies instances in the code where the XML parser is\nconfigured to allow external parameter entities. Enabling external\nentities in XML parsing can lead to XML External Entity (XXE) attacks,\nwhere an attacker could exploit the XML parser to read sensitive files\nfrom the server, perform denial of service (DoS) attacks, or achieve\nserver-side request forgery (SSRF). This vulnerability occurs when the\napplication processes XML input that includes external entity references\nwithin an XML document.\n\nTo mitigate this vulnerability, the application should be configured to disable \nthe use of external entities in XML parsing. This can be achieved by setting the \nfeature \"http://xml.org/sax/features/external-parameter-entities\" to false.\n\nSecure Code Example: \n``` \ntry {\n DBFactory dbFactory = DocumentBuilderFactory.newInstance();\n // Disable external entities to mitigate XXE vulnerability\n dbFactory.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n dbFactory.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n // Additional configuration for secure parsing\n dbFactory.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n dbFactory.setXIncludeAware(false);\n dbFactory.setExpandEntityReferences(false);\n\n // Use the configured factory to create a document builder\n DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();\n // Parse an XML file using the secure document builder\n Document doc = dBuilder.parse(new InputSource(new StringReader(xmlData)));\n // Process the document as needed\n} catch (ParserConfigurationException | SAXException | IOException e) {\n // Handle exceptions appropriately\n} \n``` \n" + - python + message: Found a Pyramid Authentication Ticket without the samesite option correctly set. Pyramid cookies should be handled securely by setting samesite='Lax'. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. metadata: category: security - cwe: CWE-611 - cwe2021-top25: "true" - cwe2022-top25: "true" - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' + impact: LOW + likelihood: LOW owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration + - A01:2021 - Broken Access Control references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln technology: - - java - - xml - vulnerability_class: - - XML Injection - pattern: | - $PARSER.setFeature("http://xml.org/sax/features/external-parameter-entities", - true); + - pyramid + patterns: + - pattern-either: + - pattern: pyramid.authentication.AuthTktCookieHelper(..., samesite=$SAMESITE, ...) + - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., samesite=$SAMESITE, ...) + - pattern: $SAMESITE + - metavariable-regex: + metavariable: $SAMESITE + regex: (?!'Lax') severity: WARNING - - id: java_xxe_rule-SAXParserFactoryDisallowDoctypeDeclMissing + - fix-regex: + regex: (.*)\) + replacement: \1, secure=True) + id: python.pyramid.audit.authtkt-cookie-secure-unsafe-default.pyramid-authtkt-cookie-secure-unsafe-default languages: - - java - message: "DOCTYPE declarations are enabled for this SAXParserFactory. Enabling DOCTYPE \ndeclarations without proper restrictions can make your application vulnerable to \nXML External Entity (XXE) attacks. \nIn an XXE attack, an attacker can exploit the processing of external entity \nreferences within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise.\n\nTo mitigate this vulnerability, disable DOCTYPE declarations by setting the\nfeature `http://apache.org/xml/features/disallow-doctype-decl` to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\nentities declarations. This can be done by setting the features\n`http://xml.org/sax/features/external-general-entities` and\n`http://xml.org/sax/features/external-parameter-entities` to false. \nNOTE: The previous links are not meant to be clicked. They are the literal\nconfig key values that are supposed to be used to disable these features.\n\nSecure Code Example (You can do either of the following):\n```\npublic void GoodSAXParserFactory() throws ParserConfigurationException {\n SAXParserFactory spf = SAXParserFactory.newInstance();\n spf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n spf.newSAXParser();\n}\n\npublic void GoodSAXParserFactory2() throws ParserConfigurationException {\n SAXParserFactory spf = SAXParserFactory.newInstance();\n spf.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n spf.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n spf.newSAXParser();\n} \n```\nFor more information, see\nhttps://semgrep.dev/docs/cheat-sheets/java-xxe/#3a-documentbuilderfactory.\n" + - python + message: Found a Pyramid Authentication Ticket cookie using an unsafe default for the secure option. Pyramid cookies should be handled securely by setting secure=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. metadata: category: security - cwe: CWE-611 - cwe2021-top25: "true" - cwe2022-top25: "true" - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration + - A05:2021 - Security Misconfiguration references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln technology: - - java - - xml - vulnerability_class: - - XML Injection - mode: taint - pattern-sanitizers: - - by-side-effect: true - pattern-either: + - pyramid + patterns: + - pattern-either: - patterns: - - pattern-either: - - pattern: | - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - - pattern: | - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - - focus-metavariable: $FACTORY + - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., secure=$SECURE, ...) + - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktCookieHelper(...) - patterns: - - pattern-either: - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", - true); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); - ... - } - ... - } - - pattern: $M($X) - - focus-metavariable: $X - pattern-sinks: - - patterns: - - pattern: $FACTORY.newSAXParser(); - pattern-sources: - - by-side-effect: true - patterns: - - pattern-either: - - pattern: | - $FACTORY = SAXParserFactory.newInstance(); - - patterns: - - pattern: $FACTORY - - pattern-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = SAXParserFactory.newInstance(); - static { - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); - ... - $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - ... - } - ... - } + - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., secure=$SECURE, ...) + - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(...) severity: WARNING - - id: java_xxe_rule-TransformerfactoryDTDNotDisabled + - fix: | + True + id: python.pyramid.audit.authtkt-cookie-secure-unsafe-value.pyramid-authtkt-cookie-secure-unsafe-value languages: - - java - message: "This rule identifies configurations of the TransformerFactory class where\nDOCTYPE declarations are enabled. Enabling DOCTYPE declarations without\nproper restrictions can make your application vulnerable to XML External\nEntity (XXE) attacks. In an XXE attack, an attacker can exploit the\nprocessing of external entity references within an XML document to access\ninternal files, conduct denial-of-service attacks, or SSRF (Server Side\nRequest Forgery), potentially leading to sensitive information disclosure\nor system compromise.\n\nTo mitigate XXE vulnerabilities related to the TransformerFactory instance in \nJava, it is crucial to disable external DTD (Document Type Definition) and \nexternal stylesheet processing. This can be accomplished by setting the \nACCESS_EXTERNAL_DTD and ACCESS_EXTERNAL_STYLESHEET factory attributes to an \nempty string (\"\"). This approach prevents the parser from fetching and processing \nexternal references specified in the XML document.\n\nSecure Code Example:\n```\npublic static void configureTransformerFactory() throws TransformerConfigurationException {\n TransformerFactory factory = TransformerFactory.newInstance();\n // Disable access to external DTDs and stylesheets to prevent XXE\n factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, \"\");\n factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, \"\");\n}\n```\n" + - python + message: Found a Pyramid Authentication Ticket cookie without the secure option correctly set. Pyramid cookies should be handled securely by setting secure=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. metadata: category: security - cwe: CWE-611 - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration + - A05:2021 - Security Misconfiguration references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://blog.sonarsource.com/secure-xml-processor - - https://xerces.apache.org/xerces2-j/features.html - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln technology: - - java - - xml - mode: taint - pattern-sanitizers: - - by-side-effect: true - pattern-either: + - pyramid + patterns: + - pattern-either: - patterns: - - pattern-either: - - pattern: | - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - - pattern: | - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - - pattern: | - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - - pattern: | - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - - focus-metavariable: $FACTORY + - pattern-not: pyramid.authentication.AuthTktCookieHelper(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktCookieHelper(..., secure=$SECURE, ...) - patterns: - - pattern-either: - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - } - ... - } - - pattern-inside: | - class $C { - ... - $T $M(...) { - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - } - ... - } - - pattern: $M($X) - - focus-metavariable: $X - pattern-sinks: - - patterns: - - pattern: $FACTORY.newTransformer(...); - pattern-sources: - - by-side-effect: true - patterns: - - pattern-either: - - pattern: | - $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); - - patterns: - - pattern: $FACTORY - - pattern-inside: | - class $C { - ... - $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - ... - $FACTORY.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - } - ... - } - - pattern-not-inside: | - class $C { - ... - $V $FACTORY = javax.xml.transform.TransformerFactory.newInstance(); - static { - ... - $FACTORY.setAttribute("=~/.*accessExternalStylesheet.*/", ""); - ... - $FACTORY.setAttribute("=~/.*accessExternalDTD.*/", ""); - ... - } - ... - } + - pattern-not: pyramid.authentication.AuthTktAuthenticationPolicy(..., **$PARAMS) + - pattern: pyramid.authentication.AuthTktAuthenticationPolicy(..., secure=$SECURE, ...) + - pattern: $SECURE + - metavariable-pattern: + metavariable: $SECURE + pattern: | + False + severity: WARNING + - fix: | + True + id: python.pyramid.audit.csrf-origin-check-disabled-globally.pyramid-csrf-origin-check-disabled-globally + languages: + - python + message: Automatic check of the referrer for cross-site request forgery tokens has been explicitly disabled globally, which might leave views unprotected when an unsafe CSRF storage policy is used. Use 'pyramid.config.Configurator.set_default_csrf_options(check_origin=True)' to turn the automatic check for all unsafe methods (per RFC2616). + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-inside: | + $CONFIG.set_default_csrf_options(..., check_origin=$CHECK_ORIGIN, ...) + - pattern: $CHECK_ORIGIN + - metavariable-comparison: + comparison: $CHECK_ORIGIN == False + metavariable: $CHECK_ORIGIN + severity: ERROR + - fix: | + True + id: python.pyramid.audit.csrf-origin-check-disabled.pyramid-csrf-origin-check-disabled + languages: + - python + message: Origin check for the CSRF token is disabled for this view. This might represent a security risk if the CSRF storage policy is not known to be secure. + metadata: + asvs: + control_id: 4.2.2 CSRF + control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V4-Access-Control.md#v42-operation-level-access-control + section: V4 Access Control + version: "4" + category: security + confidence: MEDIUM + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-inside: | + from pyramid.view import view_config + ... + @view_config(..., check_origin=$CHECK_ORIGIN, ...) + def $VIEW(...): + ... + - pattern: $CHECK_ORIGIN + - metavariable-comparison: + comparison: $CHECK_ORIGIN == False + metavariable: $CHECK_ORIGIN + severity: WARNING + - fix-regex: + regex: (.*)\) + replacement: \1, httponly=True) + id: python.pyramid.audit.set-cookie-httponly-unsafe-default.pyramid-set-cookie-httponly-unsafe-default + languages: + - python + message: Found a Pyramid cookie using an unsafe default for the httponly option. Pyramid cookies should be handled securely by setting httponly=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., httponly=$HTTPONLY, ...) + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(...) severity: WARNING - - id: java_xxe_rule-XMLInputFactoryExternalEntitiesEnabled + - fix: | + True + id: python.pyramid.audit.set-cookie-httponly-unsafe-value.pyramid-set-cookie-httponly-unsafe-value languages: - - java - message: "XML external entities are enabled for this XMLInputFactory. Enabling external \nentities can make the application vulnerable to XML external entity attacks. \nIn an XXE attack, an attacker can exploit the processing of external entity \nreferences within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise.\n\nTo mitigate this vulnerability, disable external entities by\nsetting \"javax.xml.stream.isSupportingExternalEntities\" to false.\n\nSecure Code Example:\n```\npublic GoodXMLInputFactory() {\n final XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();\n xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);\n xmlInputFactory.setProperty(\"javax.xml.stream.isSupportingExternalEntities\", false);\n}\n```\nFor more details, refer to https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.md#xmlinputfactory-a-stax-parser\n" + - python + message: Found a Pyramid cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. metadata: category: security - confidence: LOW - cwe: CWE-611 - cwe2021-top25: "true" - cwe2022-top25: "true" - impact: HIGH - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-1004: Sensitive Cookie Without ''HttpOnly'' Flag' + impact: LOW likelihood: LOW owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration + - A05:2021 - Security Misconfiguration references: - - https://semgrep.dev/blog/2022/xml-security-in-java - - https://semgrep.dev/docs/cheat-sheets/java-xxe/ - - https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference - vulnerability_class: - - XML Injection - pattern: | - $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", - true); + - https://owasp.org/www-community/controls/SecureCookieAttribute + - https://owasp.org/www-community/HttpOnly + - https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#httponly-attribute + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(..., httponly=$HTTPONLY, ...) + - pattern: $HTTPONLY + - metavariable-pattern: + metavariable: $HTTPONLY + pattern: | + False severity: WARNING - - id: java_xxe_rule-XMLStreamRdr + - fix-regex: + regex: (.*)\) + replacement: \1, samesite='Lax') + id: python.pyramid.audit.set-cookie-samesite-unsafe-default.pyramid-set-cookie-samesite-unsafe-default languages: - - java - message: "External XML entities are a feature of XML parsers that allow \ndocuments to contain references to other documents or data. This \nfeature can be abused to read files, communicate with external\nhosts, exfiltrate data, or cause a Denial of Service (DoS).\nIn most XML parsers, the recommendation to protect against XXE is \nto disable the doctype feature.\nUnfortunately use of the `XMLInputFactory` requires that the doctypes \nfeature be enabled. Instead the application can set the `ACCESS_EXTERNAL_DTD` \nto an empty string and disable `javax.xml.stream.isSupportingExternalEntities`.\n\nSecure Code Example:\n```\n// Create an XMLInputFactory\nXMLInputFactory factory = XMLInputFactory.newFactory();\n// Set the ACCESS_EXTERNAL_DTD property to an empty string so it won't access\n// entities using protocols\n// (ref:\nhttps://docs.oracle.com/javase/8/docs/api/javax/xml/XMLConstants.html#ACCESS_EXTERNAL_DTD)\nfactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, \"\");\n// Additionally, disable support for resolving external entities\nfactory.setProperty(\"javax.xml.stream.isSupportingExternalEntities\", false);\n// Continue to work with the factory/stream parser\n```\n\nFor more information on XML security see OWASP's guide:\nhttps://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java\n" + - python + message: Found a Pyramid cookie using an unsafe value for the samesite option. Pyramid cookies should be handled securely by setting samesite='Lax' in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. metadata: category: security - cwe: CWE-611 + confidence: MEDIUM + cwe: + - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' + impact: LOW + likelihood: LOW owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Improper restriction of XML external entity reference ('XXE') + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - pyramid patterns: - - pattern-not-inside: | - (javax.xml.stream.XMLInputFactory $FAC).setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - ... - - pattern-not-inside: - patterns: - - pattern-either: - - pattern: | - (javax.xml.stream.XMLInputFactory $FAC).setProperty(XMLInputFactory.SUPPORT_DTD, $FALSE); - ... - - pattern: | - (javax.xml.stream.XMLInputFactory $FAC).setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, $FALSE); - ... - - pattern: | - (javax.xml.stream.XMLInputFactory $FAC).setProperty("javax.xml.stream.isSupportingExternalEntities", $FALSE); - ... - - metavariable-pattern: - metavariable: $FALSE - pattern-either: - - pattern: | - false - - pattern: | - Boolean.FALSE - - pattern: | - (javax.xml.stream.XMLInputFactory $FAC).createXMLStreamReader(...) + - pattern-either: + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., samesite=$SAMESITE, ...) + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(...) severity: WARNING - - id: javascript_exec_rule-child-process + - fix: | + 'Lax' + id: python.pyramid.audit.set-cookie-samesite-unsafe-value.pyramid-set-cookie-samesite-unsafe-value languages: - - javascript - - typescript - message: | - OS command injection is a critical vulnerability that can lead to a full system - compromise as it may allow an adversary to pass in arbitrary commands or arguments - to be executed. - - User input should never be used in constructing commands or command arguments - to functions which execute OS commands. This includes filenames supplied by - user uploads or downloads. - - Ensure your application does not: - - - Use user-supplied information in the process name to execute. - - Use user-supplied information in an OS command execution function which does - not escape shell meta-characters. - - Use user-supplied information in arguments to OS commands. - - The application should have a hardcoded set of arguments that are to be passed - to OS commands. If filenames are being passed to these functions, it is - recommended that a hash of the filename be used instead, or some other unique - identifier. It is strongly recommended that a native library that implements - the same functionality be used instead of using OS system commands, due to the - risk of unknown attacks against third-party commands. - - When specifying the OS command, ensure the application uses the full path - information, otherwise the OS may attempt to look up which process to execute - and could be vulnerable to untrusted search path vulnerabilities (CWE-426). - - Example of safely executing an OS command: - ``` - const child_process = require('child_process'); - const fs = require('fs'); - const crypto = require('node:crypto'); - const { mkdtempSync } = require('node:fs'); - - function executeCommand(userFileData) { - // Create a temporary directory, preferably in an application directory - // that only the application has access to. - const fileDir = mkdtempSync('/tmp/tmpdir-'); - // Generate a random filename, do not use user input - const filePath = fileDir + path.sep + crypto.randomUUID(); - // Write the user-supplied data to the temporary file. - fs.writeFileSync(filePath, userFileData); - // Execute a program with a hardcoded path to the binary - child_process.exec(`/bin/cat ${filePath}`, (error, stdout, stderr) => { - // Delete the temporary directory and file if no longer needed - fs.rmSync(fileDir, { recursive: true, force: true }); - if (error) { - console.error(`exec error: ${error}`); - return; - } - console.log(`stdout: ${stdout}`); - console.error(`stderr: ${stderr}`); - }); - } - ``` - - For more information on OS command injection, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html - - Detected non-literal calls to child_process.exec(). This could lead to a command - injection vulnerability. + - python + message: Found a Pyramid cookie without the samesite option correctly set. Pyramid cookies should be handled securely by setting samesite='Lax' in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. metadata: category: security - cwe: CWE-78 - cwe2021-top25: true - cwe2022-top25: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-1275: Sensitive Cookie with Improper SameSite Attribute' + impact: LOW + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#do-not-use-dangerous-functions - security-severity: HIGH - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') - source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-child-process.js + - https://owasp.org/Top10/A01_2021-Broken_Access_Control subcategory: - - audit + - vuln technology: - - javascript - vulnerability_class: - - Command Injection - mode: taint - options: - taint_unify_mvars: true - pattern-sanitizers: - - pattern: | - $CMD = "..." - - pattern: | - $CMD = ["...",...] - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $CP = require('child_process') + - pyramid + patterns: + - pattern-either: + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): ... - - pattern-inside: | - import * as $CP from 'child_process' + $RESPONSE = $REQUEST.response ... - - pattern-inside: | - import $CP from 'child_process' + - pattern-inside: | + def $VIEW(...): ... - - pattern-either: - - pattern: $CP.exec($CMD,...) - - pattern: $CP.execSync($CMD,...) - - pattern: $CP.spawn($CMD,...) - - pattern: $CP.spawnSync($CMD,...) - - focus-metavariable: $CMD - pattern-sources: - - patterns: + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(..., samesite=$SAMESITE, ...) + - pattern: $SAMESITE + - metavariable-regex: + metavariable: $SAMESITE + regex: (?!'Lax') + severity: WARNING + - fix-regex: + regex: (.*)\) + replacement: \1, secure=True) + id: python.pyramid.audit.set-cookie-secure-unsafe-default.pyramid-set-cookie-secure-unsafe-default + languages: + - python + message: Found a Pyramid cookie using an unsafe default for the secure option. Pyramid cookies should be handled securely by setting secure=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW + owasp: + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-either: - pattern-inside: | - function ... (...,$ARG,...) { - ... - } - - focus-metavariable: $ARG - severity: ERROR - - id: php_assert_rule-assert-use + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., secure=$SECURE, ...) + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(...) + severity: WARNING + - fix: | + True + id: python.pyramid.audit.set-cookie-secure-unsafe-value.pyramid-set-cookie-secure-unsafe-value languages: - - php - message: Calling assert with user input is equivalent to eval'ing. + - python + message: Found a Pyramid cookie without the secure option correctly set. Pyramid cookies should be handled securely by setting secure=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. metadata: category: security - cwe: CWE-95 - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection + - A05:2021 - Security Misconfiguration references: - - https://www.php.net/manual/en/function.assert - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/AssertsSniff.php - security-severity: CRITICAL - shortDescription: Improper neutralization of directives in dynamically evaluated code ('Eval Injection') + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration subcategory: - vuln technology: - - php - vulnerability_class: - - Code Injection - mode: taint - pattern-sinks: - - patterns: - - pattern: assert($SINK, ...); - - pattern-not: assert("...", ...); - - pattern: $SINK - pattern-sources: + - pyramid + patterns: - pattern-either: - - patterns: - - pattern-either: - - pattern: $_GET - - pattern: $_POST - - pattern: $_COOKIE - - pattern: $_REQUEST - - pattern: $_SERVER - - patterns: - - pattern: | - Route::$METHOD($ROUTENAME, function(..., $ARG, ...) { ... }) - - focus-metavariable: $ARG + - pattern-inside: | + @pyramid.view.view_config(...) + def $VIEW($REQUEST): + ... + $RESPONSE = $REQUEST.response + ... + - pattern-inside: | + def $VIEW(...): + ... + $RESPONSE = pyramid.httpexceptions.HTTPFound(...) + ... + - pattern-not: $RESPONSE.set_cookie(..., **$PARAMS) + - pattern: $RESPONSE.set_cookie(..., secure=$SECURE, ...) + - pattern: $SECURE + - metavariable-pattern: + metavariable: $SECURE + pattern: | + False + severity: WARNING + - fix: | + True + id: python.pyramid.security.csrf-check-disabled-globally.pyramid-csrf-check-disabled-globally + languages: + - python + message: Automatic check of cross-site request forgery tokens has been explicitly disabled globally, which might leave views unprotected. Use 'pyramid.config.Configurator.set_default_csrf_options(require_csrf=True)' to turn the automatic check for all unsafe methods (per RFC2616). + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - pyramid + patterns: + - pattern-inside: | + $CONFIG.set_default_csrf_options(..., require_csrf=$REQUIRE_CSRF, ...) + - pattern: $REQUIRE_CSRF + - metavariable-comparison: + comparison: $REQUIRE_CSRF == False + metavariable: $REQUIRE_CSRF severity: ERROR - - id: php_backticks_rule-backticks-use + - id: python.pyramid.security.direct-use-of-response.pyramid-direct-use-of-response languages: - - php - message: Backticks use may lead to command injection vulnerabilities. + - python + message: Detected data rendered directly to the end user via 'Response'. This bypasses Pyramid's built-in cross-site scripting (XSS) defenses and could result in an XSS vulnerability. Use Pyramid's template engines to safely render HTML. metadata: category: security - cwe: CWE-94 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true cwe2022-top25: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection references: - - https://www.php.net/manual/en/language.operators.execution.php - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/BackticksSniff.php - security-severity: CRITICAL - shortDescription: Improper control of generation of code ('Code Injection') + - https://owasp.org/Top10/A03_2021-Injection subcategory: - - audit + - vuln technology: - - php - vulnerability_class: - - Code Injection - pattern: '`...`;' + - pyramid + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: | + pyramid.request.Response.text($SINK) + - pattern: | + pyramid.request.Response($SINK) + - pattern: | + $REQ.response.body = $SINK + - pattern: | + $REQ.response.text = $SINK + - pattern: | + $REQ.response.ubody = $SINK + - pattern: | + $REQ.response.unicode_body = $SINK + - pattern: $SINK + pattern-sources: + - patterns: + - pattern-inside: | + @pyramid.view.view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession severity: ERROR - - id: php_crypto_rule-weak-crypto + - fix-regex: + regex: format + replacement: bindparams + id: python.pyramid.security.sqlalchemy-sql-injection.pyramid-sqlalchemy-sql-injection languages: - - php - message: Detected usage of weak crypto function. Consider using stronger alternatives. + - python + message: Distinct, Having, Group_by, Order_by, and Filter in SQLAlchemy can cause sql injections if the developer inputs raw SQL into the before-mentioned clauses. This pattern captures relevant cases in which the developer inputs raw SQL into the distinct, having, group_by, order_by or filter clauses and injects user-input into the raw SQL with any function besides "bindparams". Use bindParams to securely bind user-input to SQL statements. metadata: category: security - cwe: CWE-328 - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://www.php.net/manual/en/book.sodium.php - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php - security-severity: MEDIUM - shortDescription: Use of weak hash + - https://docs.sqlalchemy.org/en/14/tutorial/data_select.html#tutorial-selecting-data subcategory: - - audit + - vuln technology: - - php - vulnerability_class: - - Insecure Hashing Algorithm - patterns: - - pattern: $FUNC(...); - - metavariable-regex: - metavariable: $FUNC - regex: crypt|md5|md5_file|sha1|sha1_file|str_rot13 - severity: WARNING - - id: php_eval_rule-eval-use + - pyramid + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: | + $QUERY = $REQ.dbsession.query(...) + ... + - pattern-either: + - pattern: | + $QUERY.$SQLFUNC("...".$FORMATFUNC(..., $SINK, ...)) + - pattern: | + $QUERY.join(...).$SQLFUNC("...".$FORMATFUNC(..., $SINK, ...)) + - pattern: $SINK + - metavariable-regex: + metavariable: $SQLFUNC + regex: (group_by|order_by|distinct|having|filter) + - metavariable-regex: + metavariable: $FORMATFUNC + regex: (?!bindparams) + pattern-sources: + - patterns: + - pattern-inside: | + from pyramid.view import view_config + ... + @view_config( ... ) + def $VIEW($REQ): + ... + - pattern: $REQ.$ANYTHING + - pattern-not: $REQ.dbsession + severity: ERROR + - id: python.sqlalchemy.security.audit.avoid-sqlalchemy-text.avoid-sqlalchemy-text languages: - - php - message: Evaluating non-constant commands. This can lead to command injection. + - python + message: sqlalchemy.text passes the constructed SQL statement to the database mostly unchanged. This means that the usual SQL injection protections are not applied and this function is vulnerable to SQL injection if user input can reach here. Use normal SQLAlchemy operators (such as or_, and_, etc.) to construct SQL. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true cwe2022-top25: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + impact: LOW + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://www.php.net/manual/en/function.eval - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/NoEvalsSniff.php - security-severity: CRITICAL - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + - https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql subcategory: - audit technology: - - php - vulnerability_class: - - Command Injection - patterns: - - pattern: eval(...); - - pattern-not: eval('...'); + - sqlalchemy + mode: taint + pattern-sinks: + - pattern: | + sqlalchemy.text(...) + pattern-sources: + - patterns: + - pattern: | + $X + $Y + - metavariable-type: + metavariable: $X + type: string + - patterns: + - pattern: | + $X + $Y + - metavariable-type: + metavariable: $Y + type: string + - patterns: + - pattern: | + f"..." + - patterns: + - pattern: | + $X.format(...) + - metavariable-type: + metavariable: $X + type: string + - patterns: + - pattern: | + $X % $Y + - metavariable-type: + metavariable: $X + type: string severity: ERROR - - id: php_exec_rule-exec-use + - fix-regex: + regex: format + replacement: bindparams + id: python.sqlalchemy.security.sqlalchemy-sql-injection.sqlalchemy-sql-injection languages: - - php - message: Executing non-constant commands. This can lead to command injection. + - python + message: Distinct, Having, Group_by, Order_by, and Filter in SQLAlchemy can cause sql injections if the developer inputs raw SQL into the before-mentioned clauses. This pattern captures relevant cases in which the developer inputs raw SQL into the distinct, having, group_by, order_by or filter clauses and injects user-input into the raw SQL with any function besides "bindparams". Use bindParams to securely bind user-input to SQL statements. metadata: category: security - cwe: CWE-94 + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true cwe2022-top25: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + impact: HIGH + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/SystemExecFunctionsSniff.php - security-severity: CRITICAL - shortDescription: Improper control of generation of code ('Code Injection') + - https://owasp.org/Top10/A03_2021-Injection subcategory: - - audit + - vuln technology: - - php - vulnerability_class: - - Code Injection + - sqlalchemy patterns: - - pattern: $FUNC(...); - - pattern-not: $FUNC('...', ...); + - pattern-either: + - pattern: | + def $FUNC(...,$VAR,...): + ... + $SESSION.query(...).$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) + - pattern: | + def $FUNC(...,$VAR,...): + ... + $SESSION.query.join(...).$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) + - pattern: | + def $FUNC(...,$VAR,...): + ... + $SESSION.query.$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) + - pattern: | + def $FUNC(...,$VAR,...): + ... + query.$SQLFUNC("...".$FORMATFUNC(...,$VAR,...)) - metavariable-regex: - metavariable: $FUNC - regex: exec|passthru|proc_open|popen|shell_exec|system|pcntl_exec - severity: ERROR - - id: php_file_rule-file-inclusion + metavariable: $SQLFUNC + regex: (group_by|order_by|distinct|having|filter) + - metavariable-regex: + metavariable: $FORMATFUNC + regex: (?!bindparams) + severity: WARNING + - id: python.twilio.security.twiml-injection.twiml-injection languages: - - php - message: Detected non-constant file inclusion. This can lead to local file inclusion (LFI) or remote file inclusion (RFI) if user input reaches this statement. LFI and RFI could lead to sensitive files being obtained by attackers. Instead, explicitly specify what to include. If that is not a viable solution, validate user input thoroughly. + - python + message: Using non-constant TwiML (Twilio Markup Language) argument when creating a Twilio conversation could allow the injection of additional TwiML commands metadata: category: security - cwe: CWE-98 - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: MEDIUM + cwe: + - 'CWE-91: XML Injection' + impact: MEDIUM + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection + - A03:2021 - Injection references: - - https://www.php.net/manual/en/function.include.php - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/EasyRFISniff.php - - https://en.wikipedia.org/wiki/File_inclusion_vulnerability#Types_of_Inclusion - security-severity: CRITICAL - shortDescription: Improper control of filename for include/require statement in PHP program ('PHP Remote File Inclusion') - subcategory: - - audit + - https://codeberg.org/fennix/funjection + subcategory: vuln technology: - - php - vulnerability_class: - - Code Injection + - python + - twilio + - twiml mode: taint pattern-sanitizers: - - patterns: - - pattern-either: - - pattern-inside: basename($PATH, ...) - - pattern-inside: linkinfo($PATH, ...) - - pattern-inside: readlink($PATH, ...) - - pattern-inside: realpath($PATH, ...) - - pattern-inside: include_safe(...) + - pattern: xml.sax.saxutils.escape(...) + - pattern: html.escape(...) pattern-sinks: - patterns: - - pattern-inside: $FUNC(...); - - pattern: $VAR - - metavariable-regex: - metavariable: $FUNC - regex: \b(include|include_once|require|require_once)\b + - pattern: | + $CLIENT.calls.create(..., twiml=$SINK, ...) + - focus-metavariable: $SINK pattern-sources: + - pattern: | + f"..." + - pattern: | + "..." % ... + - pattern: | + "...".format(...) - patterns: - - pattern-either: - - pattern: $_GET - - pattern: $_POST - - pattern: $_COOKIE - - pattern: $_REQUEST - - pattern: $_SERVER - severity: ERROR - - id: php_ftp_rule-ftp-use - languages: - - php - message: FTP allows for unencrypted file transfers. Consider using an encrypted alternative. - metadata: - category: security - cwe: CWE-319 - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://www.php.net/manual/en/intro.ftp.php - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/FringeFunctionsSniff.php - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - subcategory: - - audit - technology: - - php - vulnerability_class: - - Mishandled Sensitive Information - patterns: - - pattern: $FUNC(...); - - metavariable-regex: - metavariable: $FUNC - regex: ftp_.+ - severity: WARNING - - id: php_mcrypt_rule-mcrypt-use - languages: - - php - message: Mcrypt functionality has been deprecated and/or removed in recent PHP versions. Consider using Sodium or OpenSSL. - metadata: - category: security - cwe: CWE-676 - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - owasp: - - A9:2017-Using Components with Known Vulnerabilities - - A06:2021-Vulnerable and Outdated Components - references: - - https://www.php.net/manual/en/intro.mcrypt.php - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/CryptoFunctionsSniff.php - security-severity: MEDIUM - shortDescription: Use of potentially dangerous function - subcategory: - - audit - technology: - - php - vulnerability_class: - - Dangerous Method or Function - patterns: - - pattern: $FUNC(...); - - metavariable-regex: - metavariable: $FUNC - regex: (mcrypt_|mdecrypt_).+ + - pattern: $ARG + - pattern-inside: | + def $F(..., $ARG, ...): + ... severity: WARNING - - id: php_phpinfo_rule-phpinfo-use + - id: ruby.aws-lambda.security.activerecord-sqli.activerecord-sqli languages: - - php - message: The 'phpinfo' function may reveal sensitive information about your environment. + - ruby + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `Example.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]`' metadata: category: security - cwe: CWE-497 + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' cwe2021-top25: true - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://www.php.net/manual/en/function.phpinfo - - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/PhpinfosSniff.php - security-severity: MEDIUM - shortDescription: Exposure of sensitive system information to an unauthorized control sphere + - https://guides.rubyonrails.org/active_record_querying.html#finding-by-sql subcategory: - vuln technology: - - php - vulnerability_class: - - Mishandled Sensitive Information - pattern: phpinfo(...); + - aws-lambda + - active-record + mode: taint + pattern-sinks: + - patterns: + - pattern: $QUERY + - pattern-either: + - pattern: ActiveRecord::Base.connection.execute($QUERY,...) + - pattern: $MODEL.find_by_sql($QUERY,...) + - pattern: $MODEL.select_all($QUERY,...) + - pattern-inside: | + require 'active_record' + ... + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context) + ... + end severity: WARNING - - id: properties_spring_rule-SpringActuatorFullyEnabled + - id: ruby.aws-lambda.security.mysql2-sqli.mysql2-sqli languages: - - generic - message: "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints\nsuch as /actuator/env, /actuator/logfile, /actuator/heapdump and others.\nIf the application lacks proper security measures (e.g., authentication and \nauthorization), sensitive data could be accessed, compromising the application and \nits infrastructure. This configuration poses a serious risk in production \nenvironments or public-facing deployments.\n\nTo mitigate the risks, take the following measures:\n - Expose only the Actuator endpoints required for your use case\n - For production environments, restrict exposure to non-sensitive endpoints \n like `health` or `info`\n - Ensure Actuator endpoints are protected with authentication and authorization \n (e.g., via Spring Security)\n - Use environment-specific configurations to limit exposure in production\n\nSecure Code Example:\nInstead of include: \"*\", list only the endpoints you need to expose:\n```\nmanagement.endpoints.web.exposure.include=\"health,info,metrics\"\n```\n\nReferences:\n- https://docs.spring.io/spring-boot/reference/actuator/endpoints.html#actuator.endpoints.exposing\n- https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785\n- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators\n" + - ruby + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use sanitize statements like so: `escaped = client.escape(user_input)`' metadata: category: security confidence: MEDIUM - cwe: CWE-497 + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true impact: HIGH likelihood: MEDIUM owasp: - - A01:2021-Broken Access Control - - A3:2017-Sensitive Data Exposure - security-severity: Medium - shortDescription: Exposure of sensitive system information to an unauthorized control sphere + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/brianmario/mysql2 + subcategory: + - vuln technology: - - java - paths: - include: - - '*properties' - pattern: management.endpoints.web.exposure.include=* + - aws-lambda + - mysql2 + mode: taint + pattern-sanitizers: + - pattern: $CLIENT.escape(...) + pattern-sinks: + - patterns: + - pattern: $QUERY + - pattern-either: + - pattern: $CLIENT.query($QUERY,...) + - pattern: $CLIENT.prepare($QUERY,...) + - pattern-inside: | + require 'mysql2' + ... + pattern-sources: + - patterns: + - pattern: event + - pattern-inside: | + def $HANDLER(event, context) + ... + end severity: WARNING - - id: python_crypto_rule-HTTPConnectionPool + - id: ruby.aws-lambda.security.pg-sqli.pg-sqli languages: - - python - message: "The application is using HTTPConnectionPool method. This method transmits\ndata in cleartext, which is vulnerable to MITM (Man in the middle)\nattacks. In MITM attacks, the data transmitted over the unencrypted\nconnection can be intercepted, read and/or modified by unauthorized\nparties which can lead to data integrity and confidentiality loss. \n\nTo mitigate this issue, use HTTPSConnectionPool instead, which encrypts \ncommunications and enhances security.\n\nSecure Code Example:\n```\nimport urllib3\nspool = urllib3.connectionpool.HTTPSConnectionPool(\"example.com\")\n```\n" + - ruby + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `conn.exec_params(''SELECT $1 AS a, $2 AS b, $3 AS c'', [1, 2, nil])`' metadata: category: security confidence: MEDIUM - cwe: CWE-319 - impact: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A01:2017 - Injection + - A03:2021 - Injection references: - - https://urllib3.readthedocs.io/en/1.2.1/pools.html#urllib3.connectionpool.HTTPSConnectionPool - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + - https://www.rubydoc.info/gems/pg/PG/Connection subcategory: - - audit + - vuln technology: - - python - pattern-either: - - pattern: urllib3.HTTPConnectionPool(...) - - pattern: urllib3.connectionpool.HTTPConnectionPool(...) - severity: WARNING - - id: python_django_rule-django-raw-used - languages: - - python - message: "SQL Injections are a critical type of vulnerability that can lead to data \nor system compromise. By dynamically generating SQL query strings, user \ninput may be able to influence the logic of the SQL statement. \nThis could lead to an adversary accessing information they should not \nhave access to, or in some circumstances, being able to execute OS functionality\nor code.\n\nReplace all dynamically generated SQL queries with parameterized queries. \nIn situations where dynamic queries must be created, never use direct user input,\nbut instead use a map or dictionary of valid values and resolve them using a user \nsupplied key.\n\nFor example, some database drivers do not allow parameterized queries for \n`>` or `<` comparison operators. In these cases, do not use a user supplied \n`>` or `<` value, but rather have the user supply a `gt` or `lt` value. \nThe alphabetical values are then used to look up the `>` and `<` values to be used \nin the construction of the dynamic query. The same goes for other queries where \ncolumn or table names are required but cannot be parameterized.\n\nData that is possible user-controlled from a python request is passed\nto `raw()` function. To remediate this issue, use django's QuerySets, \nwhich are built with query parameterization and therefore not vulnerable \nto sql injection. For example, you could use `Entry.objects.filter(date=2006)`\n\nIf for some reason this is not feasible, ensure calls including user-supplied \ndata pass it in to the `params` parameter of the `raw()` method.\nBelow is an example using `raw()`, passing in user-supplied data as `params`. \nThis will treat the query as a parameterized query and `params` as strictly data, \npreventing any possibility of SQL Injection.\n\n```\ndef test(request):\n uname = request.GET[\"username\"] \n res = User.objects.raw('SELECT * FROM myapp_user WHERE username = %s', (uname,))\n```\n\nFor more information on QuerySet see:\n- https://docs.djangoproject.com/en/5.0/ref/models/querysets/\n\nFor more information on SQL Injection see OWASP:\n- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html\n" - metadata: - category: security - cwe: CWE-89 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an SQL Command ('SQL Injection') + - aws-lambda + - postgres + - pg mode: taint pattern-sinks: - patterns: - pattern: $QUERY - - pattern-inside: $MODEL.objects.raw($QUERY, ... ) + - pattern-either: + - pattern: $CONN.exec($QUERY,...) + - pattern: $CONN.exec_params($QUERY,...) + - pattern: $CONN.exec_prepared($QUERY,...) + - pattern: $CONN.async_exec($QUERY,...) + - pattern: $CONN.async_exec_params($QUERY,...) + - pattern: $CONN.async_exec_prepared($QUERY,...) + - pattern-inside: | + require 'pg' + ... pattern-sources: - patterns: - - pattern: $PARAM - - pattern-inside: "def $VIEW(...,$PARAM,...):\n ...\n return ... \n" - severity: ERROR - - id: python_django_rule-django-rawsql-used + - pattern: event + - pattern-inside: | + def $HANDLER(event, context) + ... + end + severity: WARNING + - id: ruby.aws-lambda.security.sequel-sqli.sequel-sqli languages: - - python - message: "SQL Injections are a critical type of vulnerability that can lead to data or system compromise. By \ndynamically generating SQL query strings, user input may be able to influence the logic of the SQL \nstatement. This could lead to an adversary accessing information they should not have access to, or in\nsome circumstances, being able to execute OS functionality or code.\n\nReplace all dynamically generated SQL queries with parameterized queries. In situations where dynamic \nqueries must be created, never use direct user input, but instead use a map or dictionary of valid values \nand resolve them using a user supplied key.\n\nFor example, some database drivers do not allow parameterized queries for `>` or `<` comparison operators. \nIn these cases, do not use a user supplied `>` or `<` value, but rather have the user supply a `gt` or `lt` \nvalue. The alphabetical values are then used to look up the `>` and `<` values to be used in the \nconstruction of the dynamic query. The same goes for other queries where column or table names are required \nbut cannot be parameterized.\n\nTo remediate this issue, do not use `raw` or `RawSQL` but use other `QuerySet` methods to achieve the same\ngoals. If for some reason this is not feasible, ensure calls including user-supplied data pass it in to \nthe `params` parameter of the `RawSQL` method.\n\nWhile not recommended due to [potential SQL Injection](https://docs.djangoproject.com/en/5.0/ref/models/expressions/#raw-sql-expressions), below is an example using `RawSQL`.\nPassing in user-supplied data as a `param` which will escape the input:\n\n```\n# If dealing with integer based user input, restrict the values to integers only using the\n# path configuration: path('/someview/', views.some_view, name='someview'),\n\n# views.py\ndef some_view(request, user_supplied_id):\n # Never use string interpolation in the `sql` parameter.\n # Never quote the `%s` string format such as `... where id='%s'` as this could lead to SQL Injection.\n # Pass the user supplied data only in the `params` parameter.\n for obj in DBObject.objects.all().annotate(\n val=RawSQL(sql=\"select id from some_secondary_table where id=%s\", params=[user_supplied_id])):\n # Work with the results from the query\n # ...\n```\n\nFor more information on QuerySets see:\n- https://docs.djangoproject.com/en/4.2/ref/models/querysets/#queryset-api\n\nFor more information on SQL Injection see OWASP:\n- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html\n" + - ruby + message: 'Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `DB[''select * from items where name = ?'', name]`' metadata: category: security - cwe: CWE-89 + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of special elements used in an SQL Command ('SQL Injection') + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/jeremyevans/sequel#label-Arbitrary+SQL+queries + subcategory: + - vuln + technology: + - aws-lambda + - sequel mode: taint pattern-sinks: - patterns: - pattern: $QUERY - - pattern-inside: django.db.models.expressions.RawSQL($QUERY, ... ) + - pattern-either: + - pattern: DB[$QUERY,...] + - pattern: DB.run($QUERY,...) + - pattern-inside: | + require 'sequel' + ... pattern-sources: - patterns: - - pattern: $PARAM + - pattern: event - pattern-inside: | - def $VIEW(...,$PARAM,...): + def $HANDLER(event, context) ... - return ... - severity: ERROR - - id: python_escaping_rule-django - languages: - - python - message: | - Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat - user input - as markup or script code. It is important to encode the data depending on the specific context - it - is used in. There are at least six context types: - - - Inside HTML tags `
    context 1
    ` - - Inside attributes: `
    ` - - Inside event attributes `` - - Inside script blocks: `` - - Unsafe element HTML assignment: `element.innerHTML = "context 5"` - - Inside URLs: `link` - - Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if - user input - is ever output inside of script tags. - - User input that is displayed within the application must be encoded, sanitized or validated - to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be - taken - to not mix server-side templating with client-side templating, as the server-side templating - will - not encode things like {{ 7*7 }} which may execute client-side templating features. - - It is _NOT_ advised to encode user input prior to inserting into a data store. The data will - need to be - encoded depending on context of where it is output. It is much safer to force the displaying - system to - handle the encoding and not attempt to guess how it should be encoded. - - Consider using - [format_html](https://docs.djangoproject.com/en/4.2/ref/utils/#django.utils.html.format_html) - instead of - the `django.utils.safestring` methods. - - Example using `format_html`: - ``` - # Use format_html to create an HTML link, using href as the parameter - # which will be encoded automatically - format_html("
  • Some Link
  • ", href) - ``` - - For more information on XSS see OWASP: - - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html - metadata: - category: security - cwe: CWE-79 - owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - patterns: - - pattern-not-inside: django.utils.html.format_html(...) - - pattern-either: - - patterns: - - pattern: django.utils.safestring.SafeText(...) - - pattern-not: django.utils.safestring.SafeText("...") - - patterns: - - pattern: django.utils.safestring.SafeUnicode(...) - - pattern-not: django.utils.safestring.SafeUnicode("...") - - patterns: - - pattern: django.utils.safestring.SafeString(...) - - pattern-not: django.utils.safestring.SafeString("...") - - patterns: - - pattern: django.utils.safestring.SafeBytes(...) - - pattern-not: django.utils.safestring.SafeBytes("...") - - patterns: - - pattern: django.utils.safestring.mark_safe(...) - - pattern-not: django.utils.safestring.mark_safe("...") + end severity: WARNING - - id: python_flask_rule-path-traversal-open + - id: ruby.aws-lambda.security.tainted-deserialization.tainted-deserialization languages: - - python - message: "Found request data in a call to 'open'. An attacker can manipulate this input to access files outside the intended \ndirectory. This can lead to unauthorized access to sensitive files or directories. To prevent path traversal attacks, \navoid using user-controlled input in file paths. If you must use user-controlled input, validate and sanitize the \ninput to ensure it does not contain any path traversal sequences. For example, you can use the `os.path.join` function \nto safely construct file paths or validate that the absolute path starts with the directory which is whitelisted for \naccessing file. The following code snippet demonstrates how to validate a file path from user-controlled input:\n```\nimport os\n\ndef safe_open_file(filename, base_path):\n # Resolve the absolute path of the user-supplied filename\n absolute_path = os.path.abspath(filename)\n\n # Check that the absolute path starts with the base path\n if not absolute_path.startswith(base_path):\n raise ValueError(\"Invalid file path\")\n\n return open(absolute_path, 'r')\n```\nFor more information, see the OWASP Path Traversal page: https://owasp.org/www-community/attacks/Path_Traversal\n" + - ruby + message: Deserialization of a string tainted by `event` object found. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of `load` can cause remote code execution. Loading user input with MARSHAL, YAML or CSV can potentially be dangerous. If you need to deserialize untrusted data, you should use JSON as it is only capable of returning 'primitive' types such as strings, arrays, hashes, numbers and nil. metadata: category: security confidence: MEDIUM - cwe: CWE-22 + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true impact: HIGH likelihood: MEDIUM owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures references: - - https://owasp.org/www-community/attacks/Path_Traversal - security-severity: CRITICAL - shortDescription: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') + - https://ruby-doc.org/core-3.1.2/doc/security_rdoc.html + - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb + subcategory: + - vuln technology: - - flask - pattern-either: + - ruby + - aws-lambda + mode: taint + pattern-sinks: - patterns: - - pattern: open(...) + - pattern: $SINK - pattern-either: - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - open(..., <... $ROUTEVAR ...>, ...) + YAML.load($SINK,...) - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - with open(..., <... $ROUTEVAR ...>, ...) as $FD: - ... + CSV.load($SINK,...) - pattern-inside: | - @$APP.route($ROUTE, ...) - def $FUNC(..., $ROUTEVAR, ...): - ... - $INTERIM = <... $ROUTEVAR ...> - ... - open(..., <... $INTERIM ...>, ...) - - pattern: open(..., <... flask.request.$W.get(...) ...>, ...) - - pattern: open(..., <... flask.request.$W[...] ...>, ...) - - pattern: open(..., <... flask.request.$W(...) ...>, ...) - - pattern: open(..., <... flask.request.$W ...>, ...) - - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W.get(...) ...> - ... - open(<... $INTERIM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W[...] ...> - ... - open(<... $INTERIM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W(...) ...> - ... - open(<... $INTERIM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W ...> - ... - open(<... $INTERIM ...>, ...) - - pattern: open(...) - - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W.get(...) ...> - ... - with open(<... $INTERIM ...>, ...) as $F: - ... - - pattern: open(...) + Marshal.load($SINK,...) + - pattern-inside: | + Marshal.restore($SINK,...) + pattern-sources: - patterns: + - pattern: event - pattern-inside: | - $INTERIM = <... flask.request.$W[...] ...> - ... - with open(<... $INTERIM ...>, ...) as $F: + def $HANDLER(event, context) ... - - pattern: open(...) + end + severity: WARNING + - id: ruby.aws-lambda.security.tainted-sql-string.tainted-sql-string + languages: + - ruby + message: Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://rorsecurity.info/portfolio/ruby-on-rails-sql-injection-cheat-sheet + subcategory: + - vuln + technology: + - aws-lambda + mode: taint + pattern-sinks: - patterns: - - pattern-inside: | - $INTERIM = <... flask.request.$W(...) ...> - ... - with open(<... $INTERIM ...>, ...) as $F: - ... - - pattern: open(...) + - pattern-either: + - patterns: + - pattern: | + "...#{...}..." + - pattern-regex: (?i)(select|delete|insert|create|update|alter|drop)\b|\w+\s*!?[<>=].* + - patterns: + - pattern-either: + - pattern: Kernel::sprintf("$SQLSTR", ...) + - pattern: | + "$SQLSTR" + $EXPR + - pattern: | + "$SQLSTR" % $EXPR + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b|\w+\s*!?[<>=].* + - pattern-not-inside: | + puts(...) + pattern-sources: - patterns: + - pattern: event - pattern-inside: | - $INTERIM = <... flask.request.$W ...> - ... - with open(<... $INTERIM ...>, ...) as $F: + def $HANDLER(event, context) ... - - pattern: open(...) + end severity: ERROR - - id: python_flask_rule-tainted-sql-string + - id: ruby.lang.security.bad-deserialization.bad-deserialization languages: - - python - message: "Detected user input used to manually construct a SQL string. This is usually\nbad practice because manual construction could accidentally result in a SQL\ninjection. An attacker could use a SQL injection to steal or modify contents\nof the database. Instead, use a parameterized query which is available\nby default in most database engines. Alternatively, consider using an\nobject-relational mapper (ORM) such as SQLAlchemy which will protect your queries.\n\nSQL Injections are a critical type of vulnerability that can lead to data \nor system compromise. By dynamically generating SQL query strings, user \ninput may be able to influence the logic of an SQL statement. \nThis could lead to an malicious parties accessing information they should not \nhave access to, or in some circumstances, being able to execute OS functionality\nor code.\n\nReplace all dynamically generated SQL queries with parameterized queries. \nIn situations where dynamic queries must be created, never use direct user input,\nbut instead use a map or dictionary of valid values and resolve them using a user \nsupplied key.\n\nFor example, some database drivers do not allow parameterized queries for \n`>` or `<` comparison operators. In these cases, do not use a user supplied \n`>` or `<` value, but rather have the user supply a `gt` or `lt` value. \nThe alphabetical values are then used to look up the `>` and `<` values to be used \nin the construction of the dynamic query. The same goes for other queries where \ncolumn or table names are required but cannot be parameterized.\nData that is possible user-controlled from a python request is passed\nto `execute()` function. To remediate this issue, use SQLAlchemy statements\nwhich are built with query parameterization and therefore not vulnerable \nto sql injection.\n\nIf for some reason this is not feasible, ensure calls including user-supplied \ndata pass it in to the `params` parameter of the `execute()` method.\nBelow is an example using `execute()`, passing in user-supplied data as `params`. \nThis will treat the query as a parameterized query and `params` as strictly data, \npreventing any possibility of SQL Injection.\n\n```\nname = request.args.get('name')\nreq = text('SELECT * FROM student WHERE firstname = :x')\nresult = db.session.execute(req, {\"x\":name})\n```\nFor more information on QuerySets see:\n- https://docs.djangoproject.com/en/4.2/ref/models/querysets/#queryset-api\nFor more information on SQL Injections see OWASP:\n- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html\n" + - ruby + message: Checks for unsafe deserialization. Objects in Ruby can be serialized into strings, then later loaded from strings. However, uses of load and object_load can cause remote code execution. Loading user input with MARSHAL or CSV can potentially be dangerous. Use JSON in a secure fashion instead. metadata: category: security - cwe: CWE-89 + confidence: MEDIUM + cwe: + - 'CWE-502: Deserialization of Untrusted Data' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: High - shortDescription: Improper neutralization of special elements used in an SQL Command ('SQL Injection') + - A08:2017 - Insecure Deserialization + - A08:2021 - Software and Data Integrity Failures + references: + - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_deserialize.rb + subcategory: + - vuln + technology: + - ruby mode: taint pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - <... "$QUERYLIKE" ...> - - metavariable-regex: - metavariable: $QUERYLIKE - regex: .*\b(?i)(SELECT .+ FROM|WHERE|DELETE FROM|INSERT INTO| CREATE TABLE|UPDATE .+ SET|ALTER TABLE|ALTER COLUMN|DROP COLUMN|DROP TABLE|ORDER BY)\b.* + - pattern-either: + - pattern: | + CSV.load(...) + - pattern: | + Marshal.load(...) + - pattern: | + Marshal.restore(...) + - pattern: | + Oj.object_load(...) + - pattern: | + Oj.load($X) pattern-sources: - pattern-either: - - pattern: flask.request.$ANYTHING - - patterns: - - pattern-inside: | - @$APP.route(...) - def $FUNC(..., $ROUTEVAR, ...): - ... - - pattern: $ROUTEVAR + - pattern: params + - pattern: cookies severity: ERROR - - id: python_flask_rule-flask-open-redirect + - id: ruby.lang.security.dangerous-exec.dangerous-exec languages: - - python - message: |- - Data from request is passed to redirect(). This is an open redirect and could be exploited. Consider using 'url_for()' to generate links to known locations. If you must use a URL to unknown pages, consider using 'urlparse()' or similar and checking if the 'netloc' property is the same as your site's host name. For example: - - Example: - ```python - from flask import Flask, request, redirect, url_for - from urllib.parse import urlparse - - app = Flask(__name__) - - @app.route('/login') - def login(): - next = request.args.get('next') - if not next: - next = url_for('index') - if urlparse(next).netloc != urlparse(request.url).netloc: - return redirect(url_for('index')) - return redirect(next) - ``` - See the references for more information. - metadata: - category: security - confidence: LOW - cwe: CWE-601 - impact: MEDIUM - likelihood: LOW + - ruby + message: Detected non-static command inside $EXEC. Audit the input to '$EXEC'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A01:2021-Broken Access Control - - A5:2017-Broken Access Control - references: | - - https://flask-login.readthedocs.io/en/latest/#login-example - - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html#dangerous-url-redirect-example-1 - - https://docs.python.org/3/library/urllib.parse.html#url-parsing - security-severity: MEDIUM - shortDescription: URL redirection to untrusted site ('Open Redirect') + - A03:2021 - Injection + references: + - https://guides.rubyonrails.org/security.html#command-line-injection + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_execute.rb subcategory: - - audit + - vuln technology: - - flask - patterns: - - pattern-inside: | - @$APP.route(...) - def $X(...): - ... - - pattern-not-inside: | - @$APP.route(...) - def $X(...): - ... - if <... werkzeug.urls.url_parse($V) ...>: - ... - - pattern-either: - - pattern: flask.redirect(<... flask.request.$W.get(...) ...>, ...) - - pattern: flask.redirect(<... flask.request.$W[...] ...>, ...) - - pattern: flask.redirect(<... flask.request.$W(...) ...>, ...) - - pattern: flask.redirect(<... flask.request.$W ...>, ...) - - pattern: | - $V = flask.request.$W.get(...) - ... - flask.redirect(<... $V ...>, ...) - - pattern: | - $V = flask.request.$W[...] - ... - flask.redirect(<... $V ...>, ...) + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: - pattern: | - $V = flask.request.$W(...) - ... - flask.redirect(<... $V ...>, ...) + $EXEC(...) + - pattern-not: | + $EXEC("...","...","...",...) + - pattern-not: | + $EXEC(["...","...","...",...],...) + - pattern-not: | + $EXEC({...},"...","...","...",...) + - pattern-not: | + $EXEC({...},["...","...","...",...],...) + - metavariable-regex: + metavariable: $EXEC + regex: ^(system|exec|spawn|Process.exec|Process.spawn|Open3.capture2|Open3.capture2e|Open3.capture3|Open3.popen2|Open3.popen2e|Open3.popen3|IO.popen|Gem::Util.popen|PTY.spawn)$ + pattern-sources: + - patterns: - pattern: | - $V = flask.request.$W - ... - flask.redirect(<... $V ...>, ...) - - pattern-not: flask.redirect(flask.request.path) - - pattern-not: flask.redirect(flask.request.path + ...) - - pattern-not: flask.redirect(f"{flask.request.path}...") + def $F(...,$ARG,...) + ... + end + - focus-metavariable: $ARG + - pattern: params + - pattern: cookies severity: WARNING - - id: python_jwt_rule-jwt-none-alg + - id: ruby.lang.security.divide-by-zero.divide-by-zero languages: - - python - message: | - Detected use of the 'none' algorithm in a JWT token. - The 'none' algorithm assumes the integrity of the token has already - been verified. This would allow a malicious actor to forge a JWT token - that will automatically be verified. Do not explicitly use the 'none' - algorithm. Instead, use an algorithm such as 'HS256'. + - ruby + message: Detected a possible ZeroDivisionError. metadata: category: security confidence: MEDIUM - cwe: CWE-327 + cwe: + - 'CWE-369: Divide By Zero' impact: MEDIUM likelihood: MEDIUM - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures references: - - https://owasp.org/Top10/A02_2021-Cryptographic_Failures - security-severity: MEDIUM - shortDescription: Use of a Broken or Risky Cryptographic Algorithm - source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_divide_by_zero.rb subcategory: - vuln technology: - - jwt - pattern-either: - - pattern: jwt.encode(...,algorithm="none",...) - - pattern: jwt.decode(...,algorithms=[...,"none",...],...) - severity: ERROR - - id: python_pyramid_rule-pyramid-csrf-origin-check + - ruby + mode: taint + pattern-sinks: + - patterns: + - pattern-inside: $NUMER / 0 + - pattern: $NUMER + pattern-sources: + - patterns: + - pattern: $VAR + - metavariable-regex: + metavariable: $VAR + regex: ^\d*(?!\.)$ + severity: WARNING + - fix-regex: + regex: =\s*false + replacement: = true + id: ruby.lang.security.force-ssl-false.force-ssl-false languages: - - python - message: "Automatic check of the referrer for cross-site request forgery tokens\nhas been explicitly disabled globally, which might leave views unprotected\nwhen an unsafe CSRF storage policy is used. By passing `check_origin=False` \nto `set_default_csrf_options()` method, you opt out of checking the origin \nof the domain in the referrer header or the origin header, which can make \nthe application vulnerable to CSRF attacks, specially if CSRF token is not \nproperly implemented.\nCSRF attacks are a type of exploit where an attacker tricks a user into \nexecuting unwanted actions on a web application in which they are authenticated. \nIf a user is logged into a web application, an attacker could create a malicious \nlink or script on another site that causes the user's browser to make a request \nto the web application, carrying out an action without the user's consent.\n\nTo mitigate this vulnerability, use \n'pyramid.config.Configurator.set_default_csrf_options(check_origin=True)'\nto turn the automatic check for all unsafe methods (per RFC2616).\n\nSecure Code Example:\n```\ndef safe(config):\n config.set_csrf_storage_policy(CookieCSRFStoragePolicy())\n config.set_default_csrf_options(check_origin=True)\n```\n" + - ruby + message: Checks for configuration setting of force_ssl to false. Force_ssl forces usage of HTTPS, which could lead to network interception of unencrypted application traffic. To fix, set config.force_ssl = true. metadata: category: security - confidence: MEDIUM - cwe: CWE-352 - cwe2021-top25: "true" - cwe2022-top25: "true" - impact: LOW - license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: HIGH + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: MEDIUM likelihood: LOW owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - - https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/security.html - security-severity: MEDIUM - shortDescription: Cross-site request forgery (CSRF) + - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_force_ssl.rb subcategory: - vuln technology: - - pyramid - vulnerability_class: - - Cross-Site Request Forgery (CSRF) - patterns: - - pattern-inside: | - $CONFIG.set_default_csrf_options(..., check_origin=$CHECK_ORIGIN, ...) - - pattern: | - $CHECK_ORIGIN - - metavariable-comparison: - comparison: $CHECK_ORIGIN == False - metavariable: $CHECK_ORIGIN + - ruby + pattern: config.force_ssl = false severity: WARNING - - id: ruby_cookie_rule-CheckCookieStoreSessionSecurityAttributes + - id: ruby.lang.security.hardcoded-http-auth-in-controller.hardcoded-http-auth-in-controller languages: - ruby - message: "The detected issue pertains to a Rails application where the session \nconfiguration, specifically using cookie_store, has been identified \nwith the $KEY attribute set to false. This setting is potentially \ninsecure because it may relate to crucial security attributes such \nas HttpOnly or Secure flags not being enforced. In the context of \nweb applications, these flags play a vital role in enhancing session \nsecurity:\n\n- HttpOnly Flag: When enabled, this flag prevents client-side scripts\nfrom accessing the cookie. This mitigation is crucial for reducing \nthe risk of cross-site scripting (XSS) attacks, where an attacker \nmight attempt to steal session cookies.\n- Secure Flag: This flag ensures that cookies are sent over secure, \nencrypted connections only (HTTPS). It's a critical security measure \nthat helps prevent cookies from being intercepted by attackers when \ntransmitted over an unencrypted connection.\n\nTo mitigate the identified security risk and ensure that your Rails \napplication's session cookies are securely configured. \n\nSecure Code Example:\n```\n# config/initializers/session_store.rb\nRails.application.config.session_store :cookie_store, key: '_your_app_session',\n httponly: true,\n secure: Rails.env.production?\n```\n" + message: Detected hardcoded password used in basic authentication in a controller class. Including this password in version control could expose this credential. Consider refactoring to use environment variables or configuration files. metadata: category: security - cwe: CWE-1004 + confidence: HIGH + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration + - A07:2021 - Identification and Authentication Failures references: - - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-cookie-store-session-security-attributes.yaml - security-severity: LOW - shortDescription: Sensitive cookie without 'HttpOnly' and 'Secure' flags + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/basic_auth/index.markdown + subcategory: + - audit technology: - ruby - - rails + - secrets patterns: - - pattern-either: - - patterns: - - pattern: | - :$KEY => false - - pattern-inside: | - ActionController::Base.session = {...} - - pattern: | - $MODULE::Application.config.session_store :cookie_store, ..., :$KEY => false, ... - - pattern: | - $CLASS.application.config.session_store :cookie_store, ..., $KEY: false, ... - - metavariable-regex: - metavariable: $KEY - regex: ^(session_)?(http_?only|secure)$ - severity: INFO - - id: ruby_cookie_rule-CookieSerialization + - pattern-inside: | + class $CONTROLLER < ApplicationController + ... + http_basic_authenticate_with ..., :password => "$SECRET", ... + end + - focus-metavariable: $SECRET + severity: WARNING + - id: ruby.lang.security.hardcoded-secret-rsa-passphrase.hardcoded-secret-rsa-passphrase languages: - ruby - message: "The rule warns of a significant security risk in applications that use \nRuby's Marshal module for deserializing cookies. Marshal can serialize \nand deserialize Ruby objects, which, while powerful, poses a risk if \nmisused. If an attacker crafts a malicious cookie that is deserialized, \nit could lead to remote code execution (RCE) on the server due to \nMarshal.load's ability to execute code in deserialized objects. To mitigate \nthis risk, developers are advised to switch from Marshal to JSON for cookie \nserialization. JSON is safer as it cannot execute arbitrary code, reducing \nthe threat of RCE vulnerabilities from deserialized user data. The hybrid \ncheck is just to warn users to migrate to :json for best practice.\n\nSecure code example:\n```\n# In Rails, configure the cookie serializer to :json\n# config/initializers/cookies_serializer.rb\nRails.application.config.action_dispatch.cookies_serializer = :json\n```\n\nAdditionally, always validate and sanitize user-supplied data as much \nas possible, even when using JSON, to further secure your application \nagainst various injection attacks.\n" + message: Found the use of an hardcoded passphrase for RSA. The passphrase can be easily discovered, and therefore should not be stored in source-code. It is recommended to remove the passphrase from source-code, and use system environment variables or a restricted configuration file. metadata: category: security - cwe: CWE-94 + confidence: HIGH + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection + - A07:2021 - Identification and Authentication Failures references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/cookie-serialization.yaml - - https://robertheaton.com/2013/07/22/how-to-hack-a-rails-app-using-its-secret-token/ - security-severity: HIGH - shortDescription: Improper control of generation of code ('Code Injection') + - https://cwe.mitre.org/data/definitions/522.html + subcategory: + - vuln technology: - ruby - pattern-either: - - pattern: | - Rails.application.config.action_dispatch.cookies_serializer = :marshal - - pattern: | - Rails.application.config.action_dispatch.cookies_serializer = :hybrid - severity: ERROR - - id: ruby_crypto_rule-InsufficientRSAKeySize + - secrets + patterns: + - pattern-either: + - pattern: OpenSSL::PKey::RSA.new(..., '...') + - pattern: OpenSSL::PKey::RSA.new(...).to_pem(..., '...') + - pattern: OpenSSL::PKey::RSA.new(...).export(..., '...') + - patterns: + - pattern-inside: | + $OPENSSL = OpenSSL::PKey::RSA.new(...) + ... + - pattern-either: + - pattern: | + $OPENSSL.export(...,'...') + - pattern: | + $OPENSSL.to_pem(...,'...') + - patterns: + - pattern-either: + - patterns: + - pattern-inside: | + $ASSIGN = '...' + ... + - pattern: OpenSSL::PKey::RSA.new(..., $ASSIGN) + - patterns: + - pattern-inside: | + def $METHOD1(...) + ... + $ASSIGN = '...' + ... + end + ... + def $METHOD2(...) + ... + end + - pattern: OpenSSL::PKey::RSA.new(..., $ASSIGN) + - patterns: + - pattern-inside: | + $ASSIGN = '...' + ... + def $METHOD(...) + $OPENSSL = OpenSSL::PKey::RSA.new(...) + ... + end + ... + - pattern-either: + - pattern: $OPENSSL.export(...,$ASSIGN) + - pattern: $OPENSSL.to_pem(...,$ASSIGN) + - patterns: + - pattern-inside: | + def $METHOD1(...) + ... + $OPENSSL = OpenSSL::PKey::RSA.new(...) + ... + $ASSIGN = '...' + ... + end + ... + - pattern-either: + - pattern: $OPENSSL.export(...,$ASSIGN) + - pattern: $OPENSSL.to_pem(...,$ASSIGN) + - patterns: + - pattern-inside: | + def $METHOD1(...) + ... + $ASSIGN = '...' + ... + end + ... + def $METHOD2(...) + ... + $OPENSSL = OpenSSL::PKey::RSA.new(...) + ... + end + ... + - pattern-either: + - pattern: $OPENSSL.export(...,$ASSIGN) + - pattern: $OPENSSL.to_pem(...,$ASSIGN) + severity: WARNING + - id: ruby.lang.security.insufficient-rsa-key-size.insufficient-rsa-key-size languages: - ruby - message: "The RSA key size $SIZE is insufficent by NIST standards. It is \nrecommended to use a key length of 2048 or higher. The RSA algorithm, \nbeing widely used for secure data transmission, relies on key size \nfor its security. Smaller key sizes (e.g., 1024 bits and below) are \nmore susceptible to brute-force attacks, where an attacker uses \ncomputational power to decrypt data or forge signatures. \n\nTo address this security concern, ensure that all RSA keys are \ngenerated with a size of 2048 bits or more.\n\nFolowing is a secure code example:\n```\nrequire 'openssl'\n\n# Generate a new RSA key of 2048 bits\nrsa_key = OpenSSL::PKey::RSA.new(2048)\n\n# To export the RSA key\nprivate_key = rsa_key.to_pem\npublic_key = rsa_key.public_key.to_pem\n```\n" + message: The RSA key size $SIZE is insufficent by NIST standards. It is recommended to use a key length of 2048 or higher. metadata: category: security - cwe: CWE-326 + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: HIGH owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/insufficient-rsa-key-size.yaml - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf - security-severity: MEDIUM - shortDescription: Inadequate encryption strength + subcategory: + - vuln technology: - ruby patterns: @@ -92407,258 +25454,60 @@ rules: comparison: $SIZE < 2048 metavariable: $SIZE severity: WARNING - - id: ruby_crypto_rule-WeakHashesMD5 - languages: - - ruby - message: "The MD5 hashing algorithm is considered cryptographically weak and \nvulnerable to collision attacks, where two different inputs generate \nthe same output hash. When used for hashing sensitive data, attackers \ncan exploit this weakness to generate collisions, allowing them to bypass \nsecurity checks or masquerade malicious data as legitimate. This \nvulnerability is particularly critical in authentication mechanisms, \ndigital signatures, SSL/TLS certificates, and data integrity checks.\n\nRemediation:\nTo mitigate this vulnerability, replace the MD5 hashing algorithm with \nstronger cryptographic hash functions, such as SHA-256 or SHA-3. These \nalgorithms offer significantly improved security and are resistant to \ncollision attacks, making them suitable for cryptographic purposes in \nmodern applications.\n\nSecure Code example:\n```\nrequire 'openssl'\n\ndata = \"sensitive information\"\n# Using SHA-256\ndigest = OpenSSL::Digest::SHA256.new\nhash = digest.digest(data)\nhex_hash = digest.hexdigest(data)\n\n# Using SHA-3 (256 bits)\ndigest = OpenSSL::Digest::SHA3.new(256)\nhash2 = digest.digest(data)\nhex_hash2 = digest.hexdigest(data)\n```\n" - metadata: - category: security - cwe: CWE-328 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/weak-hashes-md5.yaml - - https://www.ibm.com/support/pages/security-bulletin-vulnerability-md5-signature-and-hash-algorithm-affects-sterling-integrator-and-sterling-file-gateway-cve-2015-7575 - security-severity: MEDIUM - shortDescription: Use of weak hash - technology: - - ruby - pattern-either: - - pattern: Digest::MD5.base64digest $X - - pattern: Digest::MD5.hexdigest $X - - pattern: Digest::MD5.digest $X - - pattern: Digest::MD5.new - - pattern: OpenSSL::Digest::MD5.base64digest $X - - pattern: OpenSSL::Digest::MD5.hexdigest $X - - pattern: OpenSSL::Digest::MD5.digest $X - - pattern: OpenSSL::Digest::MD5.new - severity: WARNING - - id: ruby_crypto_rule-WeakHashesSHA1 - languages: - - ruby - message: "The SHA-1 hashing algorithm is no longer considered secure for\ncryptographic applications due to its vulnerability to collision attacks,\nwhere two different inputs produce the same output hash. SHA-1's\nsusceptibility to collision attacks undermines the security of\ncryptographic operations, allowing attackers to forge signatures or\nmanipulate data without detection. This poses significant risks in\nauthentication systems, data integrity validations, and secure\ncommunications. \n\nRemediation: To mitigate this vulnerability, replace the SHA1 hashing \nalgorithm with stronger cryptographic hash functions, such as SHA-256 \nor SHA-3. These algorithms offer significantly improved security and \nare resistant to collision attacks, making them suitable for cryptographic \npurposes in modern applications.\n\nSecure Code example : \n``` \nrequire 'openssl'\n\ndata = \"sensitive information\"\n# Using SHA-256\ndigest = OpenSSL::Digest::SHA256.new\nhash = digest.digest(data)\nhex_hash = digest.hexdigest(data)\n\n# Using SHA-3 (256 bits)\ndigest = OpenSSL::Digest::SHA3.new(256)\nhash2 = digest.digest(data)\nhex_hash2 = digest.hexdigest(data)\n```\n" - metadata: - category: security - cwe: CWE-328 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/weak-hashes-sha1.yaml - - https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html - - https://shattered.io/ - security-severity: MEDIUM - shortDescription: Use of weak hash - technology: - - ruby - pattern-either: - - pattern: Digest::SHA1.$FUNC - - pattern: OpenSSL::Digest::SHA1.$FUNC - - pattern: OpenSSL::HMAC.$FUNC("sha1",...) - severity: WARNING - - id: ruby_csrf_rule-MissingCSRFProtection - languages: - - ruby - message: "Detected controller which does not enable cross-site request forgery\nprotections using `protect_from_forgery`. When a Rails application does \nnot use `protect_from_forgery` in its controllers, it is vulnerable to \nCSRF attacks. This vulnerability can allow attackers to submit unauthorized \nrequests on behalf of authenticated users, potentially leading to \nunauthorized actions being performed. \nTo mitigate this risk, Rails offers the `protect_from_forgery` method, \nwhich integrates CSRF token verification in every form submitted to \nyour application, ensuring that requests are legitimate. \nAdd `protect_from_forgery with: :exception` to your controller class. \nThe `with: :exception` option configures Rails to raise an exception \nif a CSRF token cannot be verified, providing an additional layer of security. \nThis approach ensures that unverified requests do not proceed silently, \nallowing for appropriate error handling and response measures.\n\nSecure Code Example:\n```\nclass YourController < ApplicationController\n protect_from_forgery with: :exception\n # Your controller actions here\nend\n```\nFor more information on CSRF, see OWASP guide:\nhttps://owasp.org/www-community/attacks/csrf\n" - metadata: - category: security - cwe: CWE-352 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/missing-csrf-protection.yaml - - https://owasp.org/Top10/A01_2021-Broken_Access_Control - security-severity: MEDIUM - shortDescription: Cross-site request forgery (CSRF) - technology: - - ruby - patterns: - - pattern: | - class $CONTROLLER < ActionController::Base - ... - end - - pattern-not: | - class $CONTROLLER < ActionController::Base - ... - protect_from_forgery - end - severity: WARNING - - id: ruby_deserialization_rule-BadDeserialization - languages: - - ruby - message: "In Ruby, objects can be serialized into strings using various methods \nand later reconstituted into objects. The `load` and `object_load` \nmethods, associated with modules like Marshal and CSV, is particularly \nrisky when used to deserialize data from untrusted sources. \nIf an attacker is able to manipulate the serialized data, they could \nexecute arbitrary code on the system when the data is deserialized. \nThis vulnerability can lead to remote code execution (RCE), where an \nattacker gains the ability to execute commands on the host machine. \nThe Marshal and CSV modules are often used for serialization and \ndeserialization in Ruby but they do not inherently sanitize or validate \nthe data being processed. This makes them unsafe for handling input from \nuntrusted sources.\n\nTo mitigate the risks associated with unsafe deserialization, it is \nrecommended to:\n- Avoid deserializing from untrusted sources\n- Use JSON for serialization/deserialization as JSON is considered \nsafer for data interchange between systems. However, it's crucial \nto use JSON securely by validating and sanitizing the input before \ndeserialization.\n\nSecure Code Example:\n```\nrequire 'json'\n\ndef safe_deserialize(json_data)\n # Validate and sanitize json_data before parsing\n begin\n parsed_data = JSON.parse(json_data)\n return parsed_data\n rescue JSON::ParserError => e\n puts \"Error parsing JSON data: #{e.message}\"\n return nil\n end\nend\n\n# Example usage\n# Example of input JSON string\njson_input = '{\"name\": \"John Doe\", \"age\": 30}' \nuser_data = safe_deserialize(json_input)\nputs user_data.inspect if user_data\n```\n\nAlways ensure that any data deserialized from JSON (or any format) is \nvalidated and sanitized according to the context of your application \nto prevent injection attacks or other security issues.\n" - metadata: - category: security - cwe: CWE-502 - owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - references: - - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/bad-deserialization.yaml - security-severity: HIGH - shortDescription: Deserialization of untrusted data - technology: - - ruby - mode: taint - pattern-sinks: - - pattern-either: - - pattern: | - Marshal.load(...) - - pattern: | - Marshal.restore(...) - - pattern: | - Oj.object_load(...) - - pattern: | - Oj.load($X) - pattern-sources: - - pattern-either: - - pattern: params - - pattern: cookies - severity: ERROR - - id: ruby_deserialization_rule-BadDeserializationEnv - languages: - - ruby - message: "In Ruby, objects can be serialized into strings using various methods \nand later reconstituted into objects. The `load` and `object_load` \nmethods, associated with modules like Marshal and CSV, is particularly \nrisky when used to deserialize data from untrusted sources. \nIf an attacker is able to manipulate the serialized data, they could \nexecute arbitrary code on the system when the data is deserialized. \nThis vulnerability can lead to remote code execution (RCE), where an \nattacker gains the ability to execute commands on the host machine. \nThe Marshal and CSV modules are often used for serialization and \ndeserialization in Ruby but they do not inherently sanitize or validate \nthe data being processed. This makes them unsafe for handling input from \nuntrusted sources.\n\nTo mitigate the risks associated with unsafe deserialization, it is \nrecommended to:\n- Avoid deserializing from untrusted sources\n- Use JSON for serialization/deserialization as JSON is considered \nsafer for data interchange between systems. However, it's crucial \nto use JSON securely by validating and sanitizing the input before \ndeserialization.\n\nSecure Code Example:\n```\nrequire 'json'\n\ndef safe_deserialize(json_data)\n # Validate and sanitize json_data before parsing\n begin\n parsed_data = JSON.parse(json_data)\n return parsed_data\n rescue JSON::ParserError => e\n puts \"Error parsing JSON data: #{e.message}\"\n return nil\n end\nend\n\n# Example usage\n# Example of input JSON string\njson_input = '{\"name\": \"John Doe\", \"age\": 30}' \nuser_data = safe_deserialize(json_input)\nputs user_data.inspect if user_data\n```\n\nAlways ensure that any data deserialized from JSON (or any format) is \nvalidated and sanitized according to the context of your application \nto prevent injection attacks or other security issues.\n" - metadata: - category: security - cwe: CWE-502 - owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - references: - - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/bad-deserialization-env.yaml - security-severity: HIGH - shortDescription: Deserialization of untrusted data - technology: - - ruby - mode: taint - pattern-sinks: - - pattern-either: - - pattern: | - Marshal.load(...) - - pattern: | - Marshal.restore(...) - - pattern: | - Oj.object_load(...) - - pattern: | - Oj.load($X) - pattern-sources: - - pattern-either: - - pattern: request.env - severity: ERROR - - fix: Psych.safe_load($...ARGS) - id: ruby_deserialization_rule-BadDeserializationYAML - languages: - - ruby - message: "Unsafe deserialization from YAML. \nYAML is a popular format for configuration files in Ruby applications \ndue to its readability and simplicity. However, the `load` method \nprovided by Ruby's YAML module can be dangerous when used to deserialize \ndata from untrusted sources. The method can instantiate objects based \non the YAML input, which can lead to remote code execution (RCE) if the \ninput contains malicious code. \n\nTo mitigate the risk of RCE through unsafe deserialization practices, \nconsider the following recommendations:\n- Prefer JSON for untrusted data: JSON is generally safer for \ndeserializing untrusted data because, by design, it does not support \nthe execution of arbitrary code. Ensure that any JSON deserialization \nis performed with caution, validating and sanitizing the input before \nuse.\n- Use safe YAML loading methods: If you must use YAML, prefer safe \nloading methods like `safe_load` instead of `load`. The `safe_load` method \nlimits the objects that can be deserialized, reducing the risk of \nexecuting arbitrary code.\n- Static YAML files: Loading YAML from static, trusted files (like \nconfiguration files that are not exposed to user input) is generally \nsafe. Ensure these files are securely managed and not modifiable by \nuntrusted sources.\n\nSecure Code Example:\n```\nrequire 'yaml'\nrequire 'json'\n\n# Safe YAML deserialization\ndef safe_load_yaml(file_path)\n YAML.safe_load(File.read(file_path), [Date, Time], [], true)\nend\n\n# Example of safely loading a static YAML file\nconfig_data = safe_load_yaml('config.yml')\nputs config_data.inspect\n\n# Safe JSON deserialization\ndef safe_load_json(json_input)\n # Always validate and sanitize input before deserialization\n JSON.parse(json_input)\nend\n\n# Example JSON input\njson_input = '{\"name\": \"Jack Monroe\", \"age\": 30}'\nuser_data = safe_load_json(json_input)\nputs user_data.inspect\n```\n" - metadata: - category: security - cwe: CWE-502 - owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - references: - - https://groups.google.com/g/rubyonrails-security/c/61bkgvnSGTQ/m/nehwjA8tQ8EJ - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/bad-deserialization-yaml.yaml - security-severity: HIGH - shortDescription: Deserialization of untrusted data - technology: - - ruby - - yaml - patterns: - - pattern: | - YAML.$LOAD($...ARGS) - - pattern-not: | - YAML.$LOAD(..., safe: true, ...) - - pattern-not: | - YAML.$LOAD("...", ...) - - pattern-not-inside: | - $FILE = File.read("...", ...) - ... - YAML.$LOAD(..., $FILE, ...) - - pattern-not-inside: | - $FILENAME = "..." - ... - $FILE = File.read($FILENAME, ...) - ... - YAML.$LOAD(..., $FILE, ...) - - pattern-not-inside: | - YAML.$LOAD(..., File.read("...", ...), ...) - - metavariable-regex: - metavariable: $LOAD - regex: load(?:_stream)?\b|parse_stream - severity: ERROR - - id: ruby_error_rule-DivideByZero + - id: ruby.lang.security.md5-used-as-password.md5-used-as-password languages: - ruby - message: "A ZeroDivisionError exception has been detected, this occurs when an arithmetic operation attempts to \ndivide a number by zero. This can happen in various contexts, such as \nprocessing user inputs, performing calculations with variables, or \nworking with data from external sources. Such errors not only disrupt \nthe normal flow of the application but also can be exploited in certain \nscenarios to cause harm (eg. possible dos) or extract information based \non the application's response to the error.\n\nTo prevent ZeroDivisionError exceptions and ensure application robustness:\n- Error handling: Implement error handling around division operations to \ncatch and manage ZeroDivisionError gracefully.\n- Validation: Always validate inputs that are used in division operations \nto ensure they are not zero or unexpected values.\n" + message: It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Instead, use a suitable password hashing function such as bcrypt. You can use the `bcrypt` gem. metadata: category: security - cwe: CWE-369 + confidence: MEDIUM + cwe: + - 'CWE-327: Use of a Broken or Risky Cryptographic Algorithm' + impact: MEDIUM + likelihood: HIGH owasp: - - A6:2017-Security Misconfiguration - - A04:2021-Insecure Design + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/divide-by-zero.yaml - security-severity: LOW - shortDescription: Divide a number by zero + - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html + - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords + - https://github.com/returntocorp/semgrep-rules/issues/1609 + subcategory: + - vuln technology: - - ruby + - md5 mode: taint pattern-sinks: - patterns: - - pattern-inside: $NUMBER / 0 - - pattern: $NUMBER - pattern-sources: - - patterns: - - pattern: $VAR + - pattern: $FUNCTION(...); - metavariable-regex: - metavariable: $VAR - regex: ^\d*(?!\.)$ - severity: WARNING - - id: ruby_escaping_rule-JSONEntityEscape - languages: - - ruby - message: "This rule checks if HTML escaping is globally disabled for JSON output, \nwhich can lead to Cross-Site Scripting (XSS) vulnerabilities. \nXSS attacks allow attackers to inject malicious scripts into web pages \nviewed by other users, compromising the integrity and confidentiality \nof user data. When HTML escaping is disabled, special HTML characters \nin JSON output are not converted to their entity equivalents, making \nit possible for an attacker to inject executable scripts into the web \napplication's output. \n\nTo mitigate this risk, ensure that HTML escaping is enabled when \ngenerating JSON output, particularly in web applications \nthat dynamically insert user-generated content into the DOM.\n\nSecure Code Example:\n```\n# For an initializer configuration (e.g., in config/initializers/active_support.rb)\n# Enable HTML entity escaping in JSON to prevent XSS\nActiveSupport.escape_html_entities_in_json = true\n\n# For application-wide configuration (e.g., in config/application.rb)\nmodule YourApplication\n class Application < Rails::Application\n # Enable HTML entity escaping in JSON to prevent XSS\n config.active_support.escape_html_entities_in_json = true\n end\nend\n```\n" - metadata: - category: security - cwe: CWE-79 - owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - references: - - https://owasp.org/Top10/A03_2021-Injection - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/json-entity-escape.yaml - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - technology: - - rails - pattern-either: - - pattern: | - ActiveSupport.escape_html_entities_in_json = false - - pattern: | - config.active_support.escape_html_entities_in_json = false + metavariable: $FUNCTION + regex: (?i)(.*password.*) + pattern-sources: + - pattern: Digest::MD5 severity: WARNING - - id: ruby_eval_rule-NoEval + - id: ruby.lang.security.no-eval.ruby-eval languages: - ruby - message: "The `eval` method in Ruby executes a string argument as Ruby code. When \n`eval` is used with input that can be controlled or manipulated by an \nexternal user, it can allow arbitrary code execution. This \nmeans an attacker could potentially execute malicious code on the server, \nleading to unauthorized access, data leakage, or server compromise.\n\nRemediation Steps:\n- Validate and sanitize input: If there's an absolute necessity to use \n`eval`, ensure that any user input is rigorously validated and sanitized \nto remove potentially harmful code. However, this is generally not \nrecommended due to the difficulty of securely sanitizing code.\n- Use safer alternatives: Depending on the requirement, consider using \nsafer alternatives to `eval`, such as `send` for calling methods dynamically \nor employing DSLs (Domain-Specific Languages) and safe parsing libraries \ndesigned for specific tasks.\n\nSecure Code Example:\n```\nclass Calculator\n def add(a, b)\n a + b\n end\nend\n\n# Safer alternative using send\ncalculator = Calculator.new\nmethod = params[:operation] # Example: 'add' or 'subtract'\na = params[:a].to_i\nb = params[:b].to_i\n\nif calculator.respond_to?(method)\n result = calculator.send(method, a, b)\nelse\n puts \"Invalid operation\"\nend\n```\n\nIn this example, `send` is used to dynamically call a method on the \nCalculator object based on user input. This approach is safer than \neval because it strictly limits the operations to those defined in \nthe class, preventing arbitrary code execution.\n" + message: Use of eval with user-controllable input detected. This can lead to attackers running arbitrary code. Ensure external data does not reach here, otherwise this is a security vulnerability. Consider other ways to do this without eval. metadata: category: security - cwe: CWE-95 + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection + - A03:2021 - Injection references: - https://owasp.org/Top10/A03_2021-Injection - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/no-eval.yaml - security-severity: HIGH - shortDescription: Improper neutralization of directives in dynamically evaluated code ('Eval Injection') + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_evaluation.rb + subcategory: + - vuln technology: + - ruby - rails mode: taint pattern-sinks: @@ -92686,58 +25535,146 @@ rules: RubyVM::InstructionSequence.compile(...) - pattern-not: | RubyVM::InstructionSequence.compile("...") - severity: ERROR - - id: ruby_exceptions_rule-DetailedExceptions + severity: WARNING + - fix-regex: + regex: VERIFY_NONE + replacement: VERIFY_PEER + id: ruby.lang.security.ssl-mode-no-verify.ssl-mode-no-verify + languages: + - ruby + message: Detected SSL that will accept an unverified connection. This makes the connections susceptible to man-in-the-middle attacks. Use 'OpenSSL::SSL::VERIFY_PEER' instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + subcategory: + - vuln + technology: + - ruby + pattern: OpenSSL::SSL::VERIFY_NONE + severity: WARNING + - id: ruby.lang.security.weak-hashes-md5.weak-hashes-md5 languages: - ruby - message: "The `consider_all_requests_local` setting was found set to true, which enables detailed exception reports. This setting, \nwhile useful during development for debugging purposes, can \ninadvertently expose sensitive system or application information \nto end users when enabled in production environments. Such \ninformation exposure could potentially aid attackers in crafting \nfurther attacks against the system.\n\nIt is advisable to disable detailed exception reporting in production \nenvironments to prevent the leakage of sensitive information. \n\nSecure Configuration Example:\n```\n# config/environments/production.rb\nRails.application.config.consider_all_requests_local = false\n```\n" + message: Should not use md5 to generate hashes. md5 is proven to be vulnerable through the use of brute-force attacks. Could also result in collisions, leading to potential collision attacks. Use SHA256 or other hashing functions instead. metadata: category: security - cwe: CWE-209 + confidence: MEDIUM + cwe: + - 'CWE-328: Use of Weak Hash' + impact: HIGH + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A05:2021-Security Misconfiguration + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/detailed-exceptions.yaml - security-severity: MEDIUM - shortDescription: Generation of error message containing sensitive information + - https://www.ibm.com/support/pages/security-bulletin-vulnerability-md5-signature-and-hash-algorithm-affects-sterling-integrator-and-sterling-file-gateway-cve-2015-7575 + subcategory: + - vuln + technology: + - ruby + pattern-either: + - pattern: Digest::MD5.base64digest $X + - pattern: Digest::MD5.hexdigest $X + - pattern: Digest::MD5.digest $X + - pattern: Digest::MD5.new + - pattern: OpenSSL::Digest::MD5.base64digest $X + - pattern: OpenSSL::Digest::MD5.hexdigest $X + - pattern: OpenSSL::Digest::MD5.digest $X + - pattern: OpenSSL::Digest::MD5.new + severity: WARNING + - id: ruby.lang.security.weak-hashes-sha1.weak-hashes-sha1 + languages: + - ruby + message: Should not use SHA1 to generate hashes. There is a proven SHA1 hash collision by Google, which could lead to vulnerabilities. Use SHA256, SHA3 or other hashing functions instead. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-328: Use of Weak Hash' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html + - https://shattered.io/ + subcategory: + - vuln + technology: + - ruby + pattern-either: + - pattern: Digest::SHA1.$FUNC + - pattern: OpenSSL::Digest::SHA1.$FUNC + - pattern: OpenSSL::HMAC.$FUNC("sha1",...) + severity: WARNING + - id: ruby.rails.security.audit.avoid-session-manipulation.avoid-session-manipulation + languages: + - ruby + message: This gets data from session using user inputs. A malicious user may be able to retrieve information from your session that you didn't intend them to. Do not use user input as a session key. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-276: Incorrect Default Permissions' + cwe2021-top25: true + cwe2022-top25: true + help: | + ## Remediation + Session manipulation can occur when an application allows user-input in session keys. Since sessions are typically considered a source of truth (e.g. to check the logged-in user or to match CSRF tokens), allowing an attacker to manipulate the session may lead to unintended behavior. + + ## References + [Session Manipulation](https://brakemanscanner.org/docs/warning_types/session_manipulation/) + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A01:2021 - Broken Access Control + references: + - https://brakemanscanner.org/docs/warning_types/session_manipulation/ + shortDescription: Allowing an attacker to manipulate the session may lead to unintended behavior. + subcategory: + - vuln + tags: + - security technology: - rails - patterns: - - pattern-either: - - patterns: - - pattern: | - config.consider_all_requests_local = true - - patterns: - - pattern-inside: | - class $CONTROLLER < ApplicationController - ... - end - - pattern: | - def show_detailed_exceptions? (...) - ... - return $RETURN - end - - metavariable-pattern: - metavariable: $RETURN - patterns: - - pattern-not: | - false + mode: taint + pattern-sinks: + - pattern: session[...] + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env severity: WARNING - - id: ruby_file_rule-AvoidTaintedFileAccess + - id: ruby.rails.security.audit.avoid-tainted-file-access.avoid-tainted-file-access languages: - ruby - message: "The application dynamically constructs file or path information with user input. When an application uses data from \nuntrusted sources (like `params`, `cookies`, or `request.env`) to perform \nactions on the file system, it opens up potential vulnerabilities. \nA malicious actor could exploit this to access, modify, or delete \nfiles they shouldn't have access to, leading to information disclosure, \ndata loss, or server compromise. This type of vulnerability is often \nreferred to as a File Inclusion vulnerability or Path Traversal attack, \ndepending on the nature of the exploit.\n\nTo mitigate these risks, follow these best practices:\n- Validate and sanitize input: Ensure all user inputs are strictly \nvalidated and sanitized to prevent path traversal characters (like `../`) \nor other malicious patterns. Only allow filenames or paths that match \nspecific, safe patterns.\n- Use secure libraries: Utilize libraries or frameworks that abstract \nfile access in a secure manner, automatically handling the risks \nassociated with raw user input.\n- Least privilege principle: Run your application with the minimum \nnecessary file system permissions. Restrict the application's access \nto only those directories and files it absolutely needs.\n- Directory whitelisting: Maintain an allow list of permitted directories \nfor file operations, rejecting any requests for paths outside of these \ndirectories.\n\nSecure Code Example:\n```\ndef safe_file_read(filename)\n # Define a list of allowed files or use regex to validate the filename format\n allowed_files = ['allowed_file.txt', 'another_safe_file.txt']\n \n if allowed_files.include?(filename)\n file_path = Rails.root.join('safe_directory', filename)\n content = File.read(file_path)\n return content\n else\n raise \"Access to the requested file is not allowed.\"\n end\nend\n```\n" + message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. metadata: category: security - cwe: CWE-22 + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-file-access.yaml - security-severity: MEDIUM - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown + subcategory: + - vuln technology: - rails mode: taint @@ -92785,174 +25722,27 @@ rules: - pattern: cookies - pattern: request.env severity: WARNING - - id: ruby_file_rule-CheckRenderLocalFileInclude - languages: - - ruby - message: "The application dynamically constructs file or path information with user input when calling the `render` function. This can allow end\nusers to request arbitrary local files which may result in leaking\nsensitive information persisted on disk. Where possible, avoid letting\nusers specify template paths for `render`. If you must allow user input,\nuse an allow-list of known templates or normalize the user-supplied value\nwith `File.basename(...)`.\n\nTo mitigate this vulnerability, follow these steps:\n- Avoid direct user input: If possible, do not use user input \nto determine file paths. Use a mapping of user input to server-side \ndefined file paths instead.\n- Use `File.basename`: If user input must be used to specify a file, \nensure that the input is normalized using `File.basename` to extract \nthe filename without any directory path. This prevents directory \ntraversal attacks.\n- Path allow listing: Implement an allow list of permitted files or \ndirectories and check user input against this list before processing.\n\nSecure Code Example:\n```\nclass PagesController < ApplicationController\n # Allowlist\n def show\n valid_pages = ['home', 'about_us', 'contact']\n if valid_pages.include?(params[:page])\n render params[:page]\n else\n render 'not_found'\n end\n end\n\n # Sanitizing User Input\n def show\n # Sanitize the user input to extract just the file name\n page = File.basename(params[:page])\n # Optionally, further validate the sanitized input against an allow-list or other criteria\n render page\n end\nend\n```\n" - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - references: - - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-render-local-file-include.yaml - security-severity: MEDIUM - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - technology: - - rails - mode: taint - pattern-sanitizers: - - patterns: - - pattern: $MAP[...] - - metavariable-pattern: - metavariable: $MAP - patterns: - - pattern-not-regex: params - - pattern: File.basename(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern: | - render ..., file: $X - - pattern: | - render ..., inline: $X - - pattern: | - render ..., template: $X - - pattern: | - render ..., action: $X - - pattern: | - render $X, ... - - focus-metavariable: $X - pattern-sources: - - patterns: - - pattern: params[...] - severity: WARNING - - id: ruby_file_rule-CheckSendFile - languages: - - ruby - message: "The application dynamically constructs file or path information with user input when calling\nthe `send_file` method in Ruby. This practice can lead to a serious \nsecurity vulnerability known as Local File Inclusion (LFI), allowing \nattackers to read arbitrary files on the server. \nLFI vulnerabilities can lead to the exposure of sensitive information, \nsuch as configuration files, source code, or even data files, \nwhich could be exploited to gain further access or to mount more \nsevere attacks.\n\nTo mitigate this vulnerability, follow these steps:\n- Avoid direct user input: If possible, do not use user input \nto determine file paths. Use a mapping of user input to server-side \ndefined file paths instead.\n- Use `File.basename`: If user input must be used to specify a file, \nensure that the input is normalized using `File.basename` to extract \nthe filename without any directory path. This prevents directory \ntraversal attacks.\n- Path allow listing: Implement an allow list of permitted files or \ndirectories and check user input against this list before processing.\n\nSecure Code Example:\n```\ndef download\n filename = params[:filename]\n filepath = \"path/to/secure/directory/#{File.basename(filename)}\"\n\n # Optionally, further validate the resolved filepath against a whitelist\n\n if File.exist?(filepath) && !File.directory?(filepath)\n send_file filepath, x_sendfile: true\n else\n render plain: \"File not found\", status: :not_found\n end\nend\n```\n" - metadata: - category: security - cwe: CWE-73 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - references: - - https://owasp.org/www-community/attacks/Path_Traversal - - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-send-file.yaml - security-severity: MEDIUM - shortDescription: External control of file name or path - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern: | - send_file ... - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - severity: WARNING - - id: ruby_filter_rule-CheckBeforeFilter - languages: - - ruby - message: "The application was found disabling controller checks by setting `skip_filter` \nor `skip_before_filter` with an `:except` option. This approach can \ninadvertently open up parts of your application to unauthorized access \nbecause it relies on a blocklist approach, where only specified actions \nare protected. \n\nA safer method of providing this functionality involves specifying \nexactly which controller actions should have checks applied using an \n`:only` option, effectively creating an allowlist. This method ensures \nthat only specified actions are affected, and any new actions added to \nthe controller will have the filters applied by default, adhering to the \nprinciple of secure by default.\n\nSecure Code Example:\n```\nclass UsersController < ApplicationController\n # Apply the filter only to these actions, making it clear and secure by default\n skip_before_action :authenticate_user!, only: [:new, :create]\nend\n```\n\nIn the secure example, `:authenticate_user!` filter is explicitly skipped \nonly for the `:new` and `:create actions`. This means any new action added \nto the UsersController in the future will have the `authenticate_user!` \nfilter applied by default, ensuring that new parts of the application \nare secure from the start. \n" - metadata: - category: security - cwe: CWE-749 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - references: - - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-before-filter.yaml - security-severity: LOW - shortDescription: Exposed dangerous method or function - technology: - - ruby - - rails - mode: search - patterns: - - pattern-either: - - pattern: | - skip_filter ..., :except => $ARGS - - pattern: | - skip_before_filter ..., :except => $ARGS - severity: WARNING - - id: ruby_find_rule-CheckUnscopedFind - languages: - - ruby - message: "The application was found calling the `find(...)` method with user-controlled input. If the \nActiveRecord model being searched against is sensitive, this may lead to \nInsecure Direct Object Reference (IDOR) behavior and allow users to read \narbitrary records. This could lead to data breaches, including the \nexposure of personal information, account takeovers, and other security \nissues.\n\nTo mitigate this risk, it's essential to scope queries to the current \nuser or another appropriate scope that ensures users can only access \ndata they are authorized to see. This is done by using ActiveRecord \nassociations and scopes to limit the records that can be retrieved. \n\nSecure Code Example:\n```\n# Secure way to scope the find to the current user's accounts\ndef show\n @account = current_user.accounts.find(params[:id])\nend\n```\n" - metadata: - category: security - cwe: CWE-639 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/unscoped_find/ - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-unscoped-find.yaml - security-severity: MEDIUM - shortDescription: Authorization bypass through user-controlled key - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: $MODEL.find(...) - - pattern: $MODEL.find_by_id(...) - - pattern: $MODEL.find_by_id!(...) - - metavariable-regex: - metavariable: $MODEL - regex: '[A-Z]\S+' - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - severity: WARNING - - id: ruby_ftp_rule-AvoidTaintedFTPCall + - id: ruby.rails.security.audit.avoid-tainted-ftp-call.avoid-tainted-ftp-call languages: - ruby - message: "The application was found calling the Net::FTP modules methods with\nuser supplied input. A malicious actor could use this to modify or access files\nthey should not have access to.\n\nDirectly incorporating user-controlled input from `params`, `cookies`, \nor `request.env` into FTP commands or connection setups can lead to \nvarious security vulnerabilities, including Remote Code Execution \n(RCE), unauthorized file access, and data exfiltration. It's crucial \nto validate, sanitize, and, where possible, avoid using user-controlled \ndata in sensitive operations like FTP transactions. Ensure that any input \nused in FTP operations is strictly controlled and validated against \nexpected patterns.\n\nRemediation Strategy:\nTo mitigate these risks, ensure that all user-provided input is strictly \nvalidated and sanitized before being used in FTP operations. \n- Verify the format and content of the input to ensure it meets expected \ncriteria.\n- Use allowlists to restrict the input to known safe values.\n- Employ built-in security features of the programming language or \nframework to escape or safely handle user input.\n\nSecure Code Example:\n```\nfilename = params[:filename]\n# Validate the filename to ensure it's a known, safe file\nraise \"Invalid filename\" unless filename =~ /\\A[\\w]+\\.\\w+\\z/\n\nNet::FTP.open('example.com', 'user', 'password') do |ftp|\n # Proceed with the FTP operation using the validated and sanitized filename\n ftp.getbinaryfile(filename, \"local_#{filename}\", 1024)\nend\n```\n" + message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. metadata: category: security - cwe: CWE-76 + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-ftp-call.yaml - security-severity: MEDIUM - shortDescription: Improper neutralization of equivalent special elements + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown + subcategory: + - vuln technology: - - ruby - rails mode: taint pattern-sinks: @@ -92969,20 +25759,25 @@ rules: - pattern: cookies - pattern: request.env severity: WARNING - - id: ruby_http_rule-AvoidTaintedHTTPRequest + - id: ruby.rails.security.audit.avoid-tainted-http-request.avoid-tainted-http-request languages: - ruby - message: "The application was found including unvalidated user input into `Net::HTTP` methods, \nwhich could lead to HTTP Parameter Pollution (HPP) or worse, Server Side Request Forgery (SSRF).\nSpecifically, it looks for methods like GET, POST, DELETE, etc., \nbeing called with parameters that could be controlled by an end-user. \nUsing untrusted input in such a manner without proper validation and \nsanitization can lead to a variety of security vulnerabilities, including \nSSRF, injection attacks, unintended data leaks, and unauthorized actions \nbeing performed on behalf of the attacker.\n\nEnsure all user-controlled input is validated against a strict set of rules \n(e.g., expected data types, patterns, and lengths) and sanitized to remove \nor encode potentially harmful characters before being used in HTTP requests. \nAdditionally, consider using higher-level abstractions or frameworks that \nautomatically handle some of these concerns.\n\nSecure Code Example:\n```\nrequire 'uri'\n\n# Validate and sanitize the user input before using it in the HTTP request\nbegin\n user_input = params[:url]\n uri = URI.parse(user_input)\n\n # Ensure the URI is HTTP/HTTPS and refers to a trusted domain\n if uri.scheme.match?(/\\Ahttps?\\z/) && uri.host == 'www.abc.com'\n response = Net::HTTP.get(uri)\n else\n raise \"Invalid URL\"\n end\nrescue URI::InvalidURIError\n puts \"Provided URL is not valid\"\nend\n```\n" + message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. metadata: category: security - cwe: CWE-918 + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A10:2021-Server-Side Request Forgery + - A10:2021 - Server-Side Request Forgery (SSRF) references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-http-request.yaml - security-severity: MEDIUM - shortDescription: Server side request forgery (SSRF) + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown + subcategory: + - vuln technology: - rails mode: taint @@ -93039,269 +25834,434 @@ rules: - pattern: cookies - pattern: request.env severity: WARNING - - id: ruby_http_rule-CheckHTTPVerbConfusion + - id: ruby.rails.security.audit.avoid-tainted-shell-call.avoid-tainted-shell-call + languages: + - ruby + message: Using user input when accessing files is potentially dangerous. A malicious actor could use this to modify or access files they have no right to. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/docs/warning_types/file_access/index.markdown + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: Kernel.$X(...) + - patterns: + - pattern-either: + - pattern: Shell.$X(...) + - patterns: + - pattern-inside: | + $SHELL = Shell.$ANY(...) + ... + $SHELL.$X(...) + - pattern: $SHELL.$X(...) + - metavariable-pattern: + metavariable: $X + patterns: + - pattern-either: + - pattern: cat + - pattern: chdir + - pattern: chroot + - pattern: delete + - pattern: entries + - pattern: exec + - pattern: foreach + - pattern: glob + - pattern: install + - pattern: lchmod + - pattern: lchown + - pattern: link + - pattern: load + - pattern: load_file + - pattern: makedirs + - pattern: move + - pattern: new + - pattern: open + - pattern: read + - pattern: readlines + - pattern: rename + - pattern: rmdir + - pattern: safe_unlink + - pattern: symlink + - pattern: syscopy + - pattern: sysopen + - pattern: system + - pattern: truncate + - pattern: unlink + pattern-sources: + - pattern-either: + - pattern: params[...] + - pattern: cookies + - pattern: request.env + severity: ERROR + - id: ruby.rails.security.audit.sqli.ruby-pg-sqli.ruby-pg-sqli + languages: + - ruby + message: 'Detected string concatenation with a non-literal variable in a pg Ruby SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized queries like so: `conn.exec_params(''SELECT $1 AS a, $2 AS b, $3 AS c'', [1, 2, nil])` And you can use prepared statements with `exec_prepared`.' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://www.rubydoc.info/gems/pg/PG/Connection + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-propagators: + - from: $Y + pattern: $X << $Y + to: $X + pattern-sinks: + - patterns: + - pattern-either: + - pattern-inside: | + $CON = PG.connect(...) + ... + - pattern-inside: | + $CON = PG::Connection.open(...) + ... + - pattern-inside: | + $CON = PG::Connection.new(...) + ... + - pattern-either: + - pattern: | + $CON.$METHOD($X,...) + - pattern: | + $CON.$METHOD $X, ... + - focus-metavariable: $X + - metavariable-regex: + metavariable: $METHOD + regex: ^(exec|exec_params)$ + pattern-sources: + - pattern-either: + - pattern: | + params + - pattern: | + cookies + severity: WARNING + - id: ruby.rails.security.audit.xss.avoid-link-to.avoid-link-to + languages: + - ruby + message: This code includes user input in `link_to`. In Rails 2.x, the body of `link_to` is not escaped. This means that user input which reaches the body will be executed when the HTML is rendered. Even in other versions, values starting with `javascript:` or `data:` are not escaped. It is better to create and use a safer function which checks the body argument. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH + owasp: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://brakemanscanner.org/docs/warning_types/link_to/ + - https://brakemanscanner.org/docs/warning_types/link_to_href/ + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_link_to.rb + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sanitizers: + - patterns: + - pattern: | + "...#{...}..." + - pattern-not: | + "#{...}..." + pattern-sinks: + - pattern: link_to(...) + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + - pattern-either: + - pattern: $MODEL.url(...) + - pattern: $MODEL.uri(...) + - pattern: $MODEL.link(...) + - pattern: $MODEL.page(...) + - pattern: $MODEL.site(...) + severity: WARNING + - id: ruby.rails.security.audit.xss.avoid-redirect.avoid-redirect languages: - ruby - message: "Found an improperly constructed control flow block with `request.get?`. \nRails will route HEAD requests as GET requests but they will fail the \n`request.get?` check, potentially causing unexpected behavior unless an \n`elsif` condition is used.\n\nSecure Code Example:\n```\nif request.get?\n # Handle GET request logic here\nelsif request.head?\n # Handle HEAD request logic here\nelse\n # Handle others if needed\nend\n```\n" + message: When a redirect uses user input, a malicious user can spoof a website under a trusted URL or access restricted parts of a site. When using user-supplied values, sanitize the value before using it for the redirect. metadata: category: security - cwe: CWE-754 + confidence: MEDIUM + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A04:2021-Insecure Design + - A01:2021 - Broken Access Control references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-http-verb-confusion.yaml - security-severity: MEDIUM - shortDescription: Improper check for unusual or exceptional conditions + - https://brakemanscanner.org/docs/warning_types/redirect/ + subcategory: + - vuln technology: - - ruby - rails - mode: search - patterns: - - pattern: | - if request.get? - ... - else - ... - end - - pattern-not-inside: | - if ... - elsif ... - ... - end + mode: taint + pattern-sanitizers: + - pattern: params.merge(:only_path => true) + - pattern: params.merge(:host => ...) + pattern-sinks: + - pattern: redirect_to(...) + pattern-sources: + - pattern: params + - pattern: cookies + - pattern: request.env + - patterns: + - pattern: $MODEL.$X(...) + - pattern-not: $MODEL.$X("...") + - metavariable-pattern: + metavariable: $X + pattern-either: + - pattern: all + - pattern: create + - pattern: create! + - pattern: find + - pattern: find_by_sql + - pattern: first + - pattern: last + - pattern: new + - pattern: from + - pattern: group + - pattern: having + - pattern: joins + - pattern: lock + - pattern: order + - pattern: reorder + - pattern: select + - pattern: where + - pattern: find_by + - pattern: find_by! + - pattern: take severity: WARNING - - id: ruby_injection_rule-AvoidTaintedShellCall + - id: ruby.rails.security.audit.xss.avoid-render-dynamic-path.avoid-render-dynamic-path languages: - ruby - message: "User input should never be used in constructing commands or command arguments\nto functions which execute OS related functionality. Using external \ninput without validation in functions like `Kernel.system`, `exec`, or any \noperations that interact with the shell or file system (`cat`, `delete` \netc.) poses a severe security risk. These patterns can lead to command \ninjection vulnerabilities, where an attacker could execute arbitrary \ncommands on the system the application is hosted on, leading to data \nbreaches, unauthorized access, or worse.\n\nTo prevent command injection vulnerabilities, validate and sanitize all \nuser input before using it in any system or shell operation. Additionally, \nconsider using safer alternatives for executing system commands that don't \ndirectly pass user input to the shell, such as parameterized APIs or \nfunctions that handle arguments safely.\n\nSecure Code Example:\n```\nuser_filename_key = params[:filename_key]\n\nallowed_filenames = {\n 'file1' => 'allowed_file_1.txt',\n 'file2' => 'allowed_file_2.txt',\n}\n\n# Validate and select the filename from the lookup table\nif allowed_filenames.has_key?(user_filename_key)\n safe_filename = allowed_filenames[user_filename_key]\n\n # Use a safer API to read file content without invoking the shell\n content = File.read(safe_filename)\nelse\n puts \"Invalid filename.\"\nend\n```\n" + message: Avoid rendering user input. It may be possible for a malicious user to input a path that lets them access a template they shouldn't. To prevent this, check dynamic template paths against a predefined allowlist to make sure it's an allowed template. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-tainted-shell-call.yaml - security-severity: HIGH - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + - https://brakemanscanner.org/docs/warning_types/dynamic_render_paths/ + subcategory: + - vuln technology: - rails - - ruby mode: taint pattern-sinks: - patterns: - - pattern-either: - - patterns: - - pattern: Kernel.$X(...) - - patterns: - - pattern-either: - - pattern: Shell.$X(...) - - patterns: - - pattern-inside: | - $SHELL = Shell.$ANY(...) - ... - $SHELL.$X(...) - - pattern: $SHELL.$X(...) + - pattern-inside: render($X => $INPUT, ...) + - pattern: $INPUT - metavariable-pattern: metavariable: $X - patterns: - - pattern-either: - - pattern: cat - - pattern: chdir - - pattern: chroot - - pattern: delete - - pattern: entries - - pattern: exec - - pattern: foreach - - pattern: glob - - pattern: install - - pattern: lchmod - - pattern: lchown - - pattern: link - - pattern: load - - pattern: load_file - - pattern: makedirs - - pattern: move - - pattern: new - - pattern: open - - pattern: read - - pattern: readlines - - pattern: rename - - pattern: rmdir - - pattern: safe_unlink - - pattern: symlink - - pattern: syscopy - - pattern: sysopen - - pattern: system - - pattern: truncate - - pattern: unlink + pattern-either: + - pattern: action + - pattern: template + - pattern: partial + - pattern: file pattern-sources: - - pattern-either: - - pattern: params[...] - - pattern: cookies - - pattern: request.env - severity: ERROR - - id: ruby_injection_rule-BadSend + - pattern: params + - pattern: cookies + - pattern: request.env + severity: WARNING + - id: ruby.rails.security.brakeman.check-before-filter.check-before-filter languages: - ruby - message: "The application was found calling dynamic method invocations in Ruby. \nIn particular one of the methods of: `Object#send`, `Object#try`, `Object#__send__`, \nor `Object#public_send`. These methods are powerful Ruby features that allow \ncalling another method on an object \nby name, where the method's name is passed as a string or symbol. \nHowever, when combined with untrusted input, such as parameters from \nweb requests, they can lead to severe security vulnerabilities, including \narbitrary method execution and potentially arbitrary code execution.\n\nTo mitigate these risks, it's crucial to validate and sanitize any user \ninput that might determine which methods are invoked. Moreover, consider \nusing safer alternatives to direct method invocation based on user input, \nsuch as explicitly whitelisting allowed methods or using conditional logic \nto determine method calls.\n\nSecure Code Example:\n```\n# Secure method invocation with validation and allow lists\nmethod_name = params[:method].to_sym\nallowed_methods = [:allowed_method_1, :allowed_method_2, :safe_method]\n\nif allowed_methods.include?(method_name)\n result = object.public_send(method_name)\nelse\n raise \"Unauthorized method call\"\nend\n```\n" + message: 'Disabled-by-default Rails controller checks make it much easier to introduce access control mistakes. Prefer an allowlist approach with `:only => [...]` rather than `except: => [...]`' metadata: category: security - cwe: CWE-94 + confidence: MEDIUM + cwe: + - 'CWE-284: Improper Access Control' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/no-send.yaml - - https://the.igreque.info/posts/2016/01-object-send-considered-harmful-en.html - security-severity: HIGH - shortDescription: Improper control of generation of code ('Code Injection') + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_skip_before_filter.rb + subcategory: + - vuln technology: - ruby - pattern-either: - - pattern: | - $PARAM = params[...] - ... - $RES = $MOD.send($PARAM.$FUNC) - - pattern: | - $PARAM = params[...] - ... - $RES = $MOD.try($PARAM.$FUNC) - - pattern: | - $PARAM = params[...] - ... - $RES = $MOD.__send__($PARAM.$FUNC) - - pattern: | - $PARAM = params[...] - ... - $RES = $MOD.public_send($PARAM.$FUNC) + - rails + mode: search + patterns: + - pattern-either: + - pattern: | + skip_filter ..., :except => $ARGS + - pattern: | + skip_before_filter ..., :except => $ARGS + - pattern: | + skip_before_action ..., :except => $ARGS severity: ERROR - - id: ruby_injection_rule-DangerousExec + - id: ruby.rails.security.brakeman.check-dynamic-render-local-file-include.check-dynamic-render-local-file-include languages: - - ruby - message: "OS command injection is a critical vulnerability that can lead to a full system\ncompromise as it may allow an adversary to pass in arbitrary commands or arguments\nto be executed.\n\nUser input should never be used in constructing commands or command arguments\nto functions which execute OS commands. This includes filenames supplied by\nuser uploads or downloads.\n\nTo mitigate this vulnerability, follow these best practices:\n- Validate input: Ensure that all user inputs are validated against a \nstrict pattern that only allows safe characters for the context. Reject \nany input that does not meet these criteria.\n- Sanitize input: When validation is not feasible, sanitize the input \nby escaping or removing potentially dangerous characters.\n- Use secure methods: Prefer using secure methods or libraries designed \nto execute system commands with parameters, which automatically handle \nproper escaping of user inputs, such as `Open3.capture3` in Ruby.\n- Least privilege: Run your application with the least privileges \nnecessary, limiting what an attacker can do if they manage to execute a \ncommand.\n\nSecure Code Example:\nInstead of directly interpolating user input into system commands, validate \nuser input against an allowlist, then use parameterized execution or safer \nAPIs like Open3:\n```\nrequire 'open3'\n\nuser_input = params[:user_input]\n# Define an allow list of permitted arguments\nallowed_arguments = ['allowed_argument1', 'allowed_argument2', 'allowed_argument3']\n\n# Validate user_input against the list\nif allowed_arguments.include?(user_input)\n # Using Open3 to safely execute system commands with allowed arguments\n stdout, stderr, status = Open3.capture3('grep', user_input, 'my_file.txt')\n if status.success?\n puts stdout\n else\n warn \"Error: #{stderr}\"\n end\nelse\n warn \"Error: Unpermitted argument.\"\nend\n```\n" + - generic + message: Found request parameters in a call to `render` in a dynamic context. This can allow end users to request arbitrary local files which may result in leaking sensitive information persisted on disk. metadata: category: security - cwe: CWE-94 + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://guides.rubyonrails.org/security.html#command-line-injection - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/dangerous-exec.yaml - security-severity: HIGH - shortDescription: Improper control of generation of code ('Code Injection') + - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion + - https://github.com/presidentbeef/brakeman/blob/f74cb53ead47f0af821d98b5b41e16d63100c240/test/apps/rails2/app/views/home/test_render.html.erb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render.rb + subcategory: + - vuln technology: - ruby - rails - mode: taint - pattern-sinks: - - patterns: - - pattern: | - $EXEC(...) - - pattern-not: | - $EXEC("...","...","...",...) - - pattern-not: | - $EXEC(["...","...","...",...],...) - - pattern-not: | - $EXEC({...},"...","...","...",...) - - pattern-not: | - $EXEC({...},["...","...","...",...],...) - - metavariable-regex: - metavariable: $EXEC - regex: ^(system|exec|spawn|Process.exec|Process.spawn|Open3.capture2|Open3.capture2e|Open3.capture3|Open3.popen2|Open3.popen2e|Open3.popen3|IO.popen|Gem::Util.popen|PTY.spawn)$ - pattern-sources: - - patterns: - - pattern: | - def $F(...,$ARG,...) - ... - end - - focus-metavariable: $ARG - - pattern: params - - pattern: cookies - severity: ERROR - - id: ruby_mass_assignment_rule-ModelAttrAccessible + mode: search + paths: + include: + - '*.erb' + patterns: + - pattern: | + params[...] + - pattern-inside: | + render :file => ... + severity: WARNING + - id: ruby.rails.security.brakeman.check-http-verb-confusion.check-http-verb-confusion languages: - ruby - message: "The application was found permitting attributes which could lead to mass assignment\nvulnerabilities. Permitting attributes such as `admin`, `role`, `banned` etc, \nwithout proper authorization checks can lead to security issues like unauthorized \naccess or privilege escalation.\n\nRemediation Strategy\n- Explicitly permit attributes: Carefully review which attributes are \npermissible and avoid including sensitive ones in the list.\n- Role-based permissions: Implement checks that allow only authorized \nusers (e.g., administrators) to modify sensitive attributes.\n- Avoid using `params.permit!`: Use specific permit statements instead of \npermitting all parameters to ensure only expected attributes are allowed \nfor mass assignment.\n\nSecure Code Example:\n```\n# Secure: Conditionally permit sensitive attributes based on user role\ndef user_params\npermitted = params.require(:user).permit(:name, :email)\npermitted[:role] = params[:user][:role] if current_user.admin? && params[:user][:role].present?\npermitted\nend\n\ndef user_params2\n permitted_attributes = [:username, :email]\n # Only allow 'admin' attribute to be updated by users with admin role\n permitted_attributes << :admin if current_user.admin?\n params.require(:user).permit(*permitted_attributes)\nend\n```\n" + message: Found an improperly constructed control flow block with `request.get?`. Rails will route HEAD requests as GET requests but they will fail the `request.get?` check, potentially causing unexpected behavior unless an `elif` condition is used. metadata: category: security - cwe: CWE-915 + confidence: MEDIUM + cwe: + - 'CWE-650: Trusting HTTP Permission Methods on the Server Side' + impact: MEDIUM + likelihood: HIGH owasp: - - A6:2017-Security Misconfiguration - - A08:2021-Software and Data Integrity Failures + - A04:2021 - Insecure Design references: - - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/model-attr-accessible.yaml - security-severity: MEDIUM - shortDescription: Improperly controlled modification of dynamically-determined object attributes + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails6/app/controllers/accounts_controller.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_verb_confusion.rb + subcategory: + - vuln technology: - ruby - rails - pattern-either: - - pattern: | - ....permit(..., :admin, ...) - - pattern: | - ....permit(..., :role, ...) - - pattern: | - ....permit(..., :banned, ...) - - pattern: | - ....permit(..., :account_id, ...) - - pattern: | - attr_accessible ..., :admin, ... - - pattern: | - attr_accessible ..., :role, ... - - pattern: | - attr_accessible ..., :banned, ... - - pattern: | - attr_accessible ..., :account_id, ... + mode: search + patterns: - pattern: | - params.permit! - severity: WARNING - - id: ruby_mass_assignment_rule-UnprotectedMassAssign + if request.get? + ... + else + ... + end + - pattern-not-inside: | + if ... + elsif ... + ... + end + severity: ERROR + - id: ruby.rails.security.brakeman.check-rails-session-secret-handling.check-rails-session-secret-handling languages: - ruby - message: "Checks for calls to `without_protection` during mass assignment (which \nallows record creation from hash values). This can lead to users bypassing \npermissions protections. Using `:without_protection => true` makes your \napplication vulnerable to attackers who may craft malicious requests to \nmodify sensitive attributes, leading to unauthorized access or data \nmanipulation. For Rails 4 and higher, mass protection is on by default.\n\nTo mitigate this issue, don't use :without_protection => true. Instead, \nconfigure attr_accessible to control attribute access.\n\nSecure Code Example:\n```\nclass User < ActiveRecord::Base\n # Only name and email can be updated via mass assignment\n attr_accessible :name, :email\n\n # admin and account_id are not listed here, so they cannot be mass-assigned\nend\n```\n" + message: Found a string literal assignment to a Rails session secret `$KEY`. Do not commit secret values to source control! Any user in possession of this value may falsify arbitrary session data in your application. Read this value from an environment variable, KMS, or file on disk outside of source control. metadata: category: security - cwe: CWE-915 + confidence: MEDIUM + cwe: + - 'CWE-540: Inclusion of Sensitive Information in Source Code' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A08:2021-Software and Data Integrity Failures + - A01:2021 - Broken Access Control references: - - https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/unprotected-mass-assign.yaml - security-severity: MEDIUM - shortDescription: Improperly controlled modification of dynamically-determined object attributes + - https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails4_with_engines/config/initializers/secret_token.rb + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3/config/initializers/secret_token.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_session_settings.rb + subcategory: + - vuln technology: - ruby - rails patterns: - pattern-either: + - patterns: + - pattern: | + :$KEY => "$LITERAL" + - pattern-inside: | + ActionController::Base.session = {...} - pattern: | - $MOD.new(params[$CODE]) + $RAILS::Application.config.$KEY = "$LITERAL" - pattern: | - $MOD.new(..., params[$CODE], :without_protection => true, ...) - - pattern-not-inside: | - attr_accessible $VAR - ... - $MOD.new(params[$CODE]) + Rails.application.config.$KEY = "$LITERAL" + - metavariable-regex: + metavariable: $KEY + regex: ^secret(_(token|key_base))?$ severity: WARNING - - id: ruby_redirect_rule-CheckRedirectTo + - id: ruby.rails.security.brakeman.check-redirect-to.check-redirect-to languages: - ruby - message: "The application was found handling redirect behavior with user-supplied input. \nDo not pass `params` to `redirect_to` without the `:only_path => true` \nhash value. Using `:only_path => true` ensures that the URL is interpreted \nas a relative path, not allowing redirection to an arbitrary external URL, \nthus mitigating the risk of open redirects. Alternatively, validate or \nsanitize the input to ensure it's safe and intended.\n\nSecure Code Example:\n```\n# Secure - Ensuring redirection is only to internal paths\ndef secure_redirect\n redirect_to params[:redirect_url], only_path: true\nend\n```\n" + message: Found potentially unsafe handling of redirect behavior $X. Do not pass `params` to `redirect_to` without the `:only_path => true` hash value. metadata: category: security - cwe: CWE-601 + confidence: MEDIUM + cwe: + - 'CWE-601: URL Redirection to Untrusted Site (''Open Redirect'')' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection + - A01:2021 - Broken Access Control references: - https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-redirect-to.yaml - security-severity: LOW - shortDescription: URL redirection to untrusted site 'open redirect' + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_redirect.rb + subcategory: + - vuln technology: - ruby - rails @@ -93360,9454 +26320,7791 @@ rules: - pattern: cookies - pattern: request.env - pattern: url_for(params[...],...,:only_path => false,...) - severity: INFO - - id: ruby_reflection_rule-CheckUnsafeReflection - languages: - - ruby - message: "The application was found calling a reflection method with user-controllable\ninput. Reflection in Ruby allows a program to examine and modify its own \nstructure and behavior at runtime. When user input is used unsafely \nwith reflection methods (like `constantize`, `safe_constantize`, `const_get`, \n`qualified_const_get`), it poses a significant security risk, potentially \nleading to arbitrary code execution.\n\nTo mitigate these risks:\n- Avoid direct user input in reflection: Never use user-controllable input \ndirectly with reflection methods.\n- Validate and sanitize input: If user input must influence program behavior, \nrigorously validate and sanitize the input against a whitelist of allowed \nvalues.\n- Use indirect references: Instead of allowing direct specification of class \nor method names, map user inputs to a predefined set of allowed actions or \nclasses.\n- Do not provide user-controllable input to reflection functionality. \n- Do not call symbol conversion on user-controllable input.\n\nSecure Code Example:\n```\nclass SafeClassHandler\n ALLOWED_CLASSES = {\n 'user' => User,\n 'product' => Product\n }.freeze\n\n def self.handle_class_action(class_key)\n klass = ALLOWED_CLASSES[class_key]\n raise ArgumentError, \"Invalid class key\" unless klass\n\n klass.some_method\n end\nend\n\n# Example usage\nSafeClassHandler.handle_class_action(params[:class_key])\n```\n" - metadata: - category: security - cwe: CWE-94 - owasp: - - A1:2017-Injection - - A03:2021-Injection - references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-unsafe-reflection.yaml - security-severity: HIGH - shortDescription: Improper control of generation of code ('Code Injection') - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern: $X - - pattern-either: - - pattern-inside: | - $X.constantize - - pattern-inside: | - $X. ... .safe_constantize - - pattern-inside: | - const_get(...) - - pattern-inside: | - qualified_const_get(...) - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - severity: ERROR - - id: ruby_reflection_rule-CheckUnsafeReflectionMethods - languages: - - ruby - message: "The application was found calling a reflection method with user-controllable\ninput. This practice can lead to unauthorized alteration of program behavior, \nincluding the potential execution of arbitrary code. Reflection methods \nallow dynamic execution of code, which is powerful but risky if not properly \nsanitized, as it could enable attackers to execute unintended methods or \nblocks.\n\nRemediation:\n- Validate and sanitize input: Ensure that any user input is strictly \nvalidated against a whitelist of allowed values before being passed to \nreflection methods. Avoid direct mapping of user input to method names \nor proc conversions.\n- Limit reflection use: Minimize the use of reflection with user input. \nPrefer direct method calls or other non-reflective approaches whenever \npossible.\n- Use safer alternatives: When dynamic behavior is necessary, use controlled \nmethods like `public_send` with proper input validation to reduce risk.\n\nSecure Code Example:\n```\n# Assume user input is to invoke a method on an object\nuser_method = params[:method_name]\n\n# Define an allow list of permissible methods\nallowed_methods = ['safe_method_1', 'safe_method_2']\n\nif allowed_methods.include?(user_method)\n # Using public_send for controlled method invocation\n result = my_object.public_send(user_method)\nelse\n raise 'Unauthorized method access'\nend\n```\n" - metadata: - category: security - cwe: CWE-94 - owasp: - - A1:2017-Injection - - A03:2021-Injection - references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-unsafe-reflection-methods.yaml - security-severity: HIGH - shortDescription: Improper control of generation of code ('Code Injection') - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern: $X - - pattern-either: - - pattern-inside: | - $X. ... .to_proc - - patterns: - - pattern-inside: | - $Y.method($Z) - - focus-metavariable: $Z - - patterns: - - pattern-inside: | - $Y.tap($Z) - - focus-metavariable: $Z - - patterns: - - pattern-inside: | - $Y.tap{ |$ANY| $Z } - - focus-metavariable: $Z - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - severity: ERROR - - id: ruby_regex_rule-CheckRegexDOS - languages: - - ruby - message: "The application was found constructing a regular expression with user-controllable\ninput. This may result in excessive resource consumption \nwhen applied to certain inputs, or when the user is allowed to control \nthe match target.\n\nTo mitigate the issue, avoid allowing users to specify regular expressions \nprocessed by the server. If you must support user-controllable input in a \nregular expression, use an allow-list to restrict the expressions users \nmay supply to limit catastrophic backtracking.\n\nSecure Code Example:\n```\n# Define an allow-list of safe, predefined patterns\nALLOWED_PATTERNS = {\n 'digits_only' => /^\\d+$/,\n 'letters_only' => /^[a-zA-Z]+$/,\n 'email_format' => /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/\n}\nuser_pattern_key = params[:pattern_key]\ntarget_data = params[:data]\n\nif ALLOWED_PATTERNS.key?(user_pattern_key)\n # Fetch the safe pattern from the allow-list\n safe_pattern = ALLOWED_PATTERNS[user_pattern_key]\n \n # Apply the regular expression safely\n if target_data.match(safe_pattern)\n # Do something\n else\n # Do something\n end\nelse\n # Handle case where the pattern is not allowed\nend\n```\n" - metadata: - category: security - cwe: CWE-1333 - owasp: - - A6:2017-Security Misconfiguration - - A04:2021-Insecure Design - references: - - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-regex-dos.yaml - security-severity: MEDIUM - shortDescription: Inefficient regular expression complexity - technology: - - ruby - - rails - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: $Y - - pattern-inside: | - /...#{...}.../ - - patterns: - - pattern: $Y - - pattern-inside: | - Regexp.new(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] - - patterns: - - pattern: $Y - - pattern-either: - - pattern-inside: | - $RECORD.read_attribute($Y) - - pattern-inside: | - $RECORD[$Y] - - metavariable-regex: - metavariable: $RECORD - regex: '[A-Z][a-z]+' - severity: WARNING - - id: ruby_regex_rule-CheckValidationRegex - languages: - - ruby - message: "An incorrectly-bounded regex was passed to `validates_format_of` \nor `validate ... format => ...`.\n\nRuby regex behavior is multiline by default and lines should be terminated \nby `\\A` for beginning of line and `\\Z` for end of line, respectively.\n\nSecure Code Example:\n```\nclass User < ApplicationRecord\n # Securely anchored from start to end of the string\n validates :username, format: { with: /\\A(?=.*[a-zA-Z])[a-zA-Z0-9]+\\z/ }\nend\n```\n" - metadata: - category: security - cwe: CWE-185 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/format_validation/ - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-validation-regex.yaml - security-severity: MEDIUM - shortDescription: Incorrect regular expression - technology: - - ruby - - rails - mode: search - patterns: - - pattern-either: - - pattern: | - validates ..., :format => <... $V ...>,... - - pattern: | - validates_format_of ..., :with => <... $V ...>,... - - metavariable-regex: - metavariable: $V - regex: /(.{2}(? 'posts#index', as: :posts - get 'posts/:id' => 'posts#show', as: :post - post 'posts' => 'posts#create' - - # Other CRUD actions for posts can be defined similarly - end - ``` - metadata: - category: security - cwe: CWE-276 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-default-routes.yaml - security-severity: MEDIUM - shortDescription: Incorrect Default Permissions - technology: - - rails - paths: - include: - - '*routes.rb' - patterns: - - pattern-either: - - pattern: map.connect ":controller/:action/:id" - - pattern: match ':controller(/:action(/:id(.:format)))' severity: WARNING - - id: ruby_session_rule-AvoidSessionManipulation - languages: - - ruby - message: "The application was found retrieving session data using user input. A \nmalicious user may be able to retrieve information from the session \nthat was not meant to be allowed. \nSession manipulation can occur when an application allows user-input in \nsession keys. Since sessions are typically considered a source of truth \n(e.g. to check the logged-in user or to match CSRF tokens), allowing an \nattacker to manipulate the session may lead to unintended behavior. \n\nTo mitigate this issue, never use user input as a session key. Instead, \nconsider an allow list approach to control access to session keys, \nensuring only predefined keys are accessible, and user input is not used\nto directly access the session key values. \n\nSecure Code Example:\n```\n# Define an allowed list of permitted session keys\nALLOWED_SESSION_KEYS = ['display_settings', 'locale']\n\nuser_provided_key = params[:key]\n\n# Validate the key against the list\nif ALLOWED_SESSION_KEYS.include?(user_provided_key)\n # Access the session value safely\n value = session[user_provided_key]\nelse\n raise \"Invalid session key provided.\"\nend\n```\n" - metadata: - category: security - cwe: CWE-276 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - references: - - https://brakemanscanner.org/docs/warning_types/session_manipulation/ - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/avoid-session-manipulation.yaml - security-severity: CRITICAL - shortDescription: Incorrect default permissions - technology: - - rails - mode: taint - pattern-sinks: - - pattern: session[...] - pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - severity: ERROR - - id: ruby_sql_rule-CheckSQL + - id: ruby.rails.security.brakeman.check-regex-dos.check-regex-dos languages: - ruby - message: "SQL Injection is a critical vulnerability that can lead to data or system compromise. By\ndynamically generating SQL query strings, user input may be able to influence the logic of\nthe SQL statement. This could lead to an adversary accessing information they should\nnot have access to, or in some circumstances, being able to execute OS functionality or code.\n\nTo mitigate this issue, always use parameterized queries or the \nActiveRecord query interface, which ensures that inputs are properly \nescaped, preventing SQL injection attacks. Avoid string interpolation \nor concatenation with user-controlled input for constructing SQL queries.\n\nSecure Code Example:\n```\n# Secure: Using parameterized queries with ActiveRecord\nuser_id = params[:id]\nUser.where(\"id = ?\", user_id)\n\n# Secure: Using ActiveRecord's query methods, which automatically handle parameterization\n# Converting to integer as an additional layer of input sanitization\nuser_id = params[:id].to_i \nUser.where(id: user_id)\n```\n" + message: Found a potentially user-controllable argument in the construction of a regular expressions. This may result in excessive resource consumption when applied to certain inputs, or when the user is allowed to control the match target. Avoid allowing users to specify regular expressions processed by the server. If you must support user-controllable input in a regular expression, use an allow-list to restrict the expressions users may supply to limit catastrophic backtracking. metadata: category: security - cwe: CWE-89 + confidence: MEDIUM + cwe: + - 'CWE-1333: Inefficient Regular Expression Complexity' + impact: MEDIUM + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection + - A03:2017 - Sensitive Data Exposure references: - - https://owasp.org/www-community/attacks/SQL_Injection - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-sql.yaml - security-severity: HIGH - shortDescription: Improper neutralization of special elements used in a SQL command ('SQL Injection') + - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_regex_dos.rb + subcategory: + - vuln technology: - ruby - rails mode: taint - pattern-sanitizers: + pattern-sinks: - patterns: - pattern-either: - patterns: - - pattern: $X - - pattern-either: - - pattern-inside: | - :$KEY => $X - - pattern-inside: | - ["...",$X,...] - - pattern: | - params[...].to_i - - pattern: | - params[...].to_f + - pattern: $Y + - pattern-inside: | + /...#{...}.../ - patterns: - - pattern: | - params[...] ? $A : $B - - metavariable-pattern: - metavariable: $A - patterns: - - pattern-not: | - params[...] - - metavariable-pattern: - metavariable: $B - patterns: - - pattern-not: | - params[...] - pattern-sinks: + - pattern: $Y + - pattern-inside: | + Regexp.new(...) + pattern-sources: - patterns: - - pattern: $X - - pattern-not-inside: | - $P.where("...",...) - - pattern-not-inside: | - $P.where(:$KEY => $VAL,...) - pattern-either: - - pattern-inside: | - $P.$M(...) - - pattern-inside: | - $P.$M("...",...) - - pattern-inside: | - class $P < ActiveRecord::Base - ... - end - - metavariable-regex: - metavariable: $M - regex: (where|find|first|last|select|minimum|maximum|calculate|sum|average) - pattern-sources: - - pattern-either: - - pattern: | - cookies[...] - - patterns: - pattern: | - cookies. ... .$PROPERTY[...] - - metavariable-regex: - metavariable: $PROPERTY - regex: (?!signed|encrypted) - - pattern: | - params[...] - - pattern: | - request.env[...] + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + - patterns: + - pattern: $Y + - pattern-either: + - pattern-inside: | + $RECORD.read_attribute($Y) + - pattern-inside: | + $RECORD[$Y] + - metavariable-regex: + metavariable: $RECORD + regex: '[A-Z][a-z]+' severity: ERROR - - fix-regex: - regex: =\s*false - replacement: = true - id: ruby_ssl_rule-ForceSSLFalse - languages: - - ruby - message: "The application was found setting `force_ssl` to `false`. This setting\ncan expose the application to the risk of network\ninterception of unencrypted traffic. Enabling `force_ssl` by setting \n`config.force_ssl = true` in the application's configuration, specifically \nwithin `config/environments/production.rb`, forces the use of HTTPS, \nencrypting data in transit and safeguarding against eavesdropping or data \ntampering. \n" - metadata: - category: security - cwe: CWE-319 - owasp: - - A3:2017-Sensitive Data Exposure - - A04:2021-Insecure Design - references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/force-ssl-false.yaml - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information - technology: - - ruby - pattern: config.force_ssl = false - severity: WARNING - - fix-regex: - regex: VERIFY_NONE - replacement: VERIFY_PEER - id: ruby_ssl_rule-SSLModeNoVerify + - id: ruby.rails.security.brakeman.check-render-local-file-include.check-render-local-file-include languages: - ruby - message: "The application was found using `OpenSSL::SSL::VERIFY_NONE`.\nThis effectively disables the validation of TLS certificates.\n\nThis allows for an adversary who is in between the application and the \ntarget host to intercept potentially sensitive information or transmit \nmalicious data.\n\nTo remediate this issue, use 'OpenSSL::SSL::VERIFY_PEER' instead.\n" + message: Found request parameters in a call to `render`. This can allow end users to request arbitrary local files which may result in leaking sensitive information persisted on disk. Where possible, avoid letting users specify template paths for `render`. If you must allow user input, use an allow-list of known templates or normalize the user-supplied value with `File.basename(...)`. metadata: category: security - cwe: CWE-295 + confidence: MEDIUM + cwe: + - 'CWE-22: Improper Limitation of a Pathname to a Restricted Directory (''Path Traversal'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A07:2021-Identification and Authentication Failures + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control references: - - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/lang/security/ssl-mode-no-verify.yaml - security-severity: MEDIUM - shortDescription: Improper certificate validation + - https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion + - https://github.com/presidentbeef/brakeman/blob/f74cb53/test/apps/rails2/app/controllers/home_controller.rb#L48-L60 + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_render.rb + subcategory: + - vuln technology: - ruby - pattern: OpenSSL::SSL::VERIFY_NONE - severity: WARNING - - id: ruby_xss_rule-AvoidLinkTo - languages: - - ruby - message: "This code includes user input in `link_to`. In Rails, the body of \n`link_to` is not escaped. This means that user input which reaches the \nbody will be executed when the HTML is rendered. Even in other versions, \nvalues starting with `javascript:` or `data:` are not escaped. \n\nMitigation Strategy:\nAlways sanitize user input used within `link_to` method calls. For versions of \nRails where `link_to` does not automatically escape the body, or when dealing \nwith schemes that are not escaped (`javascript:`, `data:`), manually escape or \nvalidate the input against a list of safe values. Consider using the `sanitize` \nhelper method or other Rails sanitization helpers to clean user input before \nrendering.\n\nSecure Code Example:\n```\nuser_input = params[:user_link_text]\n\n# This example uses the `sanitize` helper to ensure any HTML tags or JavaScript in the user input are escaped\nsafe_link_text = sanitize(user_input)\n\n# Use the sanitized text as the body of the `link_to` method\n<%= link_to safe_link_text, some_safe_path %>\n```\n" - metadata: - category: security - cwe: CWE-79 - owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - references: - - https://brakemanscanner.org/docs/warning_types/link_to/ - - https://brakemanscanner.org/docs/warning_types/link_to_href/ - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-link-to.yaml - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - technology: - rails + vulnerability_class: + - Path Traversal mode: taint pattern-sanitizers: - patterns: - - pattern: | - "...#{...}..." - - pattern-not: | - "#{...}..." + - pattern: $MAP[...] + - metavariable-pattern: + metavariable: $MAP + patterns: + - pattern-not-regex: params + - pattern: File.basename(...) pattern-sinks: - - pattern: link_to(...) + - patterns: + - pattern-either: + - pattern: | + render ..., file: $X + - pattern: | + render ..., inline: $X + - pattern: | + render ..., template: $X + - pattern: | + render ..., action: $X + - pattern: | + render $X, ... + - focus-metavariable: $X pattern-sources: - - pattern: params - - pattern: cookies - - pattern: request.env - - pattern-either: - - pattern: $MODEL.url(...) - - pattern: $MODEL.uri(...) - - pattern: $MODEL.link(...) - - pattern: $MODEL.page(...) - - pattern: $MODEL.site(...) + - patterns: + - pattern: params[...] severity: WARNING - - id: ruby_xss_rule-AvoidRenderInline + - id: ruby.rails.security.brakeman.check-reverse-tabnabbing.check-reverse-tabnabbing languages: - - ruby - message: "The application was found calling `render inline: ...` which renders an entire ERB template inline and is potentially dangerous.\nIf user supplied input is used, the application can be exploited by malicious \nactors via server-side template injection (SSTI) or cross-site scripting (XSS) attacks.\nInstead, consider using a partial or another safe rendering method.\n\nSecure Code Example:\n```\n# In your controller or view\nuser_input = params[:user_input]\nrender partial: 'users/user_input', locals: { user_input: user_input }\n\n# erb file\n\n\n
    \n <%= sanitize(user_input) %>\n
    \n```\n" + - generic + message: Setting an anchor target of `_blank` without the `noopener` or `noreferrer` attribute allows reverse tabnabbing on Internet Explorer, Opera, and Android Webview. metadata: category: security - cwe: CWE-79 - owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection + confidence: MEDIUM + cwe: + - 'CWE-1022: Use of Web Link to Untrusted Target with window.opener Access' + impact: MEDIUM + likelihood: MEDIUM references: - - https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#inline-renders---even-worse-than-xss - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-render-inline.yaml - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#browser_compatibility + - https://github.com/presidentbeef/brakeman/blob/3f5d5d5/test/apps/rails5/app/views/users/show.html.erb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_reverse_tabnabbing.rb + subcategory: + - vuln technology: + - ruby - rails - pattern: 'render inline: ...' + mode: search + paths: + include: + - '*.erb' + patterns: + - pattern: | + _blank + - pattern-inside: | + target: ... + - pattern-not-inside: | + <%= ... rel: 'noopener noreferrer' ...%> + - pattern-either: + - patterns: + - pattern-inside: | + <%= $...INLINERUBYDO do -%> + ... + <% end %> + - metavariable-pattern: + language: ruby + metavariable: $...INLINERUBYDO + patterns: + - pattern: | + link_to ... + - pattern-not: | + link_to "...", "...", ... + - patterns: + - pattern-not-inside: | + <%= ... do - %> + - pattern-inside: | + <%= $...INLINERUBY %> + - metavariable-pattern: + language: ruby + metavariable: $...INLINERUBY + patterns: + - pattern: | + link_to ... + - pattern-not: | + link_to '...', '...', ... + - pattern-not: | + link_to '...', target: ... severity: WARNING - - fix-regex: - regex: 'text:' - replacement: 'plain:' - id: ruby_xss_rule-AvoidRenderText + - id: ruby.rails.security.brakeman.check-secrets.check-secrets languages: - ruby - message: "The application was found calling `render text: ...` which actually sets the \ncontent-type to 'text/html'. If external data can reach here, this exposes your \napplication to cross-site scripting (XSS) attacks. Instead, use `render plain: ...` to\nrender non-HTML text.\n" + message: Found a Brakeman-style secret - a variable with the name password/secret/api_key/rest_auth_site_key and a non-empty string literal value. metadata: category: security - cwe: CWE-79 + confidence: MEDIUM + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection + - A01:2021 - Broken Access Control references: - - https://brakemanpro.com/2017/09/08/cross-site-scripting-in-rails#inline-renders---even-worse-than-xss - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/avoid-render-text.yaml - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + - https://github.com/presidentbeef/brakeman/blob/3f5d5d5f00864cdf7769c50f5bd26f1769a4ba75/test/apps/rails3.1/app/controllers/users_controller.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_secrets.rb + subcategory: + - vuln technology: + - ruby - rails - pattern: 'render text: ...' + patterns: + - pattern: $VAR = "$VALUE" + - metavariable-regex: + metavariable: $VAR + regex: (?i)password|secret|(rest_auth_site|api)_key$ + - metavariable-regex: + metavariable: $VALUE + regex: .+ severity: WARNING - - id: ruby_xss_rule-ManualTemplateCreation + - id: ruby.rails.security.brakeman.check-send-file.check-send-file languages: - ruby - message: "The application was identified manually creating ERB templates. Manual creation of templates\nmay expose your application to server-side template injection (SSTI) or\ncross-site scripting (XSS) attacks if user input is used to create the\ntemplate. Instead, create a '.erb' template file and use 'render'.\n\nSecure Code Example:\n```\n# Controller: messages_controller.rb\nclass MessagesController < ApplicationController\n def show\n # Safely assign user input to an instance variable\n @message_content = sanitize(params[:user_content])\n \n # Render the static .erb template\n render 'messages/show'\n end\nend\n\n\n
    \n Message: <%= @message_content %>\n
    \n```\n" - metadata: - category: security - cwe: CWE-79 - owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - references: - - https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/audit/xss/manual-template-creation.yaml - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - technology: - - rails - pattern: ERB.new(...) - severity: WARNING - - id: yaml_spring_rule-SpringActuatorFullyEnabled - languages: - - yaml - message: "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints\nsuch as /actuator/env, /actuator/logfile, /actuator/heapdump and others.\nIf the application lacks proper security measures (e.g., authentication and \nauthorization), sensitive data could be accessed, compromising the application and \nits infrastructure. This configuration poses a serious risk in production \nenvironments or public-facing deployments.\n\nTo mitigate the risks, take the following measures:\n - Expose only the Actuator endpoints required for your use case\n - For production environments, restrict exposure to non-sensitive endpoints \n like `health` or `info`\n - Ensure Actuator endpoints are protected with authentication and authorization \n (e.g., via Spring Security)\n - Use environment-specific configurations to limit exposure in production\n\nSecure Code Example:\nInstead of include: \"*\", list only the endpoints you need to expose:\n```\nmanagement:\n endpoints:\n web:\n exposure:\n include: \"health,info,metrics\"\n```\n\nReferences:\n- https://docs.spring.io/spring-boot/reference/actuator/endpoints.html#actuator.endpoints.exposing\n- https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785\n- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators\n" + message: Allowing user input to `send_file` allows a malicious user to potentially read arbitrary files from the server. Avoid accepting user input in `send_file` or normalize with `File.basename(...)` metadata: category: security confidence: MEDIUM - cwe: CWE-497 - impact: HIGH + cwe: + - 'CWE-73: External Control of File Name or Path' + impact: MEDIUM likelihood: MEDIUM owasp: - - A01:2021-Broken Access Control - - A3:2017-Sensitive Data Exposure - security-severity: Medium - shortDescription: Exposure of sensitive system information to an unauthorized control sphere + - A04:2021 - Insecure Design + references: + - https://owasp.org/www-community/attacks/Path_Traversal + - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_send_file.rb + subcategory: + - vuln technology: - - java - patterns: - - pattern: | - management: - ... - endpoints: - ... - web: - ... - exposure: - ... - include: "*" - ... - severity: WARNING - - id: rules_lgpl_java_webview_rule-ignore-ssl-certificate-errors - languages: - - java - message: "Insecure WebView Implementation. leading to a security problem known as SSL certificate \nvalidation bypass. This occurs when the app fails to properly validate SSL certificates, \nallowing potentially malicious or spoofed certificates to be accepted, leading to a \nMan-in-the-Middle (MitM) attack where an attacker intercepts and manipulates communication \nbetween the app and the server. \n\nTo fix this security issue, you should properly handle SSL errors and only proceed with \nthe connection if the SSL certificate is valid and trusted. Here's an example code in Java:\n``` \npublic class MyWebViewClient extends WebViewClient { \n @Override\n public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {\n // Check the SSL error type\n switch (error.getPrimaryError()) {\n case SslError.SSL_UNTRUSTED:\n // Certificate is untrusted\n // Handle the error appropriately, such as showing an error message\n break;\n case SslError.SSL_EXPIRED:\n // Certificate has expired\n // Handle the error appropriately\n break;\n case SslError.SSL_IDMISMATCH:\n // Certificate hostname mismatch\n // Handle the error appropriately\n break;\n case SslError.SSL_NOTYETVALID:\n // Certificate is not yet valid\n // Handle the error appropriately\n break;\n }\n // Cancel the connection\n // This prevents the WebView from loading the content\n handler.cancel();\n }\n}\n```\n" - metadata: - category: security - cwe: CWE-295 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Improper certificate validation" - pattern: | - $RET onReceivedSslError(WebView $W, SslErrorHandler $H, SslError $E) { - ... - $H.proceed(); - } - severity: WARNING - - id: rules_lgpl_java_webview_rule-webview-debugging - languages: - - java - message: "Remote WebView debugging is enabled. This allows an attacker with\ndebugging access to interact with the webview and steal or corrupt data.\nTo fix these security issues, it is recommended to disable remote \ndebugging and restrict file access in the WebView. \nHere's how you can do it:\n```\nWebView webView = new WebView(context);\n\n// Disable remote debugging\nif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {\n WebView.setWebContentsDebuggingEnabled(false);\n}\n\n// Restrict file access from file URLs\nwebView.getSettings().setAllowFileAccessFromFileURLs(false);\n\n// Load a web page\nwebView.loadUrl(\"https://example.com\");\n```\n" - metadata: - category: security - cwe: CWE-489 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Active debug code - patterns: - - pattern-either: - - pattern: | - $WB.setWebContentsDebuggingEnabled(true); + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: - pattern: | - $X = true; - ... - $WB.setWebContentsDebuggingEnabled($X); - severity: WARNING - - id: rules_lgpl_java_webview_rule-webview-external-storage - languages: - - java - message: "WebView load files from external storage. Files in external storage can be\nmodified by any application.\n\nLoading files from external storage in a WebView can introduce security risks, \nas it allows web content to access potentially sensitive data stored on the \ndevice's external storage. This can lead to unauthorized access to user data, \nincluding personal files, credentials, or other sensitive information, by \nmalicious web content.\n\nTo fix this security issue, you should avoid loading files directly from external \nstorage in a WebView. Instead, you should use a Content Provider or a secure file \nstorage mechanism to access files and provide them to the WebView as content.\n\nHere's a general approach to fix this problem:\n(1) Use a Content Provider: If you need to load files from external storage in a WebView, \nconsider using a Content Provider to securely access the files. Content Providers \nprovide controlled access to files stored on external storage and allow you to define \npermissions for accessing them.\n(2) Secure File Storage: Store files containing sensitive data in a secure location, such \nas internal storage or encrypted storage, and provide access to them through a secure \nAPI. Avoid exposing sensitive files directly to the WebView.\n(3) Restrict WebView Access: Configure the WebView to restrict access to external resources \nand content. Use methods like setAllowFileAccess() to control file access and \nsetAllowContentAccess() to control access to content from other origins.\nHere's an example of how you can use a Content Provider to provide secure access to \nfiles in a WebView:\n```\n// Define the URI of the content provider for accessing files\nUri contentProviderUri = Uri.parse(\"content://com.example.myapp.provider/files\");\n// Load the content from the Content Provider into the WebView\nwebView.loadUrl(contentProviderUri.toString());\n```\nIn the above code, we define the URI of a Content Provider that provides access to files \nstored in the app's external storage. The content is loaded from the Content Provider into \nthe WebView using loadUrl(), which ensures that access to files is controlled and secure, \npreventing unauthorized access to sensitive data.\n" - metadata: - category: security - cwe: CWE-749 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Exposed dangerous method or function - patterns: + send_file ... + pattern-sources: - pattern-either: - pattern: | - $X = <... $E.getExternalStorageDirectory() ...>; - ... - $WV.loadUrl(<... $X ...>); - - pattern: | - $WV.loadUrl(<... $E.getExternalStorageDirectory().$F() ...>); + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) - pattern: | - $X = <... Environment.getExternalStorageDirectory().$F() ...>; - ... - $WV.loadUrl(<... $X ...>); + params[...] - pattern: | - $X = <... $E.getExternalFilesDir(...) ...>; - ... - $WV.loadUrl(<... $X ...>); + request.env[...] severity: ERROR - - id: rules_lgpl_java_webview_rule-webview-set-allow-file-access - languages: - - java - message: "WebView File System Access is enabled. An attacker able to inject \nscript into a WebView, could exploit the opportunity to unauthorized \naccess to sensitive user data or system files.\n\nTo fix this security issue, you should disable file access in the \nWebView or restrict it to specific directories. \nAn example:\n```\n// Create a WebView instance\nWebView webView = new WebView(context);\n// Disable file access in the WebView\nwebView.getSettings().setAllowFileAccess(false);\n```\n" - metadata: - category: security - cwe: CWE-73 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: External control of file name or path - pattern: $WB.setAllowFileAccess(true); - severity: WARNING - - id: rules_lgpl_javascript_crypto_rule-node-aes-ecb - languages: - - javascript - message: | - AES with ECB mode is deterministic in nature and not suitable for encrypting large amount of repetitive data. - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: | - $X.createCipheriv("=~/^aes-([0-9]+)-ecb$/i", ...) - - pattern: | - $X.createDecipheriv("=~/^aes-([0-9]+)-ecb$/i", ...) - severity: WARNING - - id: rules_lgpl_javascript_crypto_rule-node-aes-noiv - languages: - - javascript - message: | - AES algorithms requires an initialization vector (IV). Providing no or null IV in some implementation results to a 0 IV. Use of a deterministic IV makes dictionary attacks easier. - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Use of a broken or risky cryptographic algorithm - patterns: - - pattern-either: - - pattern: | - $X.createCipheriv("=~/^aes-/i", $KEY, "", ...) - severity: WARNING - - id: rules_lgpl_javascript_crypto_rule-node-insecure-random-generator - languages: - - javascript - message: "This rule identifies use of cryptographically weak random number generators.\nUsing cryptographically weak random number generators like `crypto.pseudoRandomBytes()` \nand `Math.random()` for security-critical tasks can expose systems to significant \nvulnerabilities. Attackers might predict the generated random numbers, compromising \nthe integrity and confidentiality of cryptographic operations. This could lead to \nbreaches where sensitive data is accessed or manipulated, authentication mechanisms \nare bypassed, or secure communications are intercepted, ultimately undermining the \nsecurity of the entire system or application.\n\nMitigation strategy:\nReplace the use of these cryptographically weak random number generators with \n`crypto.randomBytes()`, a method provided by Node.js's `crypto` module that \ngenerates cryptographically secure random numbers. This method should be used \nfor all operations requiring secure randomness, such as generating keys, tokens, \nor any cryptographic material.\n\nSecure Code Example:\n```\nconst crypto = require('crypto');\nconst secureBytes = crypto.randomBytes(256);\nconsole.log(`Secure random bytes: ${secureBytes.toString('hex')}`);\n```\n" - metadata: - category: security - cwe: CWE-338 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Use of cryptographically weak pseudo-random number generator (PRNG) - pattern-either: - - patterns: - - pattern-inside: | - require('crypto') - ... - - pattern: | - $X.pseudoRandomBytes(...) - - pattern: | - Math.random(...) - severity: WARNING - - id: rules_lgpl_javascript_crypto_rule-node-md5 + - id: ruby.rails.security.brakeman.check-sql.check-sql languages: - - javascript - message: "The MD5 hashing algorithm is considered cryptographically weak and \nvulnerable to collision attacks, where two different inputs generate \nthe same output hash. When used for hashing sensitive data, attackers \ncan exploit this weakness to generate collisions, allowing them to bypass \nsecurity checks or masquerade malicious data as legitimate. This \nvulnerability is particularly critical in authentication mechanisms, \ndigital signatures, SSL/TLS certificates, and data integrity checks.\n\nRemediation:\nTo mitigate this vulnerability, replace the MD5 hashing algorithm with \nstronger cryptographic hash functions, such as SHA-256 or SHA-3. These \nalgorithms offer significantly improved security and are resistant to \ncollision attacks, making them suitable for cryptographic purposes in \nmodern applications.\n\nSecure Code example :\n```\nconst crypto = require('crypto');\nconst hash = crypto.createHash('sha256').update('sensitive data').digest('hex');\nconsole.log(hash); \n```\n" + - ruby + message: Found potential SQL injection due to unsafe SQL query construction via $X. Where possible, prefer parameterized queries. metadata: category: security - cwe: CWE-328 + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Use of weak hash - pattern-either: - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $Y = $X.createHash('md5') - ... - - pattern: | - $Y.update("...") - - pattern: | - $X.createHash('md5').update("...") - - patterns: - - pattern-inside: | - require('crypto-js') - ... - - pattern: | - $X.MD5("...") - - patterns: - - pattern-either: - - pattern-inside: | - $M = require('md5') - ... - - pattern-inside: | - $M = require('blueimp-md5') - ... - - pattern-inside: | - $M = require('js-md5') - ... - - pattern: | - $M("...") + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://owasp.org/www-community/attacks/SQL_Injection + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/models/product.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_sql.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sanitizers: - patterns: - - pattern-inside: | - require('node-forge') - ... - pattern-either: - patterns: - - pattern-inside: | - $Y = $X.md.md5.create() - ... - - pattern: | - $Y.update("...") + - pattern: $X + - pattern-either: + - pattern-inside: | + :$KEY => $X + - pattern-inside: | + ["...",$X,...] - pattern: | - $X.md.md5.create().update("...") - - patterns: - - pattern-inside: | - $X = require('jshashes') - ... - $Y = new $X.MD5() - ... - - pattern: | - $Y.$METHOD("...") - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $X = require('create-hash') - ... - $Y = $X('md5') - ... - - pattern: | - $Y.update("...") - - patterns: - - pattern-inside: | - $X = require('create-hash') - ... - - pattern: "$X('md5').update(\"...\") \n" - severity: WARNING - - id: rules_lgpl_javascript_crypto_rule-node-sha1 - languages: - - javascript - message: "The SHA-1 hashing algorithm is no longer considered secure for\ncryptographic applications due to its vulnerability to collision attacks,\nwhere two different inputs produce the same output hash. SHA-1's\nsusceptibility to collision attacks undermines the security of\ncryptographic operations, allowing attackers to forge signatures or\nmanipulate data without detection. This poses significant risks in\nauthentication systems, data integrity validations, and secure\ncommunications. \n\nRemediation: To mitigate this vulnerability, replace the SHA1 hashing \nalgorithm with stronger cryptographic hash functions, such as SHA-256 \nor SHA-3. These algorithms offer significantly improved security and \nare resistant to collision attacks, making them suitable for cryptographic \npurposes in modern applications.\n\nSecure Code example: \n``` \nconst crypto = require('crypto'); \nconst hash = crypto.createHash('sha256').update('sensitive data').digest('hex'); \nconsole.log(hash); \n```\n" - metadata: - category: security - cwe: CWE-328 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Use of weak hash - pattern-either: - - patterns: - - pattern-either: + params[...].to_i + - pattern: | + params[...].to_f - patterns: - - pattern-inside: | - $Y = $X.createHash('sha1') - ... - pattern: | - $Y.update("...") - - pattern: | - $X.createHash('sha1').update("...") - - patterns: - - pattern-inside: | - require('crypto-js') - ... - - pattern: | - $X.SHA1("...") + params[...] ? $A : $B + - metavariable-pattern: + metavariable: $A + patterns: + - pattern-not: | + params[...] + - metavariable-pattern: + metavariable: $B + patterns: + - pattern-not: | + params[...] + pattern-sinks: - patterns: + - pattern: $X + - pattern-not-inside: | + $P.where("...",...) + - pattern-not-inside: | + $P.where(:$KEY => $VAL,...) - pattern-either: - pattern-inside: | - $M = require('sha1') - ... + $P.$M(...) - pattern-inside: | - $M = require('js-sha1') - ... - - pattern: | - $M("...") - - patterns: - - pattern-inside: | - require('node-forge') - ... - - pattern-either: - - patterns: - - pattern-inside: | - $Y = $X.md.sha1.create() - ... - - pattern: | - $Y.update("...") - - pattern: | - $X.md.sha1.create().update("...") - - patterns: + $P.$M("...",...) - pattern-inside: | - $X = require('jshashes') - ... - $Y = new $X.SHA1() - ... + class $P < ActiveRecord::Base + ... + end + - metavariable-regex: + metavariable: $M + regex: (where|find|first|last|select|minimum|maximum|calculate|sum|average) + pattern-sources: + - pattern-either: - pattern: | - $Y.$METHOD("...") - - patterns: - - pattern-inside: | - require('hash.js') - ... - - pattern-either: - - patterns: - - pattern-inside: | - $Y = $X.sha1() - ... - - pattern: | - $Y.update("...") + cookies[...] + - patterns: - pattern: | - $X.sha1().update("...") + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: ERROR + - id: ruby.rails.security.brakeman.check-unsafe-reflection-methods.check-unsafe-reflection-methods + languages: + - ruby + message: Found user-controllable input to a reflection method. This may allow a user to alter program behavior and potentially execute arbitrary instructions in the context of the process. Do not provide arbitrary user input to `tap`, `method`, or `to_proc` + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails6/app/controllers/groups_controller.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unsafe_reflection_methods.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sinks: - patterns: - - pattern-inside: | - $X = require('jssha') - ... + - pattern: $X - pattern-either: - - pattern: | - new $X('SHA-1', ...).update("...") + - pattern-inside: | + $X. ... .to_proc - patterns: - pattern-inside: | - $Y = new $X('SHA-1', ...) - ... - - pattern: | - $Y.update("...") - - patterns: - - pattern-either: - - pattern: | - $X('sha1').update("...") + $Y.method($Z) + - focus-metavariable: $Z - patterns: - pattern-inside: | - $Y = $X('sha1') - ... - - pattern: | - $Y.update("...") - - pattern: | - $X.subtle.digest('SHA-1', ...) - - patterns: - - pattern-either: - - pattern: | - $X.SHA1.digest(...) + $Y.tap($Z) + - focus-metavariable: $Z - patterns: - pattern-inside: | - $Y = $X.SHA1 - ... - - pattern: "$Y.digest(...) \n" - - patterns: - - pattern-either: + $Y.tap{ |$ANY| $Z } + - focus-metavariable: $Z + pattern-sources: + - pattern-either: + - pattern: | + cookies[...] + - patterns: - pattern: | - $X.codec.hex.fromBits($SJCL) - - patterns: - - pattern-inside: | - $Y = $SJCL - ... - - pattern: | - $X.codec.hex.fromBits($Y) - - metavariable-pattern: - metavariable: $SJCL - pattern: | - $K.hash.sha1.hash("...") - severity: WARNING - - id: rules_lgpl_javascript_crypto_rule-node-timing-attack + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) + - pattern: | + params[...] + - pattern: | + request.env[...] + severity: ERROR + - id: ruby.rails.security.brakeman.check-unsafe-reflection.check-unsafe-reflection languages: - - javascript - message: | - 'String comparisons using ''==='', ''!=='', ''!='' and ''=='' is vulnerable to timing attacks. More info: https://snyk.io/blog/node-js-timing-attack-ccc-ctf/' + - ruby + message: Found user-controllable input to Ruby reflection functionality. This allows a remote user to influence runtime behavior, up to and including arbitrary remote code execution. Do not provide user-controllable input to reflection functionality. Do not call symbol conversion on user-controllable input. metadata: category: security - cwe: CWE-208 + confidence: MEDIUM + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Observable timing discrepancy - patterns: - - pattern-not: if ($Z == null) { ... }; - - pattern-not: if ($Z === null) { ... }; - - pattern-not: if ($Z != null) { ... }; - - pattern-not: if ($Z !== null) { ... }; - - pattern-not: if ($Q != undefined) { ... }; - - pattern-not: if ($Q !== undefined) { ... }; - - pattern-not: if ($Q == undefined) { ... }; - - pattern-not: if ($Q === undefined) { ... }; - - pattern-not: return $Y == null; - - pattern-not: return $Y === null; - - pattern-not: return $Y != null; - - pattern-not: return $Y !== null; - - pattern-not: return $Y == undefined; - - pattern-not: return $Y === undefined; - - pattern-not: return $Y != undefined; - - pattern-not: return $Y !== undefined; + - A03:2021 - Injection + references: + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails2/app/controllers/application_controller.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unsafe_reflection.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern: $X + - pattern-either: + - pattern-inside: | + $X.constantize + - pattern-inside: | + $X. ... .safe_constantize + - pattern-inside: | + const_get(...) + - pattern-inside: | + qualified_const_get(...) + pattern-sources: - pattern-either: - pattern: | - if (password == $X) { - ... - } - - pattern: | - if ($X == password) { - ... - } - - pattern: | - if (password === $X) { - ... - } - - pattern: | - if ($X === password) { - ... - } - - pattern: | - if (pass == $X) { - ... - } - - pattern: | - if ($X == pass) { - ... - } - - pattern: | - if (pass === $X) { - ... - } - - pattern: | - if ($X === pass) { - ... - } - - pattern: | - if (secret == $X) { - ... - } - - pattern: | - if ($X == secret) { - ... - } - - pattern: | - if (secret === $X) { - ... - } - - pattern: | - if ($X === secret) { - ... - } - - pattern: | - if (api == $X) { - ... - } - - pattern: | - if ($X == api) { - ... - } - - pattern: | - if (api === $X) { - ... - } - - pattern: | - if ($X === api) { - ... - } - - pattern: | - if (apiKey == $X) { - ... - } - - pattern: | - if ($X == apiKey) { - ... - } - - pattern: | - if (apiKey === $X) { - ... - } - - pattern: | - if ($X === apiKey) { - ... - } - - pattern: | - if (apiSecret == $X) { - ... - } - - pattern: | - if ($X == apiSecret) { - ... - } - - pattern: | - if (apiSecret === $X) { - ... - } - - pattern: | - if ($X === apiSecret) { - ... - } - - pattern: | - if (token == $X) { - ... - } - - pattern: | - if ($X == token) { - ... - } - - pattern: | - if (token === $X) { - ... - } - - pattern: | - if ($X === token) { - ... - } - - pattern: | - if (hash == $X) { - ... - } - - pattern: | - if ($X == hash) { - ... - } - - pattern: | - if (hash === $X) { - ... - } - - pattern: | - if ($X === hash) { - ... - } - - pattern: | - if (auth_token == $X) { - ... - } - - pattern: | - if ($X == auth_token) { - ... - } - - pattern: | - if (auth_token === $X) { - ... - } - - pattern: | - if ($X === auth_token) { - ... - } - - pattern: | - if (password != $X) { - ... - } - - pattern: | - if ($X != password) { - ... - } - - pattern: | - if (password !== $X) { - ... - } - - pattern: | - if ($X !== password) { - ... - } - - pattern: | - if (pass != $X) { - ... - } - - pattern: | - if ($X != pass) { - ... - } - - pattern: | - if (pass !== $X) { - ... - } - - pattern: | - if ($X !== pass) { - ... - } - - pattern: | - if (secret != $X) { - ... - } - - pattern: | - if ($X != secret) { - ... - } - - pattern: | - if (secret !== $X) { - ... - } - - pattern: | - if ($X !== secret) { - ... - } - - pattern: | - if (api != $X) { - ... - } - - pattern: | - if ($X != api) { - ... - } - - pattern: | - if (api !== $X) { - ... - } - - pattern: | - if ($X !== api) { - ... - } - - pattern: | - if (apiKey != $X) { - ... - } - - pattern: | - if ($X != apiKey) { - ... - } - - pattern: | - if (apiKey !== $X) { - ... - } - - pattern: | - if ($X !== apiKey) { - ... - } - - pattern: | - if (apiSecret != $X) { - ... - } - - pattern: | - if ($X != apiSecret) { - ... - } - - pattern: | - if (apiSecret !== $X) { - ... - } - - pattern: | - if ($X !== apiSecret) { - ... - } - - pattern: | - if (token != $X) { - ... - } - - pattern: | - if ($X != token) { - ... - } - - pattern: | - if (token !== $X) { - ... - } - - pattern: | - if ($X !== token) { - ... - } - - pattern: | - if (hash != $X) { - ... - } - - pattern: | - if ($X != hash) { - ... - } - - pattern: | - if (hash !== $X) { - ... - } - - pattern: | - if ($X !== hash) { - ... - } - - pattern: | - if (auth_token != $X) { - ... - } - - pattern: | - if ($X != auth_token) { - ... - } - - pattern: | - if (auth_token !== $X) { - ... - } - - pattern: | - if ($X !== auth_token) { - ... - } - - pattern: | - return $X === auth_token; - - pattern: | - return auth_token === $X; - - pattern: | - return $X === token; - - pattern: | - return token === $X; - - pattern: | - return $X === hash; - - pattern: | - return hash === $X; - - pattern: | - return $X === password; - - pattern: | - return password === $X; - - pattern: | - return $X === pass; - - pattern: | - return pass === $X; - - pattern: | - return $X === apiKey; - - pattern: | - return apiKey === $X; - - pattern: | - return $X === apiSecret; - - pattern: | - return apiSecret === $X; - - pattern: | - return $X === api_key; - - pattern: | - return api_key === $X; - - pattern: | - return $X === api_secret; - - pattern: | - return api_secret === $X; - - pattern: | - return $X === secret; - - pattern: | - return secret === $X; - - pattern: | - return $X === api; - - pattern: | - return api === $X; - - pattern: | - return $X == auth_token; - - pattern: | - return auth_token == $X; - - pattern: | - return $X == token; - - pattern: | - return token == $X; - - pattern: | - return $X == hash; - - pattern: | - return hash == $X; - - pattern: | - return $X == password; - - pattern: | - return password == $X; - - pattern: | - return $X == pass; - - pattern: | - return pass == $X; - - pattern: | - return $X == apiKey; - - pattern: | - return apiKey == $X; - - pattern: | - return $X == apiSecret; - - pattern: | - return apiSecret == $X; - - pattern: | - return $X == api_key; - - pattern: | - return api_key == $X; - - pattern: | - return $X == api_secret; - - pattern: | - return api_secret == $X; - - pattern: | - return $X == secret; - - pattern: | - return secret == $X; - - pattern: | - return $X == api; - - pattern: | - return api == $X; - - pattern: | - return $X !== auth_token; - - pattern: | - return auth_token !== $X; - - pattern: | - return $X !== token; - - pattern: | - return token !== $X; - - pattern: | - return $X !== hash; - - pattern: | - return hash !== $X; - - pattern: | - return $X !== password; - - pattern: | - return password !== $X; - - pattern: | - return $X !== pass; - - pattern: | - return pass !== $X; - - pattern: | - return $X !== apiKey; - - pattern: | - return apiKey !== $X; - - pattern: | - return $X !== apiSecret; - - pattern: | - return apiSecret !== $X; - - pattern: | - return $X !== api_key; - - pattern: | - return api_key !== $X; - - pattern: | - return $X !== api_secret; - - pattern: | - return api_secret !== $X; - - pattern: | - return $X !== secret; - - pattern: | - return secret !== $X; - - pattern: | - return $X !== api; - - pattern: | - return api !== $X; - - pattern: | - return $X != auth_token; - - pattern: | - return auth_token != $X; - - pattern: | - return $X != token; - - pattern: | - return token != $X; - - pattern: | - return $X != hash; - - pattern: | - return hash != $X; - - pattern: | - return $X != password; - - pattern: | - return password != $X; - - pattern: | - return $X != pass; - - pattern: | - return pass != $X; - - pattern: | - return $X != apiKey; - - pattern: | - return apiKey != $X; - - pattern: | - return $X != apiSecret; - - pattern: | - return apiSecret != $X; - - pattern: | - return $X != api_key; - - pattern: | - return api_key != $X; - - pattern: | - return $X != api_secret; + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) - pattern: | - return api_secret != $X; + params[...] - pattern: | - return $X != secret; + request.env[...] + severity: ERROR + - id: ruby.rails.security.brakeman.check-unscoped-find.check-unscoped-find + languages: + - ruby + message: Found an unscoped `find(...)` with user-controllable input. If the ActiveRecord model being searched against is sensitive, this may lead to Insecure Direct Object Reference (IDOR) behavior and allow users to read arbitrary records. Scope the find to the current user, e.g. `current_user.accounts.find(params[:id])`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-639: Authorization Bypass Through User-Controlled Key' + impact: HIGH + likelihood: MEDIUM + owasp: + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://brakemanscanner.org/docs/warning_types/unscoped_find/ + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/controllers/users_controller.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unscoped_find.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $MODEL.find(...) + - pattern: $MODEL.find_by_id(...) + - pattern: $MODEL.find_by_id!(...) + - metavariable-regex: + metavariable: $MODEL + regex: '[A-Z]\S+' + pattern-sources: + - pattern-either: - pattern: | - return secret != $X; + cookies[...] + - patterns: + - pattern: | + cookies. ... .$PROPERTY[...] + - metavariable-regex: + metavariable: $PROPERTY + regex: (?!signed|encrypted) - pattern: | - return $X != api; + params[...] - pattern: | - return api != $X; + request.env[...] severity: WARNING - - id: rules_lgpl_javascript_crypto_rule-node-tls-reject + - id: ruby.rails.security.brakeman.check-validation-regex.check-validation-regex languages: - - javascript - message: "The application sets NODE_TLS_REJECT_UNAUTHORIZED to '0', which instructs Node.js to disable TLS/SSL certificate validation. \nThis configuration allows the application to accept self-signed certificates or certificates from untrusted authorities, \nundermining the TLS security model. Disabling TLS/SSL certificate validation compromises the integrity and confidentiality \nof data in transit between the client and server. It makes the application vulnerable to man-in-the-middle (MITM) attacks, \nwhere an attacker could intercept or alter the data being exchanged.\n\nMitigation Strategy:\nDo not disable TLS/SSL certificate validation in production environments. Ensure that NODE_TLS_REJECT_UNAUTHORIZED is \nset to '1' or is removed entirely from the production configuration (as the default configuration of validating SSL \ncertificate is safe).\n\nSecure Code Example:\n```\nconst https = require('https')\nprocess.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '1'\nconst req = https.request(options, res => {\n let data = ''\n res.on('data', chunk => {\n data += chunk\n })\n res.on('end', () => {\n console.log('Response Body:', data)\n })\n})\nreq.end()\n```\n" + - ruby + message: $V Found an incorrectly-bounded regex passed to `validates_format_of` or `validate ... format => ...`. Ruby regex behavior is multiline by default and lines should be terminated by `\A` for beginning of line and `\Z` for end of line, respectively. metadata: category: security - cwe: CWE-295 + confidence: MEDIUM + cwe: + - 'CWE-185: Incorrect Regular Expression' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Improper Certificate Validation + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://brakemanscanner.org/docs/warning_types/format_validation/ + - https://github.com/presidentbeef/brakeman/blob/aef6253a8b7bcb97116f2af1ed2a561a6ae35bd5/test/apps/rails3/app/models/account.rb + - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/models/account.rb + source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_validation_regex.rb + subcategory: + - vuln + technology: + - ruby + - rails + mode: search patterns: - pattern-either: - pattern: | - $X.env.NODE_TLS_REJECT_UNAUTHORIZED = $VAL + validates ..., :format => <... $V ...>,... - pattern: | - $X.env['NODE_TLS_REJECT_UNAUTHORIZED']= $VAL - - metavariable-pattern: - metavariable: $VAL - pattern-either: - - pattern: | - '0' - - pattern: | - 0 - severity: WARNING - - id: rules_lgpl_javascript_crypto_rule-node-weak-crypto + validates_format_of ..., :with => <... $V ...>,... + - metavariable-regex: + metavariable: $V + regex: /(.{2}(?, ...) - - pattern: | - $K.raw(<... $REQ.$QUERY ...>, ...) - - pattern: | - $SQL = <... $REQ.$QUERY.$VAR ...>; - ... - $K.raw(<... $SQL ...>, ...) - - pattern: | - $SQL = <... $REQ.$QUERY ...>; - ... - $K.raw(<... $SQL ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY.$VAR ...>; - ... - $SQL = <... $INP ...>; - ... - $K.raw(<... $SQL ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY ...>; - ... - $SQL = <... $INP ...>; - ... - $K.raw(<... $SQL ...>, ...) - - pattern: | - $K.whereRaw(<... $REQ.$QUERY.$VAR ...>, ...) - - pattern: | - $K.whereRaw(<... $REQ.$QUERY ...>, ...) - - pattern: | - $SQL = <... $REQ.$QUERY.$VAR ...>; - ... - $K.whereRaw(<... $SQL ...>, ...) - - pattern: | - $SQL = <... $REQ.$QUERY ...>; - ... - $K.whereRaw(<... $SQL ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY.$VAR ...>; - ... - $SQL = <... $INP ...>; - ... - $K.whereRaw(<... $SQL ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY ...>; - ... - $SQL = <... $INP ...>; - ... - $K.whereRaw(<... $SQL ...>, ...) + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://rorsecurity.info/portfolio/ruby-on-rails-sql-injection-cheat-sheet + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sanitizers: + - pattern: | + $PARAMS.slice(...) + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - patterns: + - pattern: | + $RECORD.where($X,...) + - pattern: | + $RECORD.find(..., :conditions => $X,...) + - focus-metavariable: $X + - patterns: + - pattern: | + "$SQLVERB#{$EXPR}..." + - pattern-not-inside: | + $FUNC("...", "...#{$EXPR}...",...) + - focus-metavariable: $SQLVERB + - pattern-regex: (?i)(select|delete|insert|create|update|alter|drop)\b + - patterns: + - pattern-either: + - pattern: Kernel::sprintf("$SQLSTR", $EXPR) + - pattern: | + "$SQLSTR" + $EXPR + - pattern: | + "$SQLSTR" % $EXPR + - pattern-not-inside: | + $FUNC("...", "...#{$EXPR}...",...) + - focus-metavariable: $EXPR + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b + pattern-sources: + - patterns: + - pattern-either: + - pattern: params + - pattern: request severity: ERROR - - id: rules_lgpl_javascript_database_rule-node-nosqli-injection + - id: ruby.rails.security.injection.tainted-url-host.tainted-url-host languages: - - javascript - message: | - Untrusted user input in findOne() function can result in NoSQL Injection. + - ruby + message: User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server running this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Use the `ssrf_filter` gem and guard the url construction with `SsrfFilter(...)`, or create an allowlist for approved hosts. metadata: category: security - cwe: CWE-943 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of special elements in data query logic - patterns: - - pattern-not-inside: | - $SANITIZE = require('mongo-sanitize') - ... - $SANITIZE(...) - ... - - pattern-not-inside: | - import $SANITIZE from 'mongo-sanitize' - ... - $SANITIZE(...) - ... - - pattern-not: | - $OBJ.findOne({$KEY : String(...).$FUNC()}, ...) - - pattern-not: | - $OBJ.findOne({$KEY : String(...).$FUNC}, ...) - - pattern-not: | - $OBJ.findOne({$KEY : String(...)}, ...) - - pattern-either: - - pattern: | - $OBJ.findOne({$KEY : <... $REQ.$FOO.$BAR ...> }, ...) - - pattern: | - $OBJ.findOne({$KEY: <... $REQ.$FOO ...> }, ...) - - pattern: | - $INP = <... $REQ.$FOO.$BAR ...>; - ... - $OBJ.findOne({$KEY : <... $INP ...> }, ...) - - pattern: | - $INP = <... $REQ.$FOO ...>; - ... - $OBJ.findOne({$KEY: <... $INP ...> }, ...) - - pattern: | - $QUERY = {$KEY: <... $REQ.$FOO.$BAR ...>}; - ... - $OBJ.findOne($QUERY, ...) - - pattern: | - $QUERY = {$KEY: <... $REQ.$FOO ...>}; - ... - $OBJ.findOne($QUERY, ...) - - pattern: | - $INP = <... $REQ.$FOO.$BAR ...>; - ... - $QUERY = {$KEY : <... $INP ...> }; - ... - $OBJ.findOne(<... $QUERY ...>, ...) - - pattern: | - $INP = <... $REQ.$FOO ...>; - ... - $QUERY = {$KEY : <... $INP ...> }; - ... - $OBJ.findOne(<... $QUERY ...>, ...) - - pattern: | - $QUERY[$KEY] = <... $REQ.$FOO.$BAR ...>; - ... - $OBJ.findOne($QUERY, ...) - - pattern: | - $QUERY[$KEY] = <... $REQ.$FOO ...>; - ... - $OBJ.findOne($QUERY, ...) - - pattern: | - $INP = <... $REQ.$FOO.$BAR ...>; - ... - $QUERY[$KEY] = <... $INP ...>; - ... - $OBJ.findOne(<... $QUERY ...>, ...) - - pattern: | - $INP = <... $REQ.$FOO ...>; - ... - $QUERY[$KEY] = <... $INP ...>; - ... - $OBJ.findOne(<... $QUERY ...>, ...) - severity: ERROR - - id: rules_lgpl_javascript_database_rule-node-nosqli-js-injection + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + - https://github.com/arkadiyt/ssrf_filter + subcategory: + - vuln + technology: + - rails + mode: taint + pattern-sanitizers: + - pattern: SsrfFilter + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: | + $URLSTR + - pattern-regex: \w+:\/\/#{.*} + - patterns: + - pattern-either: + - pattern: Kernel::sprintf("$URLSTR", ...) + - pattern: | + "$URLSTR" + $EXPR + - pattern: | + "$URLSTR" % $EXPR + - metavariable-pattern: + language: generic + metavariable: $URLSTR + pattern: $SCHEME:// ... + pattern-sources: + - patterns: + - pattern-either: + - pattern: params + - pattern: request + severity: WARNING + - id: rust.lang.security.args-os.args-os languages: - - javascript - message: | - Untrusted user input in MongoDB $where operator can result in NoSQL JavaScript Injection. + - rust + message: 'args_os should not be used for security operations. From the docs: "The first element is traditionally the path of the executable, but it can be set to arbitrary text, and might not even exist. This means this property should not be relied upon for security purposes."' metadata: category: security - cwe: CWE-943 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of special elements in data query logic - patterns: - - pattern-either: - - pattern: | - $OBJ.$FUNC({$where: <... $REQ.$FOO.$BAR ...>}, ...) - - pattern: | - $OBJ.$FUNC({$where: <... $REQ.$QUERY ...>}, ...) - - pattern: | - $NSQL = <... $REQ.$QUERY.$...>; - ... - $OBJ.$FUNC({$where: <... $NSQL ...>}, ...) - - pattern: | - $NSQL = <... $REQ.$QUERY ...>; - ... - $OBJ.$FUNC({$where: <... $NSQL ...>}, ...) - - pattern: | - $INP = $REQ.$FOO.$BAR; - ... - $QRY = {$where: <... $INP ...>}; - ... - $OBJ.$FUNC(<... $QRY ...>, ...) - - pattern: | - $INP = $REQ.$FOO; - ... - $QRY = {$where: <... $INP ...>}; - ... - $OBJ.$FUNC(<... $QRY ...>, ...) - - pattern: | - $QRY["$where"] = <... $REQ.$FOO ...>; - ... - $OBJ.$FUNC(<... $QRY ...>, ...) - - pattern: | - $QRY["$where"] = <... $REQ.$FOO.$BAR ...>; - ... - $OBJ.$FUNC(<... $QRY ...>, ...) - - pattern: | - $INP = $REQ.$FOO; - ... - $QRY["$where"] = <... $INP ...>; - ... - $OBJ.$FUNC(<... $QRY ...>, ...) - - pattern: | - $INP = $REQ.$FOO.$BAR; - ... - $QRY["$where"] = <... $INP ...>; - ... - $OBJ.$FUNC(<... $QRY ...>, ...) - severity: ERROR - - id: rules_lgpl_javascript_database_rule-node-sqli-injection + confidence: HIGH + cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' + impact: LOW + likelihood: LOW + references: + - https://doc.rust-lang.org/stable/std/env/fn.args_os.html + subcategory: audit + technology: + - rust + pattern: std::env::args_os() + severity: INFO + - id: rust.lang.security.args.args languages: - - javascript - message: | - Untrusted input concatinated with raw SQL query can result in SQL Injection. + - rust + message: 'args should not be used for security operations. From the docs: "The first element is traditionally the path of the executable, but it can be set to arbitrary text, and might not even exist. This means this property should not be relied upon for security purposes."' metadata: category: security - cwe: CWE-89 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of special elements used in an SQL command (SQL Injection) - patterns: - - pattern-inside: | - require('$LIB') - ... - - metavariable-regex: - metavariable: $LIB - regex: \b(sql-client|mysql|pg|mssql|oracledb|sequelize)\b - - pattern-not: | - $CON.query("..." + "...", ...) - - pattern-not: | - $SQL = "..."; - ... - $CON.query(<... $SQL ...>, ...) - - pattern-either: - - pattern: | - $CON.query(<... $REQ.$QUERY ...>, ...) - - pattern: | - $SQL = <... $REQ.$QUERY ...>; - ... - $CON.query(<... $SQL ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY ...>; - ... - $SQL = <... $INP ...>; - ... - $CON.query(<... $SQL ...>, ...) - - pattern: | - $CON.query(`...${...}...`, ...) - - pattern: | - $CON.query("..."+...+"...", ...) - - pattern: | - $SQL = <... $INP ...>; - ... - $CON.query(<... $SQL ...>, ...) - severity: ERROR - - id: rules_lgpl_javascript_database_rule-sequelize-tls + confidence: HIGH + cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' + impact: LOW + likelihood: LOW + references: + - https://doc.rust-lang.org/stable/std/env/fn.args.html + subcategory: audit + technology: + - rust + pattern: std::env::args() + severity: INFO + - id: rust.lang.security.current-exe.current-exe languages: - - javascript - message: | - 'The Sequelize connection string indicates that database server does not use TLS. Non TLS connections are susceptible to man in the middle (MITM) attacks.' + - rust + message: 'current_exe should not be used for security operations. From the docs: "The output of this function should not be trusted for anything that might have security implications. Basically, if users can run the executable, they can change the output arbitrarily."' metadata: category: security - cwe: CWE-319 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Cleartext transmission of sensitive information + confidence: HIGH + cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' + impact: LOW + likelihood: LOW + references: + - https://doc.rust-lang.org/stable/std/env/fn.current_exe.html#security + subcategory: audit + technology: + - rust + pattern: std::env::current_exe() + severity: INFO + - id: rust.lang.security.insecure-hashes.insecure-hashes + languages: + - rust + message: Detected cryptographically insecure hashing function + metadata: + category: security + confidence: HIGH + cwe: 'CWE-328: Use of Weak Hash' + impact: MEDIUM + likelihood: LOW + references: + - https://github.com/RustCrypto/hashes + - https://docs.rs/md2/latest/md2/ + - https://docs.rs/md4/latest/md4/ + - https://docs.rs/md5/latest/md5/ + - https://docs.rs/sha-1/latest/sha1/ + subcategory: audit + technology: + - rust + pattern-either: + - pattern: md2::Md2::new(...) + - pattern: md4::Md4::new(...) + - pattern: md5::Md5::new(...) + - pattern: sha1::Sha1::new(...) + severity: WARNING + - id: rust.lang.security.reqwest-accept-invalid.reqwest-accept-invalid + languages: + - rust + message: Dangerously accepting invalid TLS information + metadata: + category: security + confidence: HIGH + cwe: 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: LOW + references: + - https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.danger_accept_invalid_hostnames + - https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.danger_accept_invalid_certs + subcategory: vuln + technology: + - reqwest + pattern-either: + - pattern: reqwest::Client::builder(). ... .danger_accept_invalid_hostnames(true) + - pattern: reqwest::Client::builder(). ... .danger_accept_invalid_certs(true) + severity: WARNING + - id: rust.lang.security.reqwest-set-sensitive.reqwest-set-sensitive + languages: + - rust + message: Set sensitive flag on security headers with 'set_sensitive' to treat data with special care + metadata: + category: security + confidence: MEDIUM + cwe: 'CWE-921: Storage of Sensitive Data in a Mechanism without Access Control' + impact: LOW + likelihood: LOW + references: + - https://docs.rs/reqwest/latest/reqwest/header/struct.HeaderValue.html#method.set_sensitive + subcategory: audit + technology: + - reqwest patterns: - pattern: | - { - host: $HOST, - database: $DATABASE, - dialect: $DIALECT - } - - pattern-not: | - { - host: $HOST, - database: $DATABASE, - dialect: "postgres", - dialectOptions: { - ssl: true - } - } + let mut $HEADERS = header::HeaderMap::new(); + ... + let $HEADER_VALUE = <... header::HeaderValue::$FROM_FUNC(...) ...>; + ... + $HEADERS.insert($HEADER, $HEADER_VALUE); - pattern-not: | - { - host: $HOST, - database: $DATABASE, - dialect: $DIALECT, - dialectOptions: { - ssl: { ... } - } - } - - metavariable-regex: - metavariable: $DIALECT - regex: '[''"](mariadb|mysql|postgres|oracle)[''"]' - severity: WARNING - - id: rules_lgpl_javascript_database_rule-sequelize-tls-cert-validation + let mut $HEADERS = header::HeaderMap::new(); + ... + let $HEADER_VALUE = <... header::HeaderValue::$FROM_FUNC(...) ...>; + ... + $HEADER_VALUE.set_sensitive(true); + ... + $HEADERS.insert($HEADER, $HEADER_VALUE); + - metavariable-pattern: + metavariable: $FROM_FUNC + pattern-either: + - pattern: from_static + - pattern: from_str + - pattern: from_name + - pattern: from_bytes + - pattern: from_maybe_shared + - metavariable-pattern: + metavariable: $HEADER + pattern-either: + - pattern: header::AUTHORIZATION + - pattern: '"Authorization"' + severity: INFO + - id: rust.lang.security.rustls-dangerous.rustls-dangerous languages: - - javascript - message: "The Sequelize connection string indicates that TLS certificate validation \nof database server is disabled. This is equivalent to not having TLS. An \nattacker can present any invalid certificate and Sequelize will make database \nconnection ignoring certificate errors. This setting make the connection\nsusceptible to man in the middle (MITM) attacks. Not applicable to SQLite database.\n" + - rust + message: Dangerous client config used, ensure SSL verification metadata: category: security - cwe: CWE-295 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: HIGH - shortDescription: Improper certificate validation - patterns: + confidence: HIGH + cwe: 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: LOW + references: + - https://docs.rs/rustls/latest/rustls/client/struct.DangerousClientConfig.html + - https://docs.rs/rustls/latest/rustls/client/struct.ClientConfig.html#method.dangerous + subcategory: vuln + technology: + - rustls + pattern-either: + - pattern: rustls::client::DangerousClientConfig + - pattern: $CLIENT.dangerous().set_certificate_verifier(...) - pattern: | - { - host: $HOST, - database: $DATABASE, - dialect: $DIALECT, - dialectOptions: { - ssl: { - rejectUnauthorized: false - } - } - } - - metavariable-regex: - metavariable: $DIALECT - regex: '[''"](mariadb|mysql|postgres)[''"]' - severity: ERROR - - id: rules_lgpl_javascript_database_rule-sequelize-weak-tls + let $CLIENT = rustls::client::ClientConfig::dangerous(...); + ... + $CLIENT.set_certificate_verifier(...); + severity: WARNING + - id: rust.lang.security.ssl-verify-none.ssl-verify-none languages: - - javascript - message: | - 'The Sequelize connection string indicates that an older version of TLS is in use. TLS1.0 and TLS1.1 are deprecated and should be used. By default, Sequelize use TLSv1.2 but it''s recommended to use TLS1.3. Not applicable to SQLite database.' + - rust + message: SSL verification disabled, this allows for MitM attacks metadata: category: security - cwe: CWE-757 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: CRITICAL - shortDescription: Selection of Less-Secure Algorithm During Negotiation (Algorithm Downgrade) - patterns: - - pattern-inside: | - { - host: $HOST, - database: $DATABASE, - dialect: $DIALECT, - dialectOptions: - { ssl: ... } - } - - pattern-either: - - pattern: | - { - minVersion: 'TLSv1' - } - - pattern: | - { - minVersion: 'TLSv1.1' - } - - metavariable-regex: - metavariable: $DIALECT - regex: '[''"](mariadb|mysql|postgres)[''"]' - severity: ERROR - - id: rules_lgpl_javascript_dos_rule-layer7-object-dos + confidence: HIGH + cwe: 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: LOW + references: + - https://docs.rs/openssl/latest/openssl/ssl/struct.SslContextBuilder.html#method.set_verify + subcategory: vuln + technology: + - openssl + pattern: $BUILDER.set_verify(openssl::ssl::SSL_VERIFY_NONE) + severity: WARNING + - id: rust.lang.security.temp-dir.temp-dir languages: - - javascript - message: "This application is looping over user controlled objects, which can lead to a layer 7 denial of service vulnerability.\n\nA layer 7 denial of service attack refers to overloading the application layer of the OSI model, typically layer 7. \nThis can happen when user-controlled input such as objects, arrays, strings, etc. are iterated or looped over without proper validation or limits in place.\n\nFor example, if a user can control the size of an array or object passed into the application, \nthey could create an extremely large input that gets looped over. This would consume excessive CPU cycles or memory, \npotentially crashing or slowing down the application.\n\nTo prevent this, limits should be set on the number of iterations, input sizes, recursion depth, etc.\n\nSample case of secure array looped over with user-controlled input\n```\n// Potential DoS if req.body.list.length is large.\napp.post('/dos/layer7-object-dos/for-loop/1', function (req, res) {\n var list = req.body.list;\n for (let i = 0; i <= 10; i++) {\n if(!list[i]){\n // return;\n } \n }\n res.send(\"res\")\n});\n```\n\nImplementing protections against layer 7 denial of service attacks is important for securing modern web applications and APIs.\n" + - rust + message: 'temp_dir should not be used for security operations. From the docs: ''The temporary directory may be shared among users, or between processes with different privileges; thus, the creation of any files or directories in the temporary directory must use a secure method to create a uniquely named file. Creating a file or directory with a fixed or predictable name may result in “insecure temporary file” security vulnerabilities.''' metadata: category: security - cwe: CWE-606 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Unchecked input for loop condition - mode: taint - pattern-sinks: - - patterns: - - pattern: | - for(...; $COND; ...){...} - - focus-metavariable: $COND - - metavariable-pattern: - metavariable: $COND - pattern-either: - - pattern: | - Object.Keys($VAR).length - - pattern: $VAR.length - - patterns: - - pattern-either: - - pattern: $OBJ.forEach - - pattern: $OBJ.map - - pattern: Object.keys($OBJ).map - - pattern: $OBJ.filter - - pattern: $OBJ.reduce - - pattern: $OBJ.reduceRight - - focus-metavariable: $OBJ - pattern-sources: - - patterns: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern: $REQ.$FUNC. ... - - metavariable-regex: - metavariable: $FUNC - regex: ^(body|params|query|baseUrl|cookies|hostname|subdomains|ip|ips|originalUrl|path)$ - severity: WARNING - - id: rules_lgpl_javascript_dos_rule-regex-dos + confidence: HIGH + cwe: 'CWE-807: Reliance on Untrusted Inputs in a Security Decision' + impact: LOW + likelihood: LOW + references: + - https://doc.rust-lang.org/stable/std/env/fn.temp_dir.html + subcategory: audit + technology: + - rust + pattern: std::env::temp_dir() + severity: INFO + - id: rust.lang.security.unsafe-usage.unsafe-usage languages: - - javascript - message: | - Ensure that the regex used to compare with user supplied input is safe from regular expression denial of service. + - rust + message: Detected 'unsafe' usage, please audit for secure usage metadata: category: security - cwe: CWE-185 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Incorrect regular expression - patterns: - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $REGEX.test(<... $REQ ...>) - - pattern: | - $REGEX.test(<... $REQ.$QUERY ...>) - - pattern: | - $REGEX.test(<... $REQ.$BODY.$PARAM ...>) - - pattern: | - $INP = <... $REQ ...>; - ... - $REGEX.test(<... $INP ...>) - - pattern: | - $INP = <... $REQ.$QUERY ...>; - ... - $REGEX.test(<... $INP ...>) - - pattern: | - $INP = <... $REQ.$BODY.$PARAM ...>; - ... - $REGEX.test(<... $INP ...>) - - pattern: | - /.../g.exec(<... $REQ ...>) - - pattern: | - /.../g.exec(<... $REQ.$QUERY ...>) - - pattern: | - /.../.exec(<... $REQ.$BODY.$PARAM ...>) - - pattern: | - $INP = <... $REQ ...>; - ... - /.../.exec(<... $INP ...>) - - pattern: | - $INP = <... $REQ.$QUERY ...>; - ... - /.../.exec(<... $INP ...>) - - pattern: | - $INP = <... $REQ.$BODY.$PARAM ...>; - ... - /.../.exec(<... $INP ...>) - - pattern: | - $RE = /.../; - ... - $RE.exec(<... $REQ ...>) - - pattern: | - $RE = /.../; - ... - $RE.exec(<... $REQ.$QUERY ...>) - - pattern: | - $RE = /.../; - ... - $RE.exec(<... $REQ.$BODY.$PARAM ...>) - severity: WARNING - - id: rules_lgpl_javascript_electronjs_rule-electron-allow-http + confidence: HIGH + cwe: 'CWE-242: Use of Inherently Dangerous Function' + impact: LOW + likelihood: LOW + references: + - https://doc.rust-lang.org/std/keyword.unsafe.html + subcategory: audit + technology: + - rust + pattern: unsafe { ... } + severity: INFO + - id: scala.jwt-scala.security.jwt-scala-hardcode.jwt-scala-hardcode languages: - - javascript - message: | - Application can load content over HTTP and that makes the app vulnerable to Man in the middle attacks. + - scala + message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' metadata: category: security - cwe: CWE-319 + confidence: HIGH + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: CRITICAL - shortDescription: Cleartext Transmission of Sensitive Information + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://jwt-scala.github.io/jwt-scala/ + subcategory: + - vuln + technology: + - scala patterns: + - pattern-inside: | + import pdi.jwt.$DEPS + ... - pattern-either: - - pattern: | - new BrowserWindow({webPreferences: {allowRunningInsecureContent: true}}) - - pattern: | - var $X = {webPreferences: {allowRunningInsecureContent: true}}; - severity: ERROR - - id: rules_lgpl_javascript_electronjs_rule-electron-blink-integration + - pattern: $JWT.encode($X, "...", ...) + - pattern: $JWT.decode($X, "...", ...) + - pattern: $JWT.decodeRawAll($X, "...", ...) + - pattern: $JWT.decodeRaw($X, "...", ...) + - pattern: $JWT.decodeAll($X, "...", ...) + - pattern: $JWT.validate($X, "...", ...) + - pattern: $JWT.isValid($X, "...", ...) + - pattern: $JWT.decodeJson($X, "...", ...) + - pattern: $JWT.decodeJsonAll($X, "...", ...) + - patterns: + - pattern-either: + - pattern: $JWT.encode($X, $KEY, ...) + - pattern: $JWT.decode($X, $KEY, ...) + - pattern: $JWT.decodeRawAll($X, $KEY, ...) + - pattern: $JWT.decodeRaw($X, $KEY, ...) + - pattern: $JWT.decodeAll($X, $KEY, ...) + - pattern: $JWT.validate($X, $KEY, ...) + - pattern: $JWT.isValid($X, $KEY, ...) + - pattern: $JWT.decodeJson($X, $KEY, ...) + - pattern: $JWT.decodeJsonAll($X, $KEY, ...) + - pattern: $JWT.encode($X, this.$KEY, ...) + - pattern: $JWT.decode($X, this.$KEY, ...) + - pattern: $JWT.decodeRawAll($X, this.$KEY, ...) + - pattern: $JWT.decodeRaw($X, this.$KEY, ...) + - pattern: $JWT.decodeAll($X, this.$KEY, ...) + - pattern: $JWT.validate($X, this.$KEY, ...) + - pattern: $JWT.isValid($X, this.$KEY, ...) + - pattern: $JWT.decodeJson($X, this.$KEY, ...) + - pattern: $JWT.decodeJsonAll($X, this.$KEY, ...) + - pattern-either: + - pattern-inside: | + class $CL { + ... + $KEY = "..." + ... + } + - pattern-inside: | + object $CL { + ... + $KEY = "..." + ... + } + - metavariable-pattern: + metavariable: $JWT + patterns: + - pattern-either: + - pattern: Jwt + - pattern: JwtArgonaut + - pattern: JwtCirce + - pattern: JwtJson4s + - pattern: JwtJson + - pattern: JwtUpickle + severity: WARNING + - id: scala.lang.correctness.positive-number-index-of.positive-number-index-of languages: - - javascript - message: | - Blink's expirimental features are enabled in this application. Some of the features may affect the security of the application. + - scala + message: Flags scala code that look for values that are greater than 0. This ignores the first element, which is most likely a bug. Instead, use indexOf with -1. If the intent is to check the inclusion of a value, use the contains method instead. metadata: - category: security - cwe: CWE-272 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Least privilege violation + category: correctness + confidence: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + references: + - https://blog.codacy.com/9-scala-security-issues/ + technology: + - scala patterns: - pattern-either: - - pattern: | - new BrowserWindow({webPreferences: {enableBlinkFeatures: '...'}}) - - pattern: | - var $X = {webPreferences: {enableBlinkFeatures: '...'}}; + - patterns: + - pattern: | + $OBJ.indexOf(...) > $VALUE + - metavariable-comparison: + comparison: $VALUE >= 0 + metavariable: $VALUE + - patterns: + - pattern: | + $OBJ.indexOf(...) >= $SMALLERVAL + - metavariable-comparison: + comparison: $SMALLERVAL > 0 + metavariable: $SMALLERVAL severity: WARNING - - id: rules_lgpl_javascript_electronjs_rule-electron-context-isolation + - id: scala.lang.security.audit.documentbuilder-dtd-enabled.documentbuilder-dtd-enabled languages: - - javascript - message: | - Disabling context isolation can introduce Prototype Pollution vulnerabilities. + - scala + message: Document Builder being instantiated without calling the `setFeature` functions that are generally used for disabling entity processing. User controlled data in XML Document builder can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. metadata: category: security - cwe: CWE-1321 + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Improperly controlled modification of object prototype attributes ('Prototype Pollution') + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - scala patterns: - pattern-either: - pattern: | - new BrowserWindow({webPreferences: {contextIsolation: false}}) - - pattern: | - var $X = {webPreferences: {contextIsolation: false}}; + $DF = DocumentBuilderFactory.newInstance(...) + ... + $DB = $DF.newDocumentBuilder(...) + - patterns: + - pattern: $DB = DocumentBuilderFactory.newInstance(...) + - pattern-not-inside: | + ... + $X = $DB.newDocumentBuilder(...) + - pattern: $DB = DocumentBuilderFactory.newInstance(...).newDocumentBuilder(...) + - pattern-not-inside: | + ... + $DB.setXIncludeAware(true) + ... + $DB.setNamespaceAware(true) + ... + $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + - pattern-not-inside: | + ... + $DB.setXIncludeAware(true) + ... + $DB.setNamespaceAware(true) + ... + $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + ... + $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) + - pattern-not-inside: | + ... + $DB.setXIncludeAware(true) + ... + $DB.setNamespaceAware(true) + ... + $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + - pattern-not-inside: | + ... + $DB.setXIncludeAware(true) + ... + $DB.setNamespaceAware(true) + ... + $DB.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $DB.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + ... + $DB.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) severity: WARNING - - id: rules_lgpl_javascript_electronjs_rule-electron-disable-websecurity + - id: scala.lang.security.audit.io-source-ssrf.io-source-ssrf languages: - - javascript - message: | - Disabling webSecurity will disable the same-origin policy and allows the execution of insecure code from any domain. + - scala + message: A parameter being passed directly into `fromURL` most likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server running this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts, or hardcode the correct host. metadata: category: security - cwe: CWE-346 + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: LOW owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: CRITICAL - shortDescription: Origin validation error + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + - https://www.scala-lang.org/api/current/scala/io/Source$.html#fromURL(url:java.net.URL)(implicitcodec:scala.io.Codec):scala.io.BufferedSource + subcategory: + - audit + technology: + - scala patterns: - pattern-either: - - pattern: | - new BrowserWindow({webPreferences: {webSecurity: false}}) - - pattern: | - var $X = {webPreferences: {webSecurity: false}}; - severity: ERROR - - id: rules_lgpl_javascript_electronjs_rule-electron-experimental-features + - pattern: Source.fromURL($URL,...) + - pattern: Source.fromURI($URL,...) + - pattern-inside: | + import scala.io.$SOURCE + ... + - pattern-either: + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = $A { + ... + } + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = { + ... + } + severity: WARNING + - id: scala.lang.security.audit.rsa-padding-set.rsa-padding-set languages: - - javascript - message: | - Experimental features are not expected to be in production ready applications. + - scala + message: Usage of RSA without OAEP (Optimal Asymmetric Encryption Padding) may weaken encryption. This could lead to sensitive data exposure. Instead, use RSA with `OAEPWithMD5AndMGF1Padding` instead. metadata: category: security - cwe: CWE-272 + confidence: HIGH + cwe: + - 'CWE-780: Use of RSA Algorithm without OAEP' + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: CRITICAL - shortDescription: Least privilege violation + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + resources: + - https://blog.codacy.com/9-scala-security-issues/ + subcategory: + - audit + technology: + - scala + - cryptography patterns: - - pattern-either: - - pattern: | - new BrowserWindow({webPreferences: {experimentalFeatures: true}}) - - pattern: | - var $X = {webPreferences: {experimentalFeatures: true}}; + - pattern: | + $VAR = $CIPHER.getInstance($MODE) + - metavariable-regex: + metavariable: $MODE + regex: .*RSA/.*/NoPadding.* severity: WARNING - - id: rules_lgpl_javascript_electronjs_rule-electron-nodejs-integration + - id: scala.lang.security.audit.sax-dtd-enabled.sax-dtd-enabled languages: - - javascript - message: | - Node integration exposes node.js APIs to the electron app and this can introduce remote code execution vulnerabilities to the application if the app is vulnerable to Cross Site Scripting (XSS). + - scala + message: XML processor being instantiated without calling the `setFeature` functions that are generally used for disabling entity processing. User controlled data in XML Parsers can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. metadata: category: security - cwe: CWE-272 + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Least privilege violation + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - scala patterns: - pattern-either: + - pattern: $SR = new SAXReader(...) - pattern: | - new BrowserWindow({webPreferences: {nodeIntegration: true}}) - - pattern: | - var $X = {webPreferences: {nodeIntegration: true}}; + $SF = SAXParserFactory.newInstance(...) + ... + $SR = $SF.newSAXParser(...) + - patterns: + - pattern: $SR = SAXParserFactory.newInstance(...) + - pattern-not-inside: | + ... + $X = $SR.newSAXParser(...) + - pattern: $SR = SAXParserFactory.newInstance(...).newSAXParser(...) + - pattern: $SR = new SAXBuilder(...) + - pattern-not-inside: | + ... + $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + - pattern-not-inside: | + ... + $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + ... + $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) + - pattern-not-inside: | + ... + $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + ... + $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + - pattern-not-inside: | + ... + $SR.setFeature("http://xml.org/sax/features/external-general-entities", false) + ... + $SR.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + ... + $SR.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) severity: WARNING - - id: rules_lgpl_javascript_eval_rule-eval-nodejs + - id: scala.lang.security.audit.scalac-debug.scalac-debug languages: - - javascript - message: | - User controlled data in eval() or similar functions may result in Server Side Injection or Remote Code Injection + - generic + message: Scala applications built with `debug` set to true in production may leak debug information to attackers. Debug mode also affects performance and reliability. Remove it from configuration. metadata: category: security - cwe: CWE-95 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: HIGH - shortDescription: Improper neutralization of directives in dynamically evaluated code ('Eval Injection') + confidence: MEDIUM + cwe: + - 'CWE-489: Active Debug Code' + impact: LOW + likelihood: LOW + owasp: A05:2021 - Security Misconfiguration + references: + - https://docs.scala-lang.org/overviews/compiler-options/index.html + subcategory: + - audit + technology: + - scala + - sbt + paths: + include: + - '*.sbt*' patterns: - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - new Function(..., <... $REQ.$QUERY.$VAR ...>, ...) - - pattern: | - new Function(..., <... $REQ.$QUERY ...>, ...) - - pattern: | - eval(..., <... $REQ.$QUERY.$VAR ...>, ...) - - pattern: | - eval(..., <... $REQ.$QUERY ...>, ...) - - pattern: | - setTimeout(..., <... $REQ.$QUERY.$VAR ...>, ...) - - pattern: | - setTimeout(..., <... $REQ.$QUERY ...>, ...) - - pattern: | - setInterval(..., <... $REQ.$QUERY.$VAR ...>, ...) - - pattern: | - setInterval(..., <... $REQ.$QUERY ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY.$VAR ...>; - ... - new Function(..., <... $INP ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY ...>; - ... - new Function(..., <... $INP ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY.$VAR ...>; - ... - eval(..., <... $INP ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY ...>; - ... - eval(..., <... $INP ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY.$VAR ...>; - ... - setTimeout(..., <... $INP ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY ...>; - ... - setTimeout(..., <... $INP ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY.$VAR ...>; - ... - setInterval(..., <... $INP ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY ...>; - ... - setInterval(..., <... $INP ...>, ...) - severity: ERROR - - id: rules_lgpl_javascript_eval_rule-eval-require + - pattern: scalacOptions ... "-Vdebug" + - pattern: scalacOptions ... "-Ydebug" + severity: WARNING + - id: scala.lang.security.audit.tainted-sql-string.tainted-sql-string languages: - - javascript - message: "Passing untrusted user input directly into the require() function without proper \nvalidation or sanitization can possibly cause a vulnerability known as remote code execution (RCE). \nAn attacker could manipulate the input to load and execute arbitrary code from external sources, \npotentially leading to severe security breaches such as data theft, system compromise, \nor unauthorized access.\nTo mitigate this risk, it's crucial to validate and sanitize user input\nthoroughly before passing it to functions like require(), ensuring that only trusted and safe inputs are utilized.\n\nFollowing is an example of secure validation against allowlist to prevent the vulnerability:\n```\n// Define a list of explicitly allowed packages for require\nconst allowedPkgs = [\n 'package1',\n 'package2',\n 'package3'\n];\n\napp.get(\"/eval/require/7\", async (req, res) => {\n var isAllowed = allowedPkgs.includes(req.query.name); \n if (isAllowed) {\n // ok: rules_lgpl_javascript_eval_rule-eval-require\n var cp = require(req.query.name);\n cp.exec('ls', (error, stdout, stderr) => {\n console.log(\"exec output : \\n\", stdout)\n }); \n }\n res.send(\"Please check console logs.\");\n});\n```\n" + - scala + message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. metadata: category: security - cwe: CWE-706 + confidence: MEDIUM + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Use of incorrectly-resolved name or reference + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html + subcategory: + - vuln + technology: + - scala mode: taint pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: "if($VALIDATION){\n...\nrequire($REQ, ...) \n...\n} \n" - - pattern: | - $A = $VALIDATION - ... - if($A){ - ... - require($REQ, ...) - ... - } - - metavariable-pattern: - metavariable: $VALIDATION - pattern-either: - - pattern: "$AL.includes(...) \n" - - pattern: | - $AL.indexOf(...) !== -1 - - pattern: | - $AL.find(...) !== undefined - - pattern: | - $ALS.has(...) + - pattern-either: + - patterns: + - pattern-either: + - pattern: $LOGGER.$METHOD(...) + - pattern: $LOGGER(...) + - metavariable-regex: + metavariable: $LOGGER + regex: (i?)log.* + - patterns: + - pattern: $LOGGER.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (i?)(trace|info|warn|warning|warnToError|error|debug) pattern-sinks: - patterns: - - pattern: | - require($REQ, ...) - - focus-metavariable: $REQ + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR".format(...) + - patterns: + - pattern-inside: | + $SB = new StringBuilder("$SQLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$SQLSTR" + ... + - pattern: $VAR += ... + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b + - patterns: + - pattern-either: + - pattern: s"..." + - pattern: f"..." + - pattern-regex: | + .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - pattern-not-inside: println(...) pattern-sources: - patterns: - - pattern-inside: | - function ($REQ, $RES, ...) {...} - - focus-metavariable: $REQ + - pattern: $PARAM + - pattern-either: + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = $A { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = $A(...) { + ... + } severity: ERROR - - id: rules_lgpl_javascript_eval_rule-grpc-insecure-connection + - id: scala.lang.security.audit.xmlinputfactory-dtd-enabled.xmlinputfactory-dtd-enabled languages: - - javascript - - typescript - message: | - Found an insecure gRPC connection. This creates a connection without encryption to a gRPC client/server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. + - scala + message: XMLInputFactory being instantiated without calling the setProperty functions that are generally used for disabling entity processing. User controlled data in XML Document builder can result in XML Internal Entity Processing vulnerabilities like the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning. Make sure to disable entity processing functionality. metadata: category: security - cwe: CWE-502 + confidence: HIGH + cwe: + - 'CWE-611: Improper Restriction of XML External Entity Reference' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: CRITICAL - shortDescription: Deserialization of Untrusted Data + - A04:2017 - XML External Entities (XXE) + - A05:2021 - Security Misconfiguration + references: + - https://owasp.org/Top10/A05_2021-Security_Misconfiguration + source-rule-url: https://cheatsheetseries.owasp.org//cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + subcategory: + - audit + technology: + - scala patterns: + - pattern-not-inside: | + ... + $XMLFACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", false) - pattern-either: - - pattern-inside: | - require('grpc') - ... - - pattern-inside: | - import $MOD from 'grpc' - ... - - pattern: $CREDENTIALS.createInsecure() - severity: ERROR - - id: rules_lgpl_javascript_eval_rule-node-deserialize + - pattern: $XMLFACTORY = XMLInputFactory.newFactory(...) + - pattern: $XMLFACTORY = XMLInputFactory.newInstance(...) + - pattern: $XMLFACTORY = new XMLInputFactory(...) + severity: WARNING + - id: scala.play.security.conf-csrf-headers-bypass.conf-csrf-headers-bypass languages: - - javascript - - typescript - message: | - User controlled data in 'unserialize()' or 'deserialize()' function can result in Object Injection or Remote Code Injection. + - generic + message: Possibly bypassable CSRF configuration found. CSRF is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. Make sure that Content-Type black list is configured and CORS filter is turned on. metadata: category: security - cwe: CWE-502 + confidence: MEDIUM + cwe: + - 'CWE-352: Cross-Site Request Forgery (CSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: LOW + likelihood: LOW owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: CRITICAL - shortDescription: Deserialization of Untrusted Data + - A01:2021 - Broken Access Control + references: + - https://www.playframework.com/documentation/2.8.x/Migration25#CSRF-changes + - https://owasp.org/www-community/attacks/csrf + subcategory: + - vuln + technology: + - scala + - play + paths: + include: + - '*.conf' patterns: - pattern-either: - - pattern: | - require('node-serialize').unserialize(...) - - pattern-inside: | - $MOD = require('node-serialize') - ... - - pattern-inside: | - import $MOD from 'node-serialize' - ... - - pattern: | - $MOD.unserialize(...) + - pattern: X-Requested-With = "*" + - pattern: Csrf-Token = "..." + - pattern-inside: | + bypassHeaders {... + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."application/x-www-form-urlencoded"..."multipart/form-data"..."text/plain"...] + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."application/x-www-form-urlencoded"..."text/plain"..."multipart/form-data"...] + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."multipart/form-data"..."application/x-www-form-urlencoded"..."text/plain"...] + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."multipart/form-data"..."text/plain"..."application/x-www-form-urlencoded"...] + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."text/plain"..."application/x-www-form-urlencoded"..."multipart/form-data"...] + ... + ...} + - pattern-not-inside: | + {... + ... + ...blackList = [..."text/plain"..."multipart/form-data"..."application/x-www-form-urlencoded"...] + ... + ...} severity: ERROR - - id: rules_lgpl_javascript_eval_rule-sandbox-code-injection + - id: scala.play.security.conf-insecure-cookie-settings.conf-insecure-cookie-settings languages: - - javascript - message: | - Unrusted data in `sandbox` can result in code injection. + - generic + message: Session cookie `Secure` flag is explicitly disabled. The `secure` flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the `Secure` flag by setting `secure` to `true` in configuration file. metadata: category: security - cwe: CWE-94 + confidence: MEDIUM + cwe: + - 'CWE-614: Sensitive Cookie in HTTPS Session Without ''Secure'' Attribute' + impact: LOW + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code (Code Injection) + - A05:2021 - Security Misconfiguration + references: + - https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#security + - https://www.playframework.com/documentation/2.8.x/SettingsSession#Session-Configuration + subcategory: + - vuln + technology: + - play + - scala + paths: + include: + - '*.conf' patterns: + - pattern: secure = false - pattern-inside: | - require('sandbox') - ... - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $S.run(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: | - $CODE = <... $REQ.$QUERY.$FOO ...>; - ... - $S.run(<... $CODE ...>,...) - - pattern: | - new $SANDBOX(...).run(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: | - $CODE = <... $REQ.$QUERY.$FOO ...>; - ... - new $SANDBOX(...).run(<... $CODE ...>,...) - - pattern: | - $S.run(<... $REQ.$BODY ...>,...) - - pattern: | - $CODE = <... $REQ.$BODY ...>; - ... - $S.run(<... $CODE ...>,...) - - pattern: | - new $SANDBOX(...).run(<... $REQ.$BODY ...>,...) - - pattern: |- - $CODE = <... $REQ.$BODY ...>; - ... - new $SANDBOX(...).run(<... $CODE ...>,...) - severity: ERROR - - id: rules_lgpl_javascript_eval_rule-serializetojs-deserialize + session = { + ... + } + severity: WARNING + - id: scala.play.security.tainted-html-response.tainted-html-response languages: - - javascript - - typescript - message: | - User controlled data in 'unserialize()' or 'deserialize()' function can result in Object Injection or Remote Code Injection. + - scala + message: Detected a request with potential user-input going into an `Ok()` response. This bypasses any view or template environments, including HTML escaping, which may expose this application to cross-site scripting (XSS) vulnerabilities. Consider using a view technology such as Twirl which automatically escapes HTML views. metadata: category: security - cwe: CWE-502 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: CRITICAL - shortDescription: Deserialization of Untrusted Data - patterns: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + subcategory: + - vuln + technology: + - scala + - play + mode: taint + pattern-sanitizers: - pattern-either: - - pattern: | - require('serialize-to-js').deserialize(...) - - pattern-inside: | - $MOD = require('serialize-to-js') - ... - - pattern-inside: | - import $MOD from 'serialize-to-js' - ... - - pattern: | - $MOD.deserialize(...) - severity: ERROR - - id: rules_lgpl_javascript_eval_rule-server-side-template-injection + - pattern: org.apache.commons.lang3.StringEscapeUtils.escapeHtml4(...) + - pattern: org.owasp.encoder.Encode.forHtml(...) + pattern-sinks: + - pattern-either: + - pattern: Html.apply(...) + - pattern: Ok(...).as(HTML) + - pattern: Ok(...).as(ContentTypes.HTML) + - patterns: + - pattern: Ok(...).as($CTYPE) + - metavariable-regex: + metavariable: $CTYPE + regex: '"[tT][eE][xX][tT]/[hH][tT][mM][lL]"' + - patterns: + - pattern: Ok(...).as($CTYPE) + - pattern-not: Ok(...).as("...") + - pattern-either: + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = $A { + ... + } + - pattern-inside: | + def $FUNC(..., $URL: $T, ...) = { + ... + } + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern: $REQ + - pattern-either: + - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - patterns: + - pattern: $PARAM + - pattern-either: + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { + ... + } + severity: WARNING + - id: scala.play.security.tainted-slick-sqli.tainted-slick-sqli languages: - - javascript - message: | - Untrusted user input in templating engine's compile() function can result in Remote Code Execution via server side template injection. + - scala + message: Detected a tainted SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Avoid using using user input for generating SQL strings. metadata: category: security - cwe: CWE-94 + confidence: HIGH + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code (Code Injection) - patterns: - - pattern-either: - - pattern-inside: | - require('handlebars') - ... - - pattern-inside: | - require('pug') - ... - - pattern-inside: | - require('hamljs') - ... - - pattern-inside: | - require('ejs') - ... - - pattern-inside: | - require('squirrelly') - ... + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://scala-slick.org/doc/3.3.3/sql.html#splicing-literal-values + - https://scala-slick.org/doc/3.2.0/sql-to-slick.html#non-optimal-sql-code + subcategory: + - vuln + technology: + - scala + - slick + - play + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - pattern: $MODEL.overrideSql(...) + - pattern: sql"..." - pattern-inside: | - require('eta') - ... - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $HB.compile(..., <... $REQ.$FOO ...>, ...) - - pattern: | - $HB.compile(..., <... $REQ.$FOO.$BAR ...>, ...) - - pattern: | - $X = <... $REQ.$FOO ...>; - ... - $HB.compile(..., <... $X ...>, ...) - - pattern: | - $X = <... $REQ.$FOO.$BAR ...>; - ... - $HB.compile(..., <... $X ...>, ...) - - pattern: | - $X = $SOURCE.replace('...', <... $REQ.$FOO ...>, ...) - ... - $HB.compile(..., <... $X ...>, ...) - - pattern: | - $X = $SOURCE.replace('...', <... $REQ.$FOO.$BAR ...>, ...) - ... - $HB.compile(..., <... $X ...>, ...) - - pattern: | - $HB.Compile(..., <... $REQ.$FOO ...>, ...) - - pattern: | - $HB.Compile(..., <... $REQ.$FOO.$BAR ...>, ...) - - pattern: | - $X = <... $REQ.$FOO ...>; - ... - $HB.Compile(..., <... $X ...>, ...) - - pattern: | - $X = <... $REQ.$FOO.$BAR ...>; - ... - $HB.Compile(..., <... $X ...>, ...) - - pattern: | - $X = $SOURCE.replace('...', <... $REQ.$FOO ...>, ...) - ... - $HB.Compile(..., <... $X ...>, ...) - - pattern: | - $X = $SOURCE.replace('...', <... $REQ.$FOO.$BAR ...>, ...) + import slick.$DEPS ... - $HB.Compile(..., <... $X ...>, ...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern: $REQ + - pattern-either: + - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - patterns: + - pattern: $PARAM + - pattern-either: + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { + ... + } severity: ERROR - - id: rules_lgpl_javascript_eval_rule-vm2-code-injection + - id: scala.play.security.tainted-sql-from-http-request.tainted-sql-from-http-request languages: - - javascript - message: | - Untrusted user input reaching `vm2` can result in code injection. + - scala + message: User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library. metadata: category: security - cwe: CWE-94 + confidence: HIGH + cwe: + - 'CWE-89: Improper Neutralization of Special Elements used in an SQL Command (''SQL Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code (Code Injection) - patterns: - - pattern-inside: | - require('vm2') - ... - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $VM.run(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: | - $CODE = <... $REQ.$QUERY.$FOO ...>; - ... - $VM.run(<... $CODE ...>,...) - - pattern: | - new VM(...).run(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: | - new NodeVM(...).run(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: | - $CODE = <... $REQ.$QUERY.$FOO ...>; - ... - new NodeVM(...).run(<... $CODE ...>,...) - - pattern: | - $CODE = <... $REQ.$QUERY.$FOO ...>; - ... - new VMScript(<... $CODE ...>,...) - - pattern: | - $VM.run(<... $REQ.$BODY ...>,...) - - pattern: | - $CODE = <... $REQ.$BODY ...>; - ... - $VM.run(<... $CODE ...>,...) - - pattern: | - new VM(...).run(<... $REQ.$BODY ...>,...) - - pattern: | - $CODE = <... $REQ.$BODY ...>; - ... - new VM(...).run($CODE,...) - - pattern: | - new NodeVM(...).run(<... $REQ.$BODY ...>,...) - - pattern: | - $CODE = <... $REQ.$BODY ...>; - ... - new NodeVM(...).run(<... $CODE ...>,...) - - pattern: | - $CODE = <... $REQ.$BODY ...>; - ... - new VMScript(<... $CODE ...>,...) - severity: WARNING - - id: rules_lgpl_javascript_eval_rule-vm2-context-injection + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html + subcategory: + - vuln + technology: + - scala + - play + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + "$SQLSTR" + ... + - pattern: | + "$SQLSTR".format(...) + - patterns: + - pattern-inside: | + $SB = new StringBuilder("$SQLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$SQLSTR" + ... + - pattern: $VAR += ... + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop)\b + - patterns: + - pattern: s"..." + - pattern-regex: | + .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.* + - pattern-not-inside: println(...) + pattern-sources: + - patterns: + - pattern-either: + - patterns: + - pattern: $REQ + - pattern-either: + - pattern-inside: "Action {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async {\n $REQ: Request[$T] => \n ...\n}\n" + - pattern-inside: "Action.async(...) {\n $REQ: Request[$T] => \n ...\n}\n" + - patterns: + - pattern: $PARAM + - pattern-either: + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action(...) { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async { + ... + } + - pattern-inside: | + def $CTRL(..., $PARAM: $TYPE, ...) = Action.async(...) { + ... + } + severity: ERROR + - id: scala.scala-jwt.security.jwt-hardcode.scala-jwt-hardcoded-secret languages: - - javascript - message: | - Untrusted user input reaching `vm2` sandbox can result in context injection. + - scala + message: 'Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)' metadata: category: security - cwe: CWE-94 + confidence: HIGH + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code (Code Injection) - patterns: - - pattern-inside: | - require('vm2') + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - audit + technology: + - jwt + pattern-either: + - pattern: | + com.auth0.jwt.algorithms.Algorithm.HMAC256("..."); + - pattern: | + $SECRET = "..."; ... - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - new VM({sandbox: <... $REQ.$QUERY.$FOO ...>},...) - - pattern: | - $CONTEXT = <... $REQ.$QUERY.$FOO ...>; - ... - new VM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; - ... - new VM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; - ... - new VM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $VAR = <... $REQ.$QUERY.$FOO ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - new VM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $OPTS = {sandbox: <... $REQ.$QUERY.$FOO ...>}; - ... - new VM($OPTS,...) - - pattern: | - $CONTEXT = <... $REQ.$QUERY.$FOO ...>; - ... - $OPTS = {sandbox: <... $CONTEXT ...>}; - ... - new VM($OPTS,...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; - ... - $OPTS = {sandbox: <... $CONTEXT ...>}; - ... - new VM($OPTS,...) - - pattern: | - $VAR = <... $REQ.$QUERY.$FOO ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - $OPTS = {sandbox: <... $CONTEXT ...>}; - ... - new VM($OPTS,...) - - pattern: | - new NodeVM({sandbox: <... $REQ.$QUERY.$FOO ...>},...) - - pattern: | - $CONTEXT = <... $REQ.$QUERY.$FOO ...>; - ... - new NodeVM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; - ... - new NodeVM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; - ... - new NodeVM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $VAR = <... $REQ.$QUERY.$FOO ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - new NodeVM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $OPTS = {sandbox: <... $REQ.$QUERY.$FOO ...>}; - ... - new NodeVM($OPTS,...) - - pattern: | - $CONTEXT = <... $REQ.$QUERY.$FOO ...>; - ... - $OPTS = {sandbox: <... $CONTEXT ...>}; - ... - new NodeVM($OPTS,...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; - ... - $OPTS = {sandbox: <... $CONTEXT ...>}; - ... - new NodeVM($OPTS,...) - - pattern: | - $VAR = <... $REQ.$QUERY.$FOO ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - $OPTS = {sandbox: <... $CONTEXT ...>}; - ... - new NodeVM($OPTS,...) - - pattern: | - new VM({sandbox: <... $REQ.$BODY ...>},...) - - pattern: | - $CONTEXT = <... $REQ.$BODY ...>; - ... - new VM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = <... {$NAME:$REQ.$BODY} ...>; - ... - new VM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; - ... - new VM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $VAR = <... $REQ.$BODY ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - new VM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $OPTS = {sandbox: <... $REQ.$BODY ...>}; - ... - new VM($OPTS,...) - - pattern: | - $CONTEXT = <... $REQ.$BODY ...>; - ... - $OPTS = {sandbox: <... $CONTEXT ...>}; - ... - new VM($OPTS,...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; - ... - $OPTS = {sandbox: <... $CONTEXT ...>}; - ... - new VM($OPTS,...) - - pattern: | - $VAR = <... $REQ.$BODY ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - $OPTS = {sandbox: <... $CONTEXT ...>}; - ... - new VM($OPTS,...) - - pattern: | - new NodeVM({sandbox: <... $REQ.$BODY ...>},...) - - pattern: | - $CONTEXT = <... $REQ.$BODY ...>; - ... - new NodeVM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = <... {$NAME:$REQ.$BODY} ...>; - ... - new NodeVM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; - ... - new NodeVM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $VAR = <... $REQ.$BODY ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - new NodeVM({sandbox: <... $CONTEXT ...>},...) - - pattern: | - $OPTS = {sandbox: <... $REQ.$BODY ...>}; - ... - new NodeVM($OPTS,...) - - pattern: | - $CONTEXT = <... $REQ.$BODY ...>; - ... - $OPTS = {sandbox: <... $CONTEXT ...>}; + com.auth0.jwt.algorithms.Algorithm.HMAC256($SECRET); + - pattern: | + class $CLASS { + ... + $DECL $SECRET = "..."; + ... + def $FUNC (...): $RETURNTYPE = { ... - new NodeVM($OPTS,...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; + com.auth0.jwt.algorithms.Algorithm.HMAC256($SECRET); ... - $OPTS = {sandbox: <... $CONTEXT ...>}; + } + ... + } + - pattern: | + com.auth0.jwt.algorithms.Algorithm.HMAC384("..."); + - pattern: | + $SECRET = "..."; + ... + com.auth0.jwt.algorithms.Algorithm.HMAC384($SECRET); + - pattern: | + class $CLASS { + ... + $DECL $SECRET = "..."; + ... + def $FUNC (...): $RETURNTYPE = { ... - new NodeVM($OPTS,...) - - pattern: |- - $VAR = <... $REQ.$BODY ...>; + com.auth0.jwt.algorithms.Algorithm.HMAC384($SECRET); ... - $CONTEXT = {$NAME: <... $VAR ...>}; + } + ... + } + - pattern: | + com.auth0.jwt.algorithms.Algorithm.HMAC512("..."); + - pattern: | + $SECRET = "..."; + ... + com.auth0.jwt.algorithms.Algorithm.HMAC512($SECRET); + - pattern: | + class $CLASS { + ... + $DECL $SECRET = "..."; + ... + def $FUNC (...): $RETURNTYPE = { ... - $OPTS = {sandbox: <... $CONTEXT ...>}; + com.auth0.jwt.algorithms.Algorithm.HMAC512($SECRET); ... - new NodeVM($OPTS,...) + } + ... + } severity: ERROR - - id: rules_lgpl_javascript_eval_rule-vm-code-injection + - id: swift.lang.storage.sensitive-storage-userdefaults.swift-user-defaults languages: - - javascript - message: | - Untrusted user input reaching `vm` can result in code injection. + - swift + message: Potentially sensitive data was observed to be stored in UserDefaults, which is not adequate protection of sensitive information. For data of a sensitive nature, applications should leverage the Keychain. metadata: category: security - cwe: CWE-94 + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW + masvs: + - 'MASVS-STORAGE-1: The app securely stores sensitive data' owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code (Code Injection) + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html + - https://mas.owasp.org/MASVS/controls/MASVS-STORAGE-1/ + subcategory: + - vuln + technology: + - ios + - macos + options: + symbolic_propagation: true patterns: - - pattern-inside: | - $VM = require('vm') - ... - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - pattern-either: - - pattern: $VM.runInContext(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $VM.runInContext(<... $REQ.$BODY ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $VM.runInContext($INPUT,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $VM.runInContext($INPUT,...) - - pattern: $VM.runInNewContext(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $VM.runInNewContext(<... $REQ.$BODY ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $VM.runInNewContext($INPUT,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $VM.runInNewContext($INPUT,...) - - pattern: $VM.runInThisContext(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $VM.runInThisContext(<... $REQ.$BODY ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $VM.runInThisContext($INPUT,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $VM.runInThisContext($INPUT,...) - - pattern: $VM.compileFunction(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $VM.compileFunction(<... $REQ.$BODY ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $VM.compileFunction($INPUT,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $VM.compileFunction($INPUT,...) - - pattern: new $VM.Script(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: new $VM.Script(<... $REQ.$BODY ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - new $VM.Script($INPUT,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - new $VM.Script($INPUT,...) - severity: ERROR - - id: rules_lgpl_javascript_eval_rule-vm-compilefunction-injection + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $VALUE + regex: (?i).*(passcode|password|pass_word|passphrase|pass_code|pass_word|pass_phrase)$ + - focus-metavariable: $VALUE + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $KEY + regex: (?i).*(passcode|password|pass_word|passphrase|pass_code|pass_word|pass_phrase)$ + - focus-metavariable: $KEY + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $VALUE + regex: (?i).*(api_key|apikey)$ + - focus-metavariable: $VALUE + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $KEY + regex: (?i).*(api_key|apikey)$ + - focus-metavariable: $KEY + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $VALUE + regex: (?i).*(secretkey|secret_key|secrettoken|secret_token|clientsecret|client_secret)$ + - focus-metavariable: $VALUE + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $KEY + regex: (?i).*(secretkey|secret_key|secrettoken|secret_token|clientsecret|client_secret)$ + - focus-metavariable: $KEY + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $VALUE + regex: (?i).*(cryptkey|cryptokey|crypto_key|cryptionkey|symmetrickey|privatekey|symmetric_key|private_key)$ + - focus-metavariable: $VALUE + - patterns: + - pattern-either: + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: "$KEY") + - pattern: | + UserDefaults.standard.set("$VALUE", forKey: $KEY) + - pattern: | + UserDefaults.standard.set($VALUE, forKey: "$KEY") + - pattern: | + UserDefaults.standard.set($VALUE, forKey: $KEY) + - metavariable-regex: + metavariable: $KEY + regex: (?i).*(cryptkey|cryptokey|crypto_key|cryptionkey|symmetrickey|privatekey|symmetric_key|private_key)$ + - focus-metavariable: $KEY + severity: WARNING + - id: swift.webview.webview-js-window.swift-webview-config-allows-js-open-windows languages: - - javascript - message: | - Untrusted user input in `vm.compileFunction()` can result in code injection. + - swift + message: Webviews were observed that explictly allow JavaScript in an WKWebview to open windows automatically. Consider disabling this functionality if not required, following the principle of least privelege. metadata: category: security - cwe: CWE-94 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code (Code Injection) + confidence: HIGH + cwe: + - 'CWE-272: Least Privilege Violation' + impact: LOW + likelihood: LOW + masvs: + - 'MASVS-PLATFORM-2: The app uses WebViews securely' + references: + - https://mas.owasp.org/MASVS/controls/MASVS-PLATFORM-2/ + - https://developer.apple.com/documentation/webkit/wkpreferences/1536573-javascriptcanopenwindowsautomati + subcategory: + - audit + technology: + - ios + - macos patterns: - - pattern-inside: | - require('vm') + - pattern: | + $P = WKPreferences() ... - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $REQ.$QUERY.$FOO ...>},...) - - pattern: | - $CONTEXT = <... $REQ.$QUERY.$FOO ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) - - pattern: | - $VAR = <... $REQ.$QUERY.$FOO ...>; ... $CONTEXT = {$NAME: <... $VAR ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) - - pattern: | - $OPTS = {parsingContext: <... $REQ.$QUERY.$FOO ...>}; - ... - $VM.compileFunction($CODE,$PARAMS,$OPTS,...) - - pattern: | - $CONTEXT = <... $REQ.$QUERY.$FOO ...>; - ... - $OPTS = {parsingContext: <... $CONTEXT ...>}; - ... - $VM.compileFunction($CODE,$PARAMS,$OPTS,...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; - ... - $OPTS = {parsingContext: <... $CONTEXT ...>}; - ... - $VM.compileFunction($CODE,$PARAMS,$OPTS,...) - - pattern: | - $VAR = <... $REQ.$QUERY.$FOO ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - $OPTS = {parsingContext: <... $CONTEXT ...>}; - ... - $VM.compileFunction($CODE,$PARAMS,$OPTS,...) - - pattern: | - $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $REQ.$BODY ...>},...) - - pattern: | - $CONTEXT = <... $REQ.$BODY ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = <... {$NAME:$REQ.$BODY} ...>; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) - - pattern: | - $VAR = <... $REQ.$BODY ...>; ... $CONTEXT = {$NAME: <... $VAR ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT ...>},...) - - pattern: | - $OPTS = {parsingContext: <... $REQ.$BODY ...>}; - ... - $VM.compileFunction($CODE,$PARAMS,$OPTS,...) - - pattern: | - $CONTEXT = <... $REQ.$BODY ...>; - ... - $OPTS = {parsingContext: <... $CONTEXT ...>}; - ... - $VM.compileFunction($CODE,$PARAMS,$OPTS,...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; - ... - $OPTS = {parsingContext: <... $CONTEXT ...>}; - ... - $VM.compileFunction($CODE,$PARAMS,$OPTS,...) - - pattern: | - $VAR = <... $REQ.$BODY ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - $OPTS = {parsingContext: <... $CONTEXT ...>}; - ... - $VM.compileFunction($CODE,$PARAMS,$OPTS,...) - severity: ERROR - - id: rules_lgpl_javascript_eval_rule-vm-runincontext-injection + - patterns: + - pattern-inside: | + $P.JavaScriptCanOpenWindowsAutomatically = $FALSE + ... + $P.JavaScriptCanOpenWindowsAutomatically = $TRUE + - pattern-not-inside: | + ... + $P.JavaScriptCanOpenWindowsAutomatically = $TRUE + ... + $P.JavaScriptCanOpenWindowsAutomatically = $FALSE + - pattern: | + $P.JavaScriptCanOpenWindowsAutomatically = true + - metavariable-regex: + metavariable: $TRUE + regex: ^(true)$ + - metavariable-regex: + metavariable: $TRUE + regex: (.*(?!true)) + - patterns: + - pattern: | + $P.JavaScriptCanOpenWindowsAutomatically = true + - pattern-not-inside: | + ... + $P.JavaScriptCanOpenWindowsAutomatically = ... + ... + $P.JavaScriptCanOpenWindowsAutomatically = ... + severity: WARNING + - id: terraform.aws.correctness.subscription-filter-missing-depends.subscription-filter-missing-depends languages: - - javascript - message: | - Untrusted user input in `vm.runInContext()` can result in code injection. + - hcl + message: The `aws_cloudwatch_log_subscription_filter` resource "$NAME" needs a `depends_on` clause on the `aws_lambda_permission`, otherwise Terraform may try to create these out-of-order and fail. metadata: - category: security - cwe: CWE-94 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code (Code Injection) + category: correctness + confidence: MEDIUM + references: + - https://stackoverflow.com/questions/38407660/terraform-configuring-cloudwatch-log-subscription-delivery-to-lambda/38428834#38428834 + technology: + - aws + - terraform + - aws-lambda + - cloudwatch patterns: - - pattern-inside: | - require('vm') - ... - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $CONTEXT = <... $REQ.$QUERY.$FOO ...>; - ... - $VM.runInContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; - ... - $VM.runInContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; - ... - $VM.runInContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $VAR = <... $REQ.$QUERY.$FOO ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - $VM.runInContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $CONTEXT = <... $REQ.$BODY ...>; - ... - $VM.runInContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $CONTEXT = <... {$NAME:$REQ.$BODY} ...>; - ... - $VM.runInContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; - ... - $VM.runInContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $VAR = <... $REQ.$BODY ...>; - ... - $CONTEXT = {$NAME: <... $VAR ...>}; - ... - $VM.runInContext($CODE,<... $CONTEXT ...>,...) - severity: ERROR - - id: rules_lgpl_javascript_eval_rule-vm-runinnewcontext-injection + - pattern: | + resource "aws_cloudwatch_log_subscription_filter" $NAME { + ... + destination_arn = aws_lambda_function.$LAMBDA_NAME.arn + } + - pattern-not-inside: | + resource "aws_cloudwatch_log_subscription_filter" $NAME { + ... + depends_on = [..., aws_lambda_permission.$PERMISSION_NAME, ...] + } + severity: WARNING + - id: terraform.aws.security.aws-cloudfront-insecure-tls.aws-insecure-cloudfront-distribution-tls-version languages: - - javascript - message: | - Untrusted user input in `vm.runInNewContext()` can result in code injection. + - hcl + message: Detected an AWS CloudFront Distribution with an insecure TLS version. TLS versions less than 1.2 are considered insecure because they can be broken. To fix this, set your `minimum_protocol_version` to `"TLSv1.2_2018", "TLSv1.2_2019" or "TLSv1.2_2021"`. metadata: category: security - cwe: CWE-94 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code (Code Injection) + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - aws patterns: - - pattern-inside: | - require('vm') - ... - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $VM.runInNewContext($CODE,<... $REQ.$QUERY.$FOO ...>,...) - - pattern: | - $CONTEXT = <... $REQ.$QUERY.$FOO ...>; - ... - $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; - ... - $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; - ... - $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $VAR = <... $REQ.$QUERY.$FOO ...>; + - pattern: | + resource "aws_cloudfront_distribution" $ANYTHING { + ... + viewer_certificate { ... - $CONTEXT = {$NAME: <... $VAR ...>}; + } + ... + } + - pattern-not-inside: | + resource "aws_cloudfront_distribution" $ANYTHING { + ... + viewer_certificate { ... - $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $VM.runInNewContext($CODE,<... $REQ.$BODY ...>,...) - - pattern: | - $CONTEXT = <... $REQ.$BODY ...>; + minimum_protocol_version = "TLSv1.2_2018" ... - $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $CONTEXT = {$NAME: <... $REQ.$BODY ...>}; + } + ... + } + - pattern-not-inside: | + resource "aws_cloudfront_distribution" $ANYTHING { + ... + viewer_certificate { ... - $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $CONTEXT = <... {$NAME:$REQ.$BODY} ...>; + minimum_protocol_version = "TLSv1.2_2019" ... - $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) - - pattern: | - $VAR = <... $REQ.$BODY ...>; + } + ... + } + - pattern-not-inside: | + resource "aws_cloudfront_distribution" $ANYTHING { + ... + viewer_certificate { ... - $CONTEXT = {$NAME: <... $VAR ...>}; + minimum_protocol_version = "TLSv1.2_2021" ... - $VM.runInNewContext($CODE,<... $CONTEXT ...>,...) - severity: ERROR - - id: rules_lgpl_javascript_eval_rule-yaml-deserialize + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-cloudwatch-log-group-no-retention.aws-cloudwatch-log-group-no-retention languages: - - javascript - - typescript - message: | - User controlled data in 'yaml.load()' function can result in Remote Code Injection. + - hcl + message: The AWS CloudWatch Log Group has no retention. Missing retention in log groups can cause losing important event information. metadata: category: security - cwe: CWE-502 + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: CRITICAL - shortDescription: Deserialization of Untrusted Data + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform patterns: - - pattern-either: - - pattern: | - require('js-yaml').load(...) - - pattern-inside: | - $MOD = require('js-yaml') - ... - - pattern-inside: | - import $MOD from 'js-yaml' - ... - pattern: | - $MOD.load(...) - severity: ERROR - - id: rules_lgpl_javascript_exec_rule-shelljs-os-command-exec + resource "aws_cloudwatch_log_group" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_cloudwatch_log_group" $ANYTHING { + ... + retention_in_days = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-codebuild-project-unencrypted.aws-codebuild-project-unencrypted languages: - - javascript - message: | - User controlled data in 'shelljs.exec()' can result in Remote OS Command Execution. + - hcl + message: The AWS CodeBuild Project is unencrypted. The AWS KMS encryption key protects projects in the CodeBuild. To create your own, create a aws_kms_key resource or use the ARN string of a key in your account. metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform patterns: - - pattern-inside: | - require('shelljs') - ... - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $EXEC.exec(<... $REQ.$QUERY.$VAR ...>, ...) - - pattern: | - $EXEC.exec( <... $REQ.$QUERY ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY.$VAR ...>; - ... - $EXEC.exec(<... $INP ...>, ...) - - pattern: | - $INP = <... $REQ.$QUERY ...>; - ... - $EXEC.exec(<... $INP ...>, ...) - severity: ERROR - - id: rules_lgpl_javascript_headers_rule-cookie-session-default + - pattern: | + resource "aws_codebuild_project" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_codebuild_project" $ANYTHING { + ... + encryption_key = ... + ... + } + severity: WARNING + - id: terraform.aws.security.aws-config-aggregator-not-all-regions.aws-config-aggregator-not-all-regions languages: - - javascript - message: | - Consider changing the default session cookie name. An attacker can use it to fingerprint the server and target attacks accordingly. + - hcl + message: The AWS configuration aggregator does not aggregate all AWS Config region. This may result in unmonitored configuration in regions that are thought to be unused. Configure the aggregator with all_regions for the source. metadata: category: security - cwe: CWE-522 + confidence: HIGH + cwe: + - 'CWE-778: Insufficient Logging' + impact: MEDIUM + likelihood: LOW owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: INFO - shortDescription: Insufficiently protected credentials - patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session') + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ + subcategory: + - audit + technology: + - terraform + - aws + pattern-either: + - pattern: | + resource "aws_config_configuration_aggregator" $ANYTHING { + ... + account_aggregation_source { ... - - pattern-inside: | - $SESSION = require('express-session') + regions = ... ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {name:...} ...>,...) - - pattern-not-inside: | - $OPTS = <... {name:...} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.name = ...; - ... - $SESSION($OPTS,...) - severity: INFO - - id: rules_lgpl_javascript_headers_rule-cookie-session-no-domain - languages: - - javascript - message: | - 'Default session middleware settings: `domain` not set. It indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.' - metadata: - category: security - cwe: CWE-522 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: INFO - shortDescription: Insufficiently protected credentials - patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session') + } + ... + } + - pattern: | + resource "aws_config_configuration_aggregator" $ANYTHING { + ... + organization_aggregation_source { ... - - pattern-inside: | - $SESSION = require('express-session') + regions = ... ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{domain:...}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{domain:...}} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {domain:...} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {domain:...} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.domain = ...; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.domain = ...; - ... - $SESSION($OPTS,...) - severity: INFO - - id: rules_lgpl_javascript_headers_rule-cookie-session-no-httponly + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-db-instance-no-logging.aws-db-instance-no-logging languages: - - javascript - message: | - 'Session middleware settings: `httpOnly` is explicitly set to false. It ensures that sensitive cookies cannot be accessed by client side JavaScript and helps to protect against cross-site scripting attacks.' + - hcl + message: Database instance has no logging. Missing logs can cause missing important event information. metadata: category: security - cwe: CWE-1004 + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: LOW + likelihood: MEDIUM owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: MEDIUM - shortDescription: Sensitive cookie without 'HttpOnly' flag + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + subcategory: + - vuln + technology: + - aws + - terraform patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session') - ... - - pattern-inside: | - $SESSION = require('express-session') - ... - - pattern-either: - - pattern-inside: $SESSION(<... {cookie:{httpOnly:false}} ...>,...) - - pattern-inside: | - $OPTS = <... {cookie:{httpOnly:false}} ...>; - ... - $SESSION($OPTS,...) - - pattern-inside: | - $OPTS = ...; - ... - $COOKIE = <... {httpOnly:false} ...>; - ... - $SESSION($OPTS,...) - - pattern-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {httpOnly:false} ...>; - ... - $SESSION($OPTS,...) - - pattern-inside: | - $OPTS = ...; - ... - $COOKIE.httpOnly = false; - ... - $SESSION($OPTS,...) - - pattern-inside: | - $OPTS = ...; - ... - $OPTS.cookie.httpOnly = false; - ... - $SESSION($OPTS,...) + - pattern: | + resource "aws_db_instance" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_db_instance" $ANYTHING { + ... + enabled_cloudwatch_logs_exports = [$SOMETHING, ...] + ... + } severity: WARNING - - id: rules_lgpl_javascript_headers_rule-cookie-session-no-maxage + - id: terraform.aws.security.aws-documentdb-auditing-disabled.aws-documentdb-auditing-disabled languages: - - javascript - message: | - 'Session middleware settings: `maxAge` not set. Use it to set expiration date for cookies.' + - hcl + message: Auditing is not enabled for DocumentDB. To ensure that you are able to accurately audit the usage of your DocumentDB cluster, you should enable auditing and export logs to CloudWatch. metadata: category: security - cwe: CWE-613 + confidence: MEDIUM + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + likelihood: LOW owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: INFO - shortDescription: Insufficient session expiration + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_cluster#enabled_cloudwatch_logs_exports + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/ + subcategory: + - audit + technology: + - terraform + - aws patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session') - ... - - pattern-inside: | - $SESSION = require('express-session') - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{maxAge:...}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{maxAge:...}} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {maxAge:...} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {maxAge:...} ...>; - ... - $SESSION($OPTS,...) + - pattern: | + resource "aws_docdb_cluster" $ANYTHING { + ... + } - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.maxAge = ...; - ... - $SESSION($OPTS,...) - - pattern-not-inside: |- - $OPTS = ...; - ... - $OPTS.cookie.maxAge = ...; - ... - $SESSION($OPTS,...) + resource "aws_docdb_cluster" $ANYTHING { + ... + enabled_cloudwatch_logs_exports = [..., "audit", ...] + ... + } severity: INFO - - id: rules_lgpl_javascript_headers_rule-cookie-session-no-path + - id: terraform.aws.security.aws-dynamodb-table-unencrypted.aws-dynamodb-table-unencrypted languages: - - javascript - message: | - 'Default session middleware settings: `path` not set. It indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request.' + - hcl + message: By default, AWS DynamoDB Table is encrypted using AWS-managed keys. However, for added security, it's recommended to configure your own AWS KMS encryption key to protect your data in the DynamoDB table. You can either create a new aws_kms_key resource or use the ARN of an existing key in your AWS account to do so. metadata: category: security - cwe: CWE-522 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: INFO - shortDescription: Insufficiently protected credentials + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session') - ... - - pattern-inside: | - $SESSION = require('express-session') - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{path:...}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{path:...}} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {path:...} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {path:...} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.path = ...; - ... - $SESSION($OPTS,...) + - pattern: | + resource "aws_dynamodb_table" $ANYTHING { + ... + } - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.path = ...; - ... - $SESSION($OPTS,...) - severity: INFO - - id: rules_lgpl_javascript_headers_rule-cookie-session-no-samesite + resource "aws_dynamodb_table" $ANYTHING { + ... + server_side_encryption { + enabled = true + kms_key_arn = ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ebs-snapshot-encrypted-with-cmk.aws-ebs-snapshot-encrypted-with-cmk languages: - - javascript - message: | - 'Default session middleware settings: `sameSite` attribute is not configured to strict or lax. These configurations provides protection against Cross Site Request Forgery attacks.' + - hcl + message: Ensure EBS Snapshot is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. metadata: category: security - cwe: CWE-1275 + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: MEDIUM - shortDescription: Sensitive cookie with improper SameSite attribute + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - aws patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session') - ... - - pattern-inside: | - $SESSION = require('express-session') - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{sameSite:true}} ...>,...) - - pattern-not-inside: $SESSION(<... {cookie:{sameSite:'lax'}} ...>,...) - - pattern-not-inside: $SESSION(<... {cookie:{sameSite:'strict'}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{sameSite:true}} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {sameSite:true} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {sameSite:true} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.sameSite = true; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.sameSite = true; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{sameSite:'strict'}} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {sameSite:'strict'} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {sameSite:'strict'} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.sameSite = 'strict'; - ... - $SESSION($OPTS,...) + - pattern: | + resource "aws_ebs_snapshot_copy" $ANYTHING { + ... + encrypted = true + ... + } - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.sameSite = 'strict'; - ... - $SESSION($OPTS,...) + resource "aws_ebs_snapshot_copy" $ANYTHING { + ... + encrypted = true + kms_key_id = ... + ... + } severity: WARNING - - id: rules_lgpl_javascript_headers_rule-cookie-session-no-secure + - id: terraform.aws.security.aws-ebs-unencrypted.aws-ebs-unencrypted languages: - - javascript - message: | - 'Default session middleware settings: `secure` not set. It ensures the browser only sends the cookie over HTTPS.' + - hcl + message: The AWS EBS is unencrypted. The AWS EBS encryption protects data in the EBS. metadata: category: security - cwe: CWE-614 + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: MEDIUM - shortDescription: Sensitive cookie in HTTPS session without 'Secure' attribute + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform patterns: - - pattern-either: - - pattern-inside: | - $SESSION = require('cookie-session') - ... - - pattern-inside: | - $SESSION = require('express-session') - ... - - pattern: $SESSION(...) - - pattern-not-inside: $SESSION(<... {cookie:{secure:true}} ...>,...) - - pattern-not-inside: | - $OPTS = <... {cookie:{secure:true}} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE = <... {secure:true} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie = <... {secure:true} ...>; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $COOKIE.secure = true; - ... - $SESSION($OPTS,...) - - pattern-not-inside: | - $OPTS = ...; - ... - $OPTS.cookie.secure = true; - ... - $SESSION($OPTS,...) + - pattern: | + resource "aws_ebs_encryption_by_default" $ANYTHING { + ... + enabled = false + ... + } severity: WARNING - - id: rules_lgpl_javascript_headers_rule-express-cors + - id: terraform.aws.security.aws-ebs-volume-unencrypted.aws-ebs-volume-unencrypted languages: - - javascript - message: | - Access-Control-Allow-Origin response header is set to "*". This will disable CORS Same Origin Policy restrictions. + - hcl + message: The AWS EBS volume is unencrypted. The volume, the disk I/O and any derived snapshots could be read if compromised. Volumes should be encrypted to ensure sensitive data is stored securely. metadata: category: security - cwe: CWE-346 + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Origin validation error + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume#encrypted + - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html + subcategory: + - audit + technology: + - terraform + - aws patterns: - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $APP.options('*', cors(...)) - - pattern: | - $RES.set("=~/access-control-allow-origin/i", '*', ...) - - pattern: | - $RES.set(..., { "=~/access-control-allow-origin/i" : '*' }, ...) - - pattern: | - $RES.header("=~/access-control-allow-origin/i", '*', ...) - - pattern: | - $RES.writeHead(..., {"=~/access-control-allow-origin/i": '*' }, ...) + - pattern: | + resource "aws_ebs_volume" $ANYTHING { + ... + } + - pattern-not: | + resource "aws_ebs_volume" $ANYTHING { + ... + encrypted = true + ... + } severity: WARNING - - id: rules_lgpl_javascript_headers_rule-generic-cors + - id: terraform.aws.security.aws-ec2-has-public-ip.aws-ec2-has-public-ip languages: - - javascript - message: | - Access-Control-Allow-Origin response header is set to "*". This will disable CORS Same Origin Policy restrictions. + - hcl + message: EC2 instances should not have a public IP address attached in order to block public access to the instances. To fix this, set your `associate_public_ip_address` to `"false"`. metadata: category: security - cwe: CWE-346 + confidence: MEDIUM + cwe: + - 'CWE-284: Improper Access Control' + impact: MEDIUM + likelihood: LOW owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Origin validation error + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - terraform + - aws patterns: - - pattern: | - $APP.options('*', cors(...)) + - pattern-either: + - pattern: | + resource "aws_instance" $ANYTHING { + ... + associate_public_ip_address = true + ... + } + - pattern: | + resource "aws_launch_template" $ANYTHING { + ... + network_interfaces { + ... + associate_public_ip_address = true + ... + } + ... + } severity: WARNING - - id: rules_lgpl_javascript_headers_rule-generic-header-injection + - id: terraform.aws.security.aws-ec2-launch-template-metadata-service-v1-enabled.aws-ec2-launch-template-metadata-service-v1-enabled languages: - - javascript - message: | - Untrusted user input in response header will result in HTTP Header Injection or Response Splitting Attacks. + - hcl + message: The EC2 launch template has Instance Metadata Service Version 1 (IMDSv1) enabled. IMDSv2 introduced session authentication tokens which improve security when talking to IMDS. You should either disable IMDS or require the use of IMDSv2. metadata: category: security - cwe: CWE-644 + confidence: MEDIUM + cwe: + - 'CWE-1390: Weak Authentication' + impact: HIGH + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of HTTP headers for scripting syntax + - A07:2021 - Identification and Authentication Failures + references: + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration#metadata_options + - https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service + subcategory: + - audit + technology: + - terraform + - aws patterns: - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $INP = $REQ.$QUERY; - ... - $RES.set(..., <... $INP ...>, ...) - - pattern: | - $INP = $REQ.$QUERY.$VAR; - ... - $RES.set(..., <... $INP ...>, ...) - - pattern: | - $INP = $REQ.$VAR; + - pattern: | + resource "aws_launch_template" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_launch_template" $ANYTHING { + ... + metadata_options { ... - $RES.set(..., { $X: <... $INP ...>}, ...) - - pattern: | - $INP = $REQ.$QUERY.$FOO; + http_endpoint = "disabled" ... - $RES.set(..., { $X: <... $INP ...>}, ...) - - pattern: | - $INP = $REQ.$VAR; + } + ... + } + - pattern-not-inside: | + resource "aws_launch_template" $ANYTHING { + ... + metadata_options { ... - $RES.writeHead(..., { $X: <... $INP ...> }, ...) - - pattern: | - $INP = $REQ.$QUERY.$FOO; + http_tokens = "required" ... - $RES.writeHead(..., { $X: <... $INP ...> }, ...) - - pattern: | - $RES.set(..., <... $REQ.$QUERY ...>, ...) - - pattern: | - $RES.set(..., <... $REQ.$QUERY.$VAR ...>, ...) - - pattern: | - $RES.set(..., { $X: <... $REQ.$VAR ...>}, ...) - - pattern: | - $RES.set(..., { $X: <... $REQ.$QUERY.$FOO ...>}, ...) - - pattern: | - $RES.writeHead(..., { $X: <... $REQ.$VAR ...> }, ...) - - pattern: | - $RES.writeHead(..., { $X: <... $REQ.$QUERY.$FOO ...> }, ...) - severity: ERROR - - id: rules_lgpl_javascript_headers_rule-header-xss-generic + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-ecr-mutable-image-tags.aws-ecr-mutable-image-tags languages: - - javascript - message: | - X-XSS-Protection header is set to 0. This will disable the browser's XSS Filter. + - hcl + message: The ECR repository allows tag mutability. Image tags could be overwritten with compromised images. ECR images should be set to IMMUTABLE to prevent code injection through image mutation. This can be done by setting `image_tag_mutability` to IMMUTABLE. metadata: category: security - cwe: CWE-358 + confidence: MEDIUM + cwe: + - 'CWE-345: Insufficient Verification of Data Authenticity' + impact: HIGH + likelihood: LOW owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Improperly implemented security check for standard + - A08:2021 - Software and Data Integrity Failures + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository#image_tag_mutability + - https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/ + subcategory: + - audit + technology: + - terraform + - aws patterns: - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $RES.header("=~/x-xss-protection/i", 0, ...) - - pattern: | - $RES.set("=~/x-xss-protection/i", 0, ...) - - pattern: | - $RES.set(..., { "=~/x-xss-protection/i" : 0 }, ...) - - pattern: | - $RES.writeHead(..., {"=~/x-xss-protection/i": 0 }, ...) + - pattern: | + resource "aws_ecr_repository" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_ecr_repository" $ANYTHING { + ... + image_tag_mutability = "IMMUTABLE" + ... + } severity: WARNING - - id: rules_lgpl_javascript_headers_rule-header-xss-lusca + - id: terraform.aws.security.aws-ecr-repository-wildcard-principal.aws-ecr-repository-wildcard-principal languages: - - javascript - message: | - X-XSS-Protection header is set to 0. This will disable the browser's XSS Filter. + - hcl + message: Detected wildcard access granted in your ECR repository policy principal. This grants access to all users, including anonymous users (public access). Instead, limit principals, actions and resources to what you need according to least privilege. metadata: category: security - cwe: CWE-358 + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Improperly implemented security check for standard + - A05:2021 - Security Misconfiguration + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository_policy + - https://docs.aws.amazon.com/lambda/latest/operatorguide/wildcard-permissions-iam.html + - https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/monitor-amazon-ecr-repositories-for-wildcard-permissions-using-aws-cloudformation-and-aws-config.html + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - vuln + technology: + - aws + - terraform patterns: - pattern-inside: | - $X = require('lusca') - ... - - pattern-not: | - $X.use(helmet()) + resource "aws_ecr_repository_policy" $ANYTHING { + ... + } - pattern-either: - - pattern: | - $X.xssProtection(false) - - pattern: | - $X({ xssProtection: false}) + - patterns: + - pattern: policy = "$JSONPOLICY" + - metavariable-pattern: + language: json + metavariable: $JSONPOLICY + patterns: + - pattern-not-inside: | + {..., "Effect": "Deny", ...} + - pattern-either: + - pattern: | + {..., "Principal": "*", ...} + - pattern: | + {..., "Principal": [..., "*", ...], ...} + - pattern: | + {..., "Principal": { "AWS": "*" }, ...} + - pattern: | + {..., "Principal": { "AWS": [..., "*", ...] }, ...} + - patterns: + - pattern-inside: policy = jsonencode(...) + - pattern-not-inside: | + {..., Effect = "Deny", ...} + - pattern-either: + - pattern: | + {..., Principal = "*", ...} + - pattern: | + {..., Principal = [..., "*", ...], ...} + - pattern: | + {..., Principal = { AWS = "*" }, ...} + - pattern: | + {..., Principal = { AWS = [..., "*", ...] }, ...} severity: WARNING - - id: rules_lgpl_javascript_headers_rule-helmet-feature-disabled + - id: terraform.aws.security.aws-efs-filesystem-encrypted-with-cmk.aws-efs-filesystem-encrypted-with-cmk languages: - - javascript - message: | - One or more Security Response header is explicitly disabled in Helmet. + - hcl + message: Ensure EFS filesystem is encrypted at rest using KMS CMKs. CMKs gives you control over the encryption key in terms of access and rotation. metadata: category: security - cwe: CWE-358 + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Improperly implemented security check for standard + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - aws patterns: - - pattern-either: - - pattern: | - $HELMET(..., {frameguard: false}, ...) - - pattern: | - $HELMET(..., {contentSecurityPolicy: false}, ...) - - pattern: | - $HELMET(..., {permittedCrossDomainPolicies: false}, ...) - - pattern: | - $HELMET(..., {dnsPrefetchControl: false}, ...) - - pattern: | - $HELMET(..., {expectCt: false}, ...) - - pattern: | - $HELMET(..., {featurePolicy: false}, ...) - - pattern: | - $HELMET(..., {hsts: false}, ...) - - pattern: | - $HELMET(..., {ieNoOpen: false}, ...) - - pattern: | - $HELMET(..., {noSniff: false}, ...) - - pattern: | - $HELMET(..., {hidePoweredBy: false}, ...) - - pattern: | - $HELMET(..., {referrerPolicy: false}, ...) - - pattern: | - $HELMET(..., {xssFilter: false}, ...) + - pattern: | + resource "aws_efs_file_system" $ANYTHING { + ... + encrypted = true + ... + } + - pattern-not-inside: | + resource "aws_efs_file_system" $ANYTHING { + ... + encrypted = true + kms_key_id = ... + ... + } severity: WARNING - - id: rules_lgpl_javascript_headers_rule-host-header-injection + - id: terraform.aws.security.aws-elasticsearch-insecure-tls-version.aws-elasticsearch-insecure-tls-version languages: - - javascript - message: | - Using untrusted Host header for generating dynamic URLs can result in web cache and or password reset poisoning. + - terraform + message: Detected an AWS Elasticsearch domain using an insecure version of TLS. To fix this, set "tls_security_policy" equal to "Policy-Min-TLS-1-2-2019-07". metadata: category: security - cwe: CWE-348 + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Use of less trusted source + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform + pattern: | + resource "aws_elasticsearch_domain" $ANYTHING { + ... + domain_endpoint_options { + ... + enforce_https = true + tls_security_policy = "Policy-Min-TLS-1-0-2019-07" + ... + } + ... + } + severity: WARNING + - id: terraform.aws.security.aws-elasticsearch-nodetonode-encryption.aws-elasticsearch-nodetonode-encryption-not-enabled + languages: + - hcl + message: "Ensure all Elasticsearch has node-to-node encryption enabled.\t" + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW + owasp: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - aws patterns: - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $X = <... "=~/.*http[s]*:///i" + $REQ.host ...>; - pattern: | - $X = <... "=~/.*http[s]*:///i" + $REQ["host"] ...>; - - pattern: | - $X = <... "=~/.*http[s]*:///i" + $REQ("host") ...>; - - pattern: | - $X = { $Y: <... "=~/.*http[s]*:///i" + $REQ.host ...>}; - - pattern: | - $X = { $Y: <... "=~/.*http[s]*:///i" + $REQ["host"] ...>}; - - pattern: | - $X = { $Y: <... "=~/.*http[s]*:///i" + $REQ("host") ...>}; - - pattern: | - $Z = $REQ.host; - ... - $X = <... "=~/.*http[s]*:///i" + $Z ...>; - - pattern: | - $Z = $REQ["host"]; - ... - $X = <... "=~/.*http[s]*:///i" + $Z ...>; + resource "aws_elasticsearch_domain" $ANYTHING { + ... + node_to_node_encryption { + ... + enabled = false + ... + } + ... + } - pattern: | - $Z = $REQ("host") + resource "aws_elasticsearch_domain" $ANYTHING { + ... + cluster_config { + ... + instance_count = $COUNT + ... + } + } + - pattern-not-inside: | + resource "aws_elasticsearch_domain" $ANYTHING { + ... + cluster_config { ... - $X = <... "=~/.*http[s]*:///i" + $Z ...>; - - pattern: | - $Z = $REQ.host; + instance_count = $COUNT ... - $X = { $Y: <... "=~/.*http[s]*:///i" + $REQ.host ...>}; - - pattern: | - $Z = $REQ["host"]; + } + node_to_node_encryption { ... - $X = { $Y: <... "=~/.*http[s]*:///i" + $Z ...>}; - - pattern: | - $Z = $REQ("host") + enabled = true ... - $X = { $Y: <... "=~/.*http[s]*:///i" + $REQ("host") ...>}; + } + } + - metavariable-comparison: + comparison: $COUNT > 1 + metavariable: $COUNT severity: WARNING - - id: rules_lgpl_javascript_jwt_rule-hardcoded-jwt-secret + - id: terraform.aws.security.aws-glacier-vault-any-principal.aws-glacier-vault-any-principal languages: - - javascript - message: "Hardcoded JWT secret or private key was found. Hardcoding secrets like JWT signing keys poses a significant security risk. \nIf the source code ends up in a public repository or is compromised, the secret is exposed. Attackers could then use the secret to \ngenerate forged tokens and access the system. Store it properly in an environment variable.\n\nHere are some recommended safe ways to access JWT secrets:\n - Use environment variables to store the secret and access it in code instead of hardcoding. This keeps it out of source control.\n - Use a secrets management service to securely store and tightly control access to the secret. Applications can request the secret at runtime.\n - For local development, use a .env file that is gitignored and access the secret from process.env.\n\nsample code snippet of accessing JWT secret from env variables\n```\n const token = jwt.sign(payload, process.env.SECRET, { algorithm: 'HS256' });\n```\n" + - hcl + message: 'Detected wildcard access granted to Glacier Vault. This means anyone within your AWS account ID can perform actions on Glacier resources. Instead, limit to a specific identity in your account, like this: `arn:aws:iam:::`.' metadata: category: security - cwe: CWE-798 + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: HIGH - shortDescription: Use of hard-coded credentials + - A05:2021 - Security Misconfiguration + references: + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - vuln + technology: + - aws patterns: - - pattern-either: - - pattern-inside: | - const $JWT = require("jsonwebtoken"); - ... - - pattern-inside: | - const $JOSE = require("jose"); - ... - - pattern-inside: | - import $JWT from "jsonwebtoken" - ... - - pattern-inside: | - import $JOSE from "jose" - ... - - pattern-either: - - pattern: $JWT.sign($PAYLOAD, "...", ...) - - pattern: $JWT.verify($PAYLOAD, "...", ...) - - pattern: new $JOSE.SignJWT(...). ... .sign("...") - - pattern: | - var $TOKEN = new $JOSE.SignJWT(...). ... - ... - $TOKEN. ... .sign("...") - - pattern: $JOSE.jwtVerify( $TKN, "...", ... ) - - patterns: + - pattern-inside: | + resource "aws_glacier_vault" $ANYTHING { + ... + } + - pattern: access_policy = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-inside: | + {..., "Effect": "Allow", ...} - pattern-either: - - patterns: - - pattern-inside: | - var $KEY = $X - ... - - pattern-either: - - pattern: new $JOSE.SignJWT(...). ... .sign($KEY) - - patterns: - - pattern: | - var $TOKEN = new $JOSE.SignJWT(...). ... - ... - $TOKEN. ... .sign($KEY) - - pattern: $TOKEN. ... .sign($KEY) - - pattern: $JOSE.jwtVerify( $TKN, $KEY, ... ) - - pattern: new $JOSE.SignJWT(...). ... .sign($X) - - patterns: - - pattern: | - var $TOKEN = new $JOSE.SignJWT(...). ... - ... - $TOKEN. ... .sign($X) - - pattern: $TOKEN. ... .sign($X) - - pattern: $JOSE.jwtVerify( $TKN, $X, ... ) - - metavariable-pattern: - metavariable: $X - pattern-either: - - pattern: new TextEncoder().encode( "...",... ) - - pattern: Uint8Array.from("...", ...) + - pattern: | + "Principal": "*" + - pattern: | + "Principal": {..., "AWS": "*", ...} + - pattern-inside: | + "Principal": {..., "AWS": ..., ...} + - pattern-regex: | + (^\"arn:aws:iam::\*:(.*)\"$) severity: ERROR - - id: rules_lgpl_javascript_jwt_rule-jwt-exposed-credentials + - id: terraform.aws.security.aws-iam-admin-policy-ssoadmin.aws-iam-admin-policy-ssoadmin languages: - - javascript - message: "The application is storing a password in the JWT token payload. Storing \npasswords in JWT token payloads is an insecure practice that can lead to \ncompromised credentials. \n\nThe password transmitted in the JWT payload is not encrypted and therefore \nvisible to anyone who intercepts the token. It is recommended to avoid storing \nsensitive information like passwords in JWTs. Instead, reference user identifiers \nthat map to credentials stored securely on the server.This helps to mitigate the \nrisk of exposing passwords through JWT tokens that could be intercepted or leaked.\n\nSecure code example of secure JWT signing:\n```\nrouter.route(\"/jsonwebtoken/1\").get((req, res) => {\n // any payload without passwords or any other sensitive data will be secure\n const payload = { user_id: 123, username: 'john_doe' };\n const token = jwt.sign(payload, secretKey, { algorithm: 'HS256' });\n console.log('Generated Token:', token);\n res.send({ token })\n})\n```\n" + - hcl + message: Detected admin access granted in your policy. This means anyone with this policy can perform administrative actions. Instead, limit actions and resources to what you need according to least privilege. metadata: category: security - cwe: CWE-522 + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: HIGH - shortDescription: Insufficiently protected credentials + - A05:2021 - Security Misconfiguration + references: + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - vuln + technology: + - aws patterns: - - pattern-either: - - pattern-inside: | - const $JWT = require("jsonwebtoken"); - ... - - pattern-inside: | - const $JOSE = require("jose"); - ... - - pattern-inside: | - import $JWT from "jsonwebtoken" - ... - - pattern-inside: | - import $JOSE from "jose" - ... - - pattern-either: - - pattern: '$JWT.sign(<... {$PASSWORD: $VALUE} ...>, ...)' - - patterns: - - pattern: | - $OBJ = <... {$PASSWORD: $VALUE} ...> - ... - $TOKEN = $JWT.sign(<... $OBJ ...>, ...) - - pattern: $TOKEN = $JWT.sign(<... $OBJ ...>, ...) - - patterns: - - pattern: | - $OBJ. ... .$PASSWORD = ... - ... - $TOKEN = $JWT.sign(<... $OBJ ...>, ...) - - pattern: $TOKEN = $JWT.sign(<... $OBJ ...>, ...) - - pattern: 'new $JOSE.SignJWT(<... {$PASSWORD: $VALUE} ...>)' - - patterns: - - pattern: | - $OBJ = <... {$PASSWORD: $VALUE} ...> - ... - new $JOSE.SignJWT(<... $OBJ ...>) - - pattern: new $JOSE.SignJWT(<... $OBJ ...>) - - patterns: - - pattern: | - $OBJ. ... .$PASSWORD = ... - ... - new $JOSE.SignJWT(<... $OBJ ...>) - - pattern: new $JOSE.SignJWT(<... $OBJ ...>) - - metavariable-regex: - metavariable: $PASSWORD - regex: (?i)\b(?:.*password.*)\b + - pattern-inside: | + resource "aws_ssoadmin_permission_set_inline_policy" $ANYTHING { + ... + } + - pattern: inline_policy = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-not-inside: | + {..., "Effect": "Deny", ...} + - pattern-either: + - pattern: | + {..., "Action": [..., "*", ...], "Resource": [..., "*", ...], ...} + - pattern: | + {..., "Action": "*", "Resource": "*", ...} + - pattern: | + {..., "Action": "*", "Resource": [...], ...} + - pattern: | + {..., "Action": [...], "Resource": "*", ...} severity: ERROR - - id: rules_lgpl_javascript_jwt_rule-jwt-exposed-data + - id: terraform.aws.security.aws-iam-admin-policy.aws-iam-admin-policy languages: - - javascript - message: | - The object is passed strictly to jose.JWT.sign(...). Make sure that sensitive information is not exposed through JWT token payload. + - hcl + message: Detected admin access granted in your policy. This means anyone with this policy can perform administrative actions. Instead, limit actions and resources to what you need according to least privilege. metadata: category: security - cwe: CWE-522 + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: HIGH - shortDescription: Insufficiently protected credentials + - A05:2021 - Security Misconfiguration + references: + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - vuln + technology: + - aws + - terraform patterns: - pattern-inside: | - require('jose') - ... - - pattern-either: - - patterns: - - pattern-inside: function (...,$INPUT,...) {...} - - pattern-either: - - pattern: $JOSE.JWT.sign($INPUT,...) - - pattern: $JWT.sign($INPUT,...) - - patterns: - - pattern-inside: function $F(...,$INPUT,...) {...} + resource "aws_iam_policy" $ANYTHING { + ... + } + - pattern: policy = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-not-inside: | + {..., "Effect": "Deny", ...} - pattern-either: - - pattern: $JOSE.JWT.sign($INPUT,...) - - pattern: $JWT.sign($INPUT,...) - severity: WARNING - - id: rules_lgpl_javascript_jwt_rule-jwt-express-hardcoded + - pattern: | + {..., "Action": [..., "*", ...], "Resource": [..., "*", ...], ...} + - pattern: | + {..., "Action": "*", "Resource": "*", ...} + - pattern: | + {..., "Action": "*", "Resource": [...], ...} + - pattern: | + {..., "Action": [...], "Resource": "*", ...} + severity: ERROR + - id: terraform.aws.security.aws-insecure-api-gateway-tls-version.aws-insecure-api-gateway-tls-version languages: - - javascript - message: "Hardcoded JWT secret or private key was found. Hardcoding secrets like JWT signing keys poses a significant security risk. \nIf the source code ends up in a public repository or is compromised, the secret is exposed. Attackers could then use the secret to \ngenerate forged tokens and access the system. Store it properly in an environment variable.\n\nHere are some recommended safe ways to access JWT secrets:\n - Use environment variables to store the secret and access it in code instead of hardcoding. This keeps it out of source control.\n - Use a secrets management service to securely store and tightly control access to the secret. Applications can request the secret at runtime.\n - For local development, use a .env file that is gitignored and access the secret from process.env.\n\nsample code snippet of accessing JWT secret from env variables\n```\nrouter.route(\"/auth-route-1\").get(\n jwt({ secret: process.env.secret, algorithms: ['HS256'] }),\n (req, res) => {\n res.send('Token is valid');\n }\n);\n```\n" + - terraform + message: Detected AWS API Gateway to be using an insecure version of TLS. To fix this issue make sure to set "security_policy" equal to "TLS_1_2". metadata: category: security - cwe: CWE-522 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: CRITICAL - shortDescription: Insufficiently protected credentials + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform patterns: - pattern-either: - - pattern-inside: | - import { ..., $JWT,... } from 'express-jwt'; - ... - - pattern-inside: | - var {..., expressjwt: $JWT,... } = require('express-jwt'); - ... - - pattern-either: - - pattern: $JWT(<...{...,secret:"...",...}...>) - - patterns: - - pattern-inside: | - $OPTS = <... {secret: "..."} ...>; + - pattern: | + resource "aws_api_gateway_domain_name" $ANYTHING { ... - - pattern: $JWT(<... $OPTS ...>,...) - - patterns: - - pattern-inside: | - $OPTS = <... {secret: "..."} ...>; + security_policy = "..." ... - $OPTS2 = <... $OPTS ...>; + } + - pattern: | + resource "aws_apigatewayv2_domain_name" $ANYTHING { ... - - pattern: $JWT(<... $OPTS2 ...>,...) - severity: ERROR - - id: rules_lgpl_javascript_jwt_rule-jwt-not-revoked + domain_name_configuration {...} + ... + } + - pattern-not: | + resource "aws_api_gateway_domain_name" $ANYTHING { + ... + security_policy = "TLS_1_2" + ... + } + - pattern-not: | + resource "aws_apigatewayv2_domain_name" $ANYTHING { + ... + domain_name_configuration { + ... + security_policy = "TLS_1_2" + ... + } + } + severity: WARNING + - id: terraform.aws.security.aws-insecure-redshift-ssl-configuration.aws-insecure-redshift-ssl-configuration languages: - - javascript - message: | - No token revoking configured for `express-jwt`. A leaked token could still be used and unable to be revoked. Consider using function as the `isRevoked` option. + - hcl + message: Detected an AWS Redshift configuration with a SSL disabled. To fix this, set your `require_ssl` to `"true"`. metadata: category: security - cwe: CWE-522 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: HIGH - shortDescription: Insufficiently protected credentials + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - aws patterns: - - pattern-inside: | - $JWT = require('express-jwt') - ... - - pattern: $JWT(...) - - pattern-not-inside: $JWT(<... {isRevoked:...} ...>,...) - - pattern-not-inside: |- - $OPTS = <... {isRevoked:...} ...>; - ... - $JWT($OPTS,...) + - pattern: | + resource "aws_redshift_parameter_group" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_redshift_parameter_group" $ANYTHING { + ... + parameter { + name = "require_ssl" + value = "true" + } + ... + } + - pattern-not-inside: | + resource "aws_redshift_parameter_group" $ANYTHING { + ... + parameter { + name = "require_ssl" + value = true + } + ... + } severity: WARNING - - id: rules_lgpl_javascript_jwt_rule-node-jwt-none-algorithm - languages: - - javascript - message: "Use of `{algorithm:'none'}` detected with `jsonwebtoken`. \nUsing none as the algorithm for jsonwebtoken can directly impact the integrity of the information transfer through the JWT token.\nConsider using a secure algorithm to sign your JWT token such as HMAC or RSA.\nSome safe usage examples:\n```\nlet token = jwt.sign({user:\"user1\"}, 'secret', {algorithm: 'HS256'}); \n```\nUsing a secure algorithm can protect the integrity of the token information. \nAvoid using none as the algorithm when signing jwt tokens since it can violate the integrity of the JWT information.\n" - metadata: - category: security - cwe: CWE-327 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: CRITICAL - shortDescription: Use of a broken or risky cryptographic algorithm - mode: taint - pattern-sinks: - - pattern: $JWT.verify($P, $X, {...,algorithms:[...,'none',...],...},...) - - pattern: $JWT.sign($P, $X, {...,algorithm:'none',...},...) - pattern-sources: - - pattern: $JWT = require("jsonwebtoken") - - pattern: import $JWT from "jsonwebtoken" - severity: ERROR - - id: rules_lgpl_javascript_redirect_rule-express-open-redirect + - id: terraform.aws.security.aws-kinesis-stream-unencrypted.aws-kinesis-stream-unencrypted languages: - - javascript - message: "Passing untrusted user input in `redirect()` can result in an open redirect\nvulnerability. This could be abused by malicious actors to trick users into \nbeing redirected to websites under their control to capture authentication\ninformation. \nTo prevent open redirect vulnerabilities:\n\n- Always validate and sanitize user inputs, especially URL parameters\n or query strings that may influence the flow of the application.\n- Use allowlists (lists of permitted URLs) to validate redirect targets \n against known, trusted URLs before performing the redirect.\n- Avoid directly using user input for redirecting. If unavoidable, ensure\n strict validation against an allowlist.\n\nFollowing is an example of secure validation against allowlist to prevent the vulnerability:\n ```\n // Define a list of explicitly allowed URLs for redirection\n const allowedUrls = [\n 'https://www.example.com/page1',\n 'https://www.example.com/page2',\n 'https://secure.example.com/page3'\n ];\n\n app.get('/redirect/:url', (req, res) => {\n const url = decodeURIComponent(req.params.url);\n const isAllowed = allowedUrls.includes(url);\n if (isAllowed) {\n // If the URL is allowed, proceed with the redirect\n res.redirect(url);\n } else {\n res.status(400).send('Invalid redirect URL');\n }\n });\n ```\n" + - hcl + message: The AWS Kinesis stream does not encrypt data at rest. The data could be read if the Kinesis stream storage layer is compromised. Enable Kinesis stream server-side encryption. metadata: category: security - cwe: CWE-601 + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: URL redirection to untrusted site 'open redirect' - mode: taint - pattern-sanitizers: - - pattern-either: - - patterns: - - pattern-either: - - pattern: "if($VALIDATION){\n ...\n $RES.redirect(...)\n ...\n} \n" - - pattern: | - $A = $VALIDATION - ... - if($A){ - ... - $RES.redirect(...) - ... - } - - metavariable-pattern: - metavariable: $VALIDATION - pattern-either: - - pattern: "$AL.includes(...) \n" - - pattern: | - $AL.indexOf(...) !== -1 - - pattern: | - $AL.find(...) !== undefined - - pattern: | - $ALS.has(...) - - patterns: - - pattern: | - $RES.redirect("$DOM" + ...) - - metavariable-regex: - metavariable: $DOM - regex: (http(s)?:\/\/.*\/) - pattern-sinks: + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://owasp.org/Top10/A04_2021-Insecure_Design + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kinesis_stream#encryption_type + - https://docs.aws.amazon.com/streams/latest/dev/server-side-encryption.html + rule-origin-note: published from /src/aws-kinesis-stream-unencrypted.yml in None + subcategory: + - audit + technology: + - terraform + - aws + patterns: - pattern: | - $RES.redirect(...) - pattern-sources: - - patterns: - - pattern-inside: | - function ($REQ, $RES, ...) {...} - - focus-metavariable: $REQ - severity: ERROR - - id: rules_lgpl_javascript_redirect_rule-express-open-redirect2 + resource "aws_kinesis_stream" $ANYTHING { + ... + } + - pattern-not: | + resource "aws_kinesis_stream" $ANYTHING { + ... + encryption_type = "KMS" + ... + } + severity: WARNING + - id: terraform.aws.security.aws-kms-key-wildcard-principal.aws-kms-key-wildcard-principal languages: - - javascript - message: "Passing untrusted user input in `redirect()` can result in an open redirect\nvulnerability. This could be abused by malicious actors to trick users into \nbeing redirected to websites under their control to capture authentication\ninformation. \nTo prevent open redirect vulnerabilities:\n\n- Always validate and sanitize user inputs, especially URL parameters\n or query strings that may influence the flow of the application.\n- Use allowlists (lists of permitted URLs) to validate redirect targets \n against known, trusted URLs before performing the redirect.\n- Avoid directly using user input for redirecting. If unavoidable, ensure\n strict validation against an allowlist.\n\nFollowing is an example of secure validation against allowlist to prevent the vulnerability:\n ```\n // Define a list of explicitly allowed URLs for redirection\n const allowedUrls = [\n 'https://www.example.com/page1',\n 'https://www.example.com/page2',\n 'https://secure.example.com/page3'\n ];\n\n app.get('/redirect/:url', (req, res) => {\n const url = decodeURIComponent(req.params.url);\n const isAllowed = allowedUrls.includes(url);\n if (isAllowed) {\n // If the URL is allowed, proceed with the redirect\n res.location(url).status(302).end();\n } else {\n res.status(400).send('Invalid redirect URL');\n }\n });\n ```\n" + - hcl + message: Detected wildcard access granted in your KMS key. This means anyone with this policy can perform administrative actions over the keys. Instead, limit principals, actions and resources to what you need according to least privilege. metadata: category: security - cwe: CWE-601 + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: URL redirection to untrusted site 'open redirect' - mode: taint - pattern-sanitizers: - - pattern-either: - - patterns: + - A05:2021 - Security Misconfiguration + references: + - https://cwe.mitre.org/data/definitions/732.html + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern-inside: | + resource "aws_kms_key" $ANYTHING { + ... + } + - pattern: policy = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-not-inside: | + {..., "Effect": "Deny", ...} - pattern-either: - - pattern: "if($VALIDATION){\n ...\n} \n" - pattern: | - $A = $VALIDATION - ... - if($A){ - ... - } - - metavariable-pattern: - metavariable: $VALIDATION - pattern-either: - - pattern: "$AL.includes(...) \n" - - pattern: | - $AL.indexOf(...) !== -1 - - pattern: | - $AL.find(...) !== undefined - - pattern: | - $ALS.has(...) - pattern-sinks: - - pattern-either: - - patterns: - - pattern-not: | - $RES.$METHOD("=~/location/i", "=~/http(s)?:\/\/.*\//" + ...) - - pattern-not-inside: | - $VAR = "=~/http(s)?:\/\/.*\//" + ...; - ... - - pattern: | - $RES.$METHOD("=~/location/i", $VAR) - - metavariable-regex: - metavariable: $METHOD - regex: (header|set|append|setHeader) - - patterns: - - pattern-not-inside: | - $V = "=~/http(s)?:\/\/.*\//" + ...; - ... - - pattern-not: - patterns: - - pattern: "$RES.writeHead(..., { \n ..., \n location: $V,\n ...\n})\n" - - metavariable-pattern: - metavariable: $V - patterns: - - pattern: | - "=~/http(s)?:\/\/.*\//" + ... - - pattern: "$RES.writeHead(..., { \n ..., \n location: $V,\n ...\n })\n" - - focus-metavariable: $V - - patterns: - - pattern-not: | - $RES.location("=~/http(s)?:\/\/.*\//" + ...) - - pattern-not-inside: | - $VAR = "=~/http(s)?:\/\/.*\//" + ...; - ... - - pattern: | - $RES.location($VAR) - pattern-sources: - - patterns: - - pattern-inside: | - function ($REQ, $RES, ...) {...} - - focus-metavariable: $REQ + {..., "Principal": "*", "Action": "kms:*", "Resource": "*", ...} + - pattern: | + {..., "Principal": [..., "*", ...], "Action": "kms:*", "Resource": "*", ...} + - pattern: | + {..., "Principal": { "AWS": "*" }, "Action": "kms:*", "Resource": "*", ...} + - pattern: | + {..., "Principal": { "AWS": [..., "*", ...] }, "Action": "kms:*", "Resource": "*", ...} severity: ERROR - - id: rules_lgpl_javascript_ssrf_rule-node-ssrf + - id: terraform.aws.security.aws-kms-no-rotation.aws-kms-no-rotation languages: - - javascript - message: "This application allows user-controlled URLs to be passed directly to HTTP client libraries. \nThis can result in Server-Side Request Forgery (SSRF).\nSSRF refers to an attack where the attacker can abuse functionality on \nthe server to force it to make requests to other internal systems within your \ninfrastructure that are not directly exposed to the internet. \nThis allows the attacker to access internal resources they do not have direct access to.\n\nSome risks of SSRF are:\n\n- Access and manipulation of internal databases, APIs, or administrative panels\n- Ability to scan internal network architecture and services\n- Can be used to pivot attacks into the internal network\n- Circumvent network segregation and firewall rules\n\nTo avoid this, try using hardcoded HTTP request calls or a whitelisting object to \ncheck whether the user input is trying to access allowed resources or not.\n\nHere is an example:\n```\nvar whitelist = [\n \"https://example.com\", \n \"https://example.com/sample\"\n]\n\napp.get('/ssrf/node-ssrf/axios/safe/3', function (req, res) {\n if(whitelist.includes(req.query.url)){\n axios.get(url, {})\n .then(function (response) {\n console.log(response);\n })\n .catch(function (response) {\n console.log(response); \n })\n }\n});\n``` \nFor more information on SSRF see OWASP:\nhttps://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html\n" + - hcl + message: The AWS KMS has no rotation. Missing rotation can cause leaked key to be used by attackers. To fix this, set a `enable_key_rotation`. metadata: category: security - cwe: CWE-918 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: HIGH - shortDescription: Server-side request forgery (SSRF) - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: "if($VALIDATION){\n...\n} \n" - - pattern: | - $A = $VALIDATION - ... - if($A){ - ... - } - - metavariable-pattern: - metavariable: $VALIDATION - pattern-either: - - pattern: "$AL.includes(...) \n" - - pattern: | - $AL.indexOf(...) !== -1 - - pattern: | - $AL.find(...) !== undefined - - pattern: | - $ALS.has(...) - pattern-sinks: - - patterns: - - focus-metavariable: $REQ - - pattern-either: - - pattern-inside: | - $NEEDLE = require('needle'); - ... - - pattern-inside: | - import $NEEDLE from 'needle' - ... - - pattern-either: - - pattern: $NEEDLE('$VERB', $REQ, ...) - - pattern: $NEEDLE.$VERB($REQ, ...) - - metavariable-regex: - metavariable: $VERB - regex: ^(get|put|post|patch|delete|head)$ - - patterns: - - focus-metavariable: $REQ - - pattern-either: - - pattern-inside: | - $AXIOS = require('axios'); - ... - - pattern-inside: | - import $AXIOS from 'axios' - ... - - pattern-either: - - patterns: - - metavariable-regex: - metavariable: $URL - regex: ^(url|baseURL)$ - - pattern-either: - - pattern: | - $AXIOS({ ..., $URL: $REQ, ...}) - - pattern: | - $AXIOS.create({ ..., $URL: $REQ, ...}) - - patterns: - - pattern: $AXIOS.$VERB($REQ, ...) - - metavariable-regex: - metavariable: $VERB - regex: ^(get|put|post|patch|delete|head)$ - - patterns: - - pattern: axios($REQ) - - pattern-not-inside: axios({...}) - - pattern: | - axios.defaults.baseURL = $REQ - - patterns: - - focus-metavariable: $URL - - pattern-either: - - pattern-inside: | - {..., request, ... } = require('urllib'); - ... - - pattern-inside: | - import {..., request, ... } from 'urllib' - ... - - pattern: request($URL, ...) - - patterns: - - focus-metavariable: $URL - - pattern-either: - - pattern-inside: | - {..., HttpClient, ... } = require('urllib'); - ... - - pattern-inside: | - import {..., HttpClient, ... } from 'urllib' - ... - - pattern: | - $HTTPCLIENT = new HttpClient({ - allowH2: true, - }); - ... - $HTTPCLIENT.request($URL, ...) - - patterns: - - focus-metavariable: $URL - - pattern-either: - - pattern-inside: | - $URLLIIB = require('urllib'); - ... - - pattern-inside: | - import $URLLIIB from 'urllib' - ... - - pattern: $URLLIIB.request($URL, ...) - - patterns: - - pattern-either: - - pattern-inside: | - $SA = require('superagent'); - ... - - pattern-inside: | - import $SA from 'superagent' - ... - - patterns: - - pattern: $SA.$VERB(...) - - metavariable-regex: - metavariable: $VERB - regex: ^(get|put|post|patch|delete|head)$ - - patterns: - - pattern-either: - - patterns: - - pattern: fetch($REQ,...) - - focus-metavariable: $REQ - - pattern-not: fetch(new Request(...)) - - patterns: - - pattern: fetch(new Request($REQ,...)) - - focus-metavariable: $REQ - - pattern-not-inside: | - $REQUEST_OBJ = new Request(...) - ... - fetch($REQUEST_OBJ) - - patterns: - - pattern: new Request($REQ,...) - - focus-metavariable: $REQ - - pattern-inside: | - $REQUEST_OBJ = new Request($REQ,...) - ... - fetch($REQUEST_OBJ) - - patterns: - - focus-metavariable: $REQ - - pattern-either: - - pattern-inside: | - $HTTP = require('$PKG'); - ... - - pattern-inside: | - import $HTTP from $PKG - ... - - metavariable-regex: - metavariable: $PKG - regex: ^(http|https)$ - - metavariable-regex: - metavariable: $METHOD - regex: ^(get|request)$ - - pattern-either: - - patterns: - - pattern: $HTTP.$METHOD($REQ, ...) - - pattern-not-inside: | - $HTTP.$METHOD({...}, ...) - - pattern-not-inside: | - $OPTS = {...} - ... - $HTTP.$METHOD($OPTS, ...) - - pattern: | - $HTTP.$METHOD({..., hostname: $REQ}, ...) - - pattern: | - $OPTS = {..., hostname: $REQ, ...} - ... - $HTTP.$METHOD($OPTS, ...) - - patterns: - - focus-metavariable: $REQ - - pattern-either: - - pattern-inside: | - { ..., io, ... } = require('socket.io-client'); - ... - - pattern-inside: | - import { ..., io, ... } from 'socket.io-client' - ... - - pattern: io($REQ, ...) - - patterns: - - focus-metavariable: $HOST - - pattern-either: - - pattern-inside: | - $NET = require('net'); - ... - - pattern-inside: | - import $NET from 'net' - ... - - metavariable-regex: - metavariable: $METHOD - regex: ^(connect|createConnection)$ - - pattern-either: - - pattern: $NET.$METHOD($PORT, $HOST, ...) - - pattern: | - $NET.$METHOD({..., host: $HOST, ...}, ...) - - pattern: | - $OPTS = {..., host: $HOST, ...} - ... - $NET.$METHOD($OPTS, ...) - - pattern: | - $CLIENT = new $NET.Socket() - ... - $CLIENT.$METHOD($PORT, $HOST, ...) - - patterns: - - pattern-either: - - pattern-inside: | - $BENT = require('bent'); - ... - - pattern-inside: | - import $BENT from 'bent'; - ... - - pattern: $BENT(...) - - patterns: - - focus-metavariable: $REQ - - pattern-either: - - pattern-inside: | - $BENT = require('bent'); - ... - $MTD = $BENT(...) - - pattern-inside: | - import $BENT from 'bent'; - ... - $MTD = $BENT(...) - - pattern: $MTD($REQ, ...) - - patterns: - - pattern-either: - - pattern-inside: | - $BENT = require('bent'); - ... - $GETBENT = $BENT('$PKG') - ... - - pattern-inside: | - import $BENT from 'bent'; - ... - $GETBENT = $BENT('$PKG') - ... - - pattern: $GETBENT(...) - - metavariable-regex: - metavariable: $PKG - regex: ^(json|buffer)$ - - patterns: - - focus-metavariable: $REQ - - pattern-either: - - pattern-inside: | - import $GOT from 'got'; - ... - - pattern: $GOT.$VERB($REQ, ...) - - metavariable-regex: - metavariable: $VERB - regex: ^(get|put|post|patch|delete|head)$ - - patterns: - - focus-metavariable: $URL - - pattern-either: - - pattern-inside: | - $REQUEST = require('request'); - ... - - pattern-inside: | - import $REQUEST from 'request'; - ... - - pattern: $REQUEST($URL, ...) - pattern-sources: - - patterns: - - focus-metavariable: $REQ - - pattern: function ($REQ, $RES, ...) {...} - - patterns: - - focus-metavariable: $REQ - - pattern: function $FUNC($REQ, $RES, ...) {...} - severity: ERROR - - id: rules_lgpl_javascript_ssrf_rule-phantom-ssrf + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern-either: + - pattern: | + resource "aws_kms_key" $ANYTHING { + ... + enable_key_rotation = false + ... + } + - pattern: | + resource "aws_kms_key" $ANYTHING { + ... + customer_master_key_spec = "SYMMETRIC_DEFAULT" + enable_key_rotation = false + ... + } + - pattern: | + resource "aws_kms_key" $ANYTHING { + ... + } + - pattern-not-inside: | + resource "aws_kms_key" $ANYTHING { + ... + enable_key_rotation = true + ... + } + - pattern-not-inside: | + resource "aws_kms_key" $ANYTHING { + ... + customer_master_key_spec = "RSA_2096" + ... + } + severity: WARNING + - id: terraform.aws.security.aws-lambda-environment-credentials.aws-lambda-environment-credentials languages: - - javascript - message: | - 'If unverified user data can reach the `phantom` methods it can result in Server-Side Request Forgery vulnerabilities. - - ' + - hcl + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - cwe: CWE-918 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: HIGH + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Server-side request forgery (SSRF) + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + subcategory: + - vuln + technology: + - aws + - terraform + - secrets patterns: - pattern-inside: | - require('phantom') - ... - - pattern-either: - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + resource "$ANYTING" $ANYTHING { + ... + environment { + variables = { + ... + } + } + ... + } - pattern-either: - - pattern: $PAGE.open(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.setContent(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.open(<... $REQ.$BODY ...>,...) - - pattern: $PAGE.setContent(<... $REQ.$BODY ...>,...) - - pattern: $PAGE.openUrl(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.openUrl(<... $REQ.$BODY ...>,...) - - pattern: $PAGE.evaluateJavaScript(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.evaluateJavaScript(<... $REQ.$BODY ...>,...) - - pattern: $PAGE.property("content",<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.property("content",<... $REQ.$BODY ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.open(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.open(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.setContent(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.setContent(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.openUrl(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.openUrl(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluateJavaScript(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.evaluateJavaScript(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.property("content",<... $INPUT ...>,...) - - pattern: |- - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.property("content",<... $INPUT ...>,...) + - pattern-inside: | + AWS_ACCESS_KEY_ID = "$Y" + - pattern-regex: | + (?, ...) - - pattern: $PAGE.goto(<... $REQ.$BODY ...>, ...) - - pattern: $PAGE.setContent(<... $REQ.$QUERY.$FOO ...>, ...) - - pattern: $PAGE.setContent(<... $REQ.$BODY ...>, ...) - - pattern: $PAGE.evaluate(<... $REQ.$QUERY.$FOO ...>, ...) - - pattern: $PAGE.evaluate(<... $REQ.$BODY ...>, ...) - - pattern: $PAGE.evaluate($CODE,..., <... $REQ.$QUERY.$FOO ...>, ...) - - pattern: $PAGE.evaluate($CODE,..., <... $REQ.$BODY ...>, ...) - - pattern: $PAGE.evaluateHandle(<... $REQ.$QUERY.$FOO ...>, ...) - - pattern: $PAGE.evaluateHandle(<... $REQ.$BODY ...>, ...) - - pattern: $PAGE.evaluateHandle($CODE,..., <... $REQ.$QUERY.$FOO ...>, ...) - - pattern: $PAGE.evaluateHandle($CODE,..., <... $REQ.$BODY ...>, ...) - - pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY ...>, ...) - - pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY.$FOO ...>, ...) - - pattern: $CONTEXT.addInitScript(<... $REQ.$BODY ...>,...) - - pattern: $CONTEXT.addInitScript(<... $REQ.$BODY.$FOO ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.goto(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.goto(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.setContent(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.setContent(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluate($CODE,..., <... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.evaluate($CODE,..., <... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluate(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.evaluate(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluateHandle(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.evaluateHandle(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluateHandle($CODE,..., <... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.evaluateHandle($CODE,..., <... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluateOnNewDocument(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; + - pattern: | + resource "aws_lambda_permission" $ANYTHING { + ... + principal = "$PRINCIPAL" + ... + } + - pattern-not: | + resource "aws_lambda_permission" $ANYTHING { + ... + source_arn = ... + ... + } + - metavariable-regex: + metavariable: $PRINCIPAL + regex: .*[.]amazonaws[.]com$ + severity: ERROR + - id: terraform.aws.security.aws-lambda-x-ray-tracing-not-active.aws-lambda-x-ray-tracing-not-active + languages: + - hcl + message: The AWS Lambda function does not have active X-Ray tracing enabled. X-Ray tracing enables end-to-end debugging and analysis of all function activity. This makes it easier to trace the flow of logs and identify bottlenecks, slow downs and timeouts. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + likelihood: LOW + owasp: + - A09:2021 Security Logging and Monitoring Failures + references: + - https://cwe.mitre.org/data/definitions/778.html + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function#mode + - https://docs.aws.amazon.com/lambda/latest/dg/services-xray.html + subcategory: + - audit + technology: + - aws + - terraform + patterns: + - pattern: | + resource "aws_lambda_function" $ANYTHING { + ... + } + - pattern-not: | + resource "aws_lambda_function" $ANYTHING { + ... + tracing_config { ... - $PAGE.evaluateOnNewDocument(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; + mode = "Active" ... - $CONTEXT.addInitScript($INPUT,...) - severity: ERROR - - id: rules_lgpl_javascript_ssrf_rule-puppeteer-ssrf + } + ... + } + severity: INFO + - id: terraform.aws.security.aws-provider-static-credentials.aws-provider-static-credentials languages: - - javascript - message: | - If unverified user data can reach the `puppeteer` methods it can result in Server-Side Request Forgery vulnerabilities. + - hcl + message: A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module). metadata: category: security - cwe: CWE-918 + confidence: MEDIUM + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Server-side request forgery (SSRF) + - A07:2021 - Identification and Authentication Failures + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html + subcategory: + - vuln + technology: + - secrets + - aws + - terraform patterns: - pattern-inside: | - require('puppeteer') + provider "aws" { ... + secret_key = "$SECRET" + } + - focus-metavariable: $SECRET + severity: WARNING + - id: terraform.aws.security.aws-provisioner-exec.aws-provisioner-exec + languages: + - terraform + message: Provisioners are a tool of last resort and should be avoided where possible. Provisioner behavior cannot be mapped by Terraform as part of a plan, and execute arbitrary shell commands by design. + metadata: + category: security + confidence: HIGH + cwe: + - 'CWE-77: Improper Neutralization of Special Elements used in a Command (''Command Injection'')' + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + impact: MEDIUM + likelihood: HIGH + owasp: + - A03:2021 - Injection + - A01:2017 - Injection + references: + - https://developer.hashicorp.com/terraform/language/resources/provisioners/remote-exec + - https://developer.hashicorp.com/terraform/language/resources/provisioners/local-exec + subcategory: + - guardrail + technology: + - terraform + patterns: - pattern-either: - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: $PAGE.goto(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.goto(<... $REQ.$BODY ...>,...) - - pattern: $PAGE.setContent(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.setContent(<... $REQ.$BODY ...>,...) - - pattern: $PAGE.evaluate(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.evaluate(<... $REQ.$BODY ...>,...) - - pattern: $PAGE.evaluateHandle(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.evaluateHandle(<... $REQ.$BODY ...>,...) - - pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY ...>,...) - - pattern: $PAGE.evaluate($CODE,<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.evaluate($CODE,<... $REQ.$BODY ...>,...) - - pattern: $PAGE.evaluateHandle($CODE,<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.evaluateHandle($CODE,<... $REQ.$BODY ...>,...) - - pattern: $PAGE.evaluateOnNewDocument($CODE,<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PAGE.evaluateOnNewDocument($CODE,<... $REQ.$BODY ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.goto(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.goto(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.setContent(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.setContent(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluate(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.evaluate(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluateHandle(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.evaluateHandle(<... $INPUT ...>,...) - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluateOnNewDocument(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.evaluateOnNewDocument(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluate($CODE,<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.evaluate($CODE,<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluateHandle($CODE,<... $INPUT ...>,...) + provisioner "remote-exec" { + ... + } - pattern: | - $INPUT = <... $REQ.$BODY ...>; + provisioner "local-exec" { + ... + } + - pattern-inside: | + resource "aws_instance" "..." { ... - $PAGE.evaluateHandle($CODE,<... $INPUT ...>,...) + } + severity: WARNING + - id: terraform.aws.security.aws-rds-backup-no-retention.aws-rds-backup-no-retention + languages: + - hcl + message: The AWS RDS has no retention. Missing retention can cause losing important event information. To fix this, set a `backup_retention_period`. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern-either: - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PAGE.evaluateOnNewDocument($CODE,<... $INPUT ...>,...) + resource "aws_rds_cluster" $ANYTHING { + ... + backup_retention_period = 0 + ... + } - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PAGE.evaluateOnNewDocument($CODE,<... $INPUT ...>,...) - severity: ERROR - - id: rules_lgpl_javascript_ssrf_rule-wkhtmltoimage-ssrf + resource "aws_db_instance" $ANYTHING { + ... + backup_retention_period = 0 + ... + } + severity: WARNING + - id: terraform.aws.security.aws-sqs-queue-policy-wildcard-principal.aws-sqs-queue-policy-wildcard-principal languages: - - javascript - message: "This rule detects instances where user-controlled URLs are passed directly\nto the `generate` function of `wkhtmltoimage` library. This practice can\nlead to Server Side Request Forgery (SSRF) vulnerabilities, where an\nattacker can induce the server to make requests to arbitrary URLs. This\ncan potentially expose internal services within the network or lead to\ninformation disclosure.\n\nTo mitigate this vulnerability, ensure that URLs are safe and intended for \npublic access. Implementing allowlists for acceptable domains or schemes can \nsignificantly reduce the risk of SSRF. Additionally, consider using server-side \nproxy services that restrict the outgoing requests to trusted domains and \nresources.\n\nSecure Code Example:\n```\nconst wkhtmltoimage = require('wkhtmltoimage');\n\n// Define an allowlist of domains\nconst allowedDomains = ['example.com', 'trusted-source.com'];\n\napp.post('/generate-image', (req, res) => {\n const userInputUrl = req.body.url; \n const parsedUrl = new URL(userInputUrl);\n\n // Check if the domain is in the allowlist\n if (allowedDomains.includes(parsedUrl.hostname)) {\n wkhtmltoimage.generate(userInputUrl, { output: 'output.jpg' }, \n function (err, stream) {\n if (err) {\n return res.status(500).send('Error generating image');\n }\n // Send a success response or the image itself\n res.status(200).send('Image generated successfully');\n });\n } else {\n res.status(400).send('URL is not allowed due to security policies.');\n }\n});\n```\n" + - hcl + message: Wildcard used in your SQS queue policy principal. This grants access to all users, including anonymous users (public access). Unless you explicitly require anyone on the internet to be able to read or write to your queue, limit principals, actions and resources to what you need according to least privilege. metadata: category: security - cwe: CWE-918 + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A10:2021-Server-Side Request Forgery - security-severity: MEDIUM - shortDescription: Server-side request forgery (SSRF) - mode: taint - pattern-sanitizers: - - patterns: + - A05:2021 - Security Misconfiguration + references: + - https://cwe.mitre.org/data/definitions/732.html + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_policy + - https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-security-best-practices.html + rule-origin-note: published from /src/aws-sqs-queue-policy-wildcard-principal.yml in None + subcategory: + - vuln + technology: + - aws + - terraform + patterns: + - pattern-either: - pattern-inside: | - if($ALLOWED.includes($URL)){ + resource "aws_sqs_queue_policy" $ANYTHING { ... } - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $W = require('wkhtmltoimage') - ... - - pattern-inside: | - import $W from 'wkhtmltoimage' - ... + - pattern-inside: | + resource "aws_sqs_queue" $ANYTHING { + ... + } + - pattern-either: + - patterns: + - pattern: policy = "$JSONPOLICY" + - metavariable-pattern: + language: json + metavariable: $JSONPOLICY + patterns: + - pattern-not-inside: | + {..., "Effect": "Deny", ...} + - pattern-either: + - pattern: | + {..., "Principal": "*", ...} + - pattern: | + {..., "Principal": [..., "*", ...], ...} + - pattern: | + {..., "Principal": { "AWS": "*" }, ...} + - pattern: | + {..., "Principal": { "AWS": [..., "*", ...] }, ...} + - patterns: + - pattern-inside: policy = jsonencode(...) + - pattern-not-inside: | + {..., Effect = "Deny", ...} + - pattern-either: + - pattern: | + {..., Principal = "*", ...} + - pattern: | + {..., Principal = [..., "*", ...], ...} + - pattern: | + {..., Principal = { AWS = "*" }, ...} + - pattern: | + {..., Principal = { AWS = [..., "*", ...] }, ...} + severity: ERROR + - id: terraform.aws.security.aws-subnet-has-public-ip-address.aws-subnet-has-public-ip-address + languages: + - hcl + message: Resources in the AWS subnet are assigned a public IP address. Resources should not be exposed on the public internet, but should have access limited to consumers required for the function of your application. Set `map_public_ip_on_launch` to false so that resources are not publicly-accessible. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-284: Improper Access Control' + impact: MEDIUM + likelihood: LOW + owasp: + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control/ + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet#map_public_ip_on_launch + - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-public-addresses + subcategory: + - audit + technology: + - terraform + - aws + patterns: + - pattern-either: - pattern: | - $W.generate(...) - pattern-sources: - - patterns: + resource "aws_subnet" $ANYTHING { + ... + map_public_ip_on_launch = true + ... + } - pattern: | - function($REQ, $RES, ...){ + resource "aws_default_subnet" $ANYTHING { ... } - - focus-metavariable: $REQ + - pattern-not: | + resource "aws_default_subnet" $ANYTHING { + ... + map_public_ip_on_launch = false + ... + } severity: WARNING - - id: rules_lgpl_javascript_ssrf_rule-wkhtmltopdf-ssrf + - id: terraform.aws.security.insecure-load-balancer-tls-version.insecure-load-balancer-tls-version languages: - - javascript - message: | - User controlled URL reached to `wkhtmltopdf` can result in Server Side Request Forgery (SSRF). + - hcl + message: Detected an AWS load balancer with an insecure TLS version. TLS versions less than 1.2 are considered insecure because they can be broken. To fix this, set your `ssl_policy` to `"ELBSecurityPolicy-TLS13-1-2-2021-06"`, or include a default action to redirect to HTTPS. metadata: category: security - cwe: CWE-918 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Server-side request forgery (SSRF) + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.ietf.org/rfc/rfc5246.txt + subcategory: + - vuln + technology: + - terraform + - aws patterns: - - pattern-inside: | - require('wkhtmltopdf') - ... - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $INP = <... $REQ.$VAR ...>; - ... - wkhtmltopdf(<... $INP ...>, ...) - - pattern: | - $INP = <... $REQ.$VAR.$FOO ...>; - ... - wkhtmltopdf(<... $INP ...>, ...) - - pattern: | - wkhtmltopdf(<... $REQ.$VAR ...>, ...) - - pattern: | - wkhtmltopdf(<... $REQ.$VAR.$FOO ...>, ...) - severity: ERROR - - id: rules_lgpl_javascript_traversal_rule-admzip-path-overwrite + - patterns: + - pattern: ssl_policy = $ANYTHING + - pattern-not-regex: ELBSecurityPolicy-TLS13-1-[23]-[0-9-]+ + - pattern-not-regex: ELBSecurityPolicy-FS-1-2-[(Res)0-9-]+ + - patterns: + - pattern: protocol = "HTTP" + - pattern-not-inside: | + resource $ANYTHING $NAME { + ... + default_action { + ... + redirect { + ... + protocol = "HTTPS" + ... + } + ... + } + ... + } + - pattern-inside: | + resource $RESOURCE $X { + ... + } + - metavariable-pattern: + metavariable: $RESOURCE + patterns: + - pattern-either: + - pattern: | + "aws_lb_listener" + - pattern: | + "aws_alb_listener" + severity: WARNING + - id: terraform.aws.security.unrestricted-github-oidc-policy.unrestricted-github-oidc-policy languages: - - javascript - message: | - Insecure ZIP archive extraction using adm-zip can result in arbitrary path over write and can result in code injection. + - hcl + match: + all: + - inside: | + data "aws_iam_policy_document" $POLICY { + ... + } + - | + statement { + ... + principals { + ... + type = "Federated" + identifiers = [..., $IDENTIFIER, ...] + } + } + - not: | + statement { + ... + condition { + ... + variable = "token.actions.githubusercontent.com:sub" + } + } + where: + - metavariable: $IDENTIFIER + regex: .*oidc-provider/token\.actions\.githubusercontent\.com + message: '`$POLICY` is missing a `condition` block which scopes users of this policy to specific GitHub repositories. Without this, `$POLICY` is open to all users on GitHub. Add a `condition` block on the variable `token.actions.githubusercontent.com:sub` which scopes it to prevent this.' metadata: category: security - cwe: CWE-22 + confidence: MEDIUM + cwe: + - 'CWE-284: Improper Access Control' + impact: HIGH + likelihood: MEDIUM owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - patterns: - - pattern-inside: | - $X = require('adm-zip') - ... - - pattern-not: | - if ($FILENAME.indexOf('..')) - - pattern-not: | - $FS.createWriteStream($PATH.join(..., $PATH.basename($FILENAME, ...))) - - pattern-not: | - $FS.writeFile($PATH.join(..., $PATH.basename($FILENAME, ...))) - - pattern-not: | - $FS.writeFileSync($PATH.join(..., $PATH.basename($FILENAME, ...))) - - pattern-either: - - pattern: $ZIPENTZ.forEach(function $FUNC($ENTRY, ...) { $FS.createWriteStream(...) }, ...) - - pattern: $ZIPENTZ.forEach(function $FUNC($ENTRY, ...) { $FS.writeFile(...) }, ...) - - pattern: $ZIPENTZ.forEach(function $FUNC($ENTRY, ...) { $FS.writeFileSync(...) }, ...) + - A05:2017 - Sensitive Data Exposure + - A01:2021 - Broken Access Control + references: + - https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services#configuring-the-role-and-trust-policy + - https://dagrz.com/writing/aws-security/hacking-github-aws-oidc/ + subcategory: + - audit + technology: + - terraform + - aws severity: WARNING - - id: rules_lgpl_javascript_traversal_rule-express-lfr + - id: terraform.aws.security.wildcard-assume-role.wildcard-assume-role languages: - - javascript - message: "This application is using untrusted user input in express render() function.\nRendering templates with untrusted user input enables arbitrary file read \nvulnerabilities when using templating engines like Handlebars (hbs). \n\nAn attacker can craft malicious input that traverses the filesystem and exposes sensitive files. \nConsider sanitizing and validating all user input before passing it to render() to prevent arbitrary file reads. \n\nSample safe use of express.render function\n```\napp.get(\"/traversal/2\", async (req, res) => {\n var indexPath = \"index\";\n res.render(indexPath, { title: \"Index Page\" })\n});\n```\n\nFor more details see: \nhttps://owasp.org/www-community/attacks/Path_Traversal\n" + - hcl + message: 'Detected wildcard access granted to sts:AssumeRole. This means anyone with your AWS account ID and the name of the role can assume the role. Instead, limit to a specific identity in your account, like this: `arn:aws:iam:::root`.' metadata: category: security - cwe: CWE-23 + confidence: MEDIUM + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Relative path traversal - mode: taint - pattern-sinks: - - pattern: $RES.render(..., $VAR) - pattern-sources: - - patterns: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern: $REQ.$FUNC. ... - - metavariable-regex: - metavariable: $FUNC - regex: ^(body|params|query|cookies|hostname|subdomains|ip|ips|originalUrl|path)$ - severity: WARNING - - id: rules_lgpl_javascript_traversal_rule-express-lfr-warning + - A06:2017 - Security Misconfiguration + - A05:2021 - Security Misconfiguration + references: + - https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/ + subcategory: + - vuln + technology: + - aws + patterns: + - pattern-inside: | + resource "aws_iam_role" $NAME { + ... + } + - pattern: assume_role_policy = "$STATEMENT" + - metavariable-pattern: + language: json + metavariable: $STATEMENT + patterns: + - pattern-inside: | + {..., "Effect": "Allow", ..., "Action": "sts:AssumeRole", ...} + - pattern: | + "Principal": {..., "AWS": "*", ...} + severity: ERROR + - id: terraform.azure.security.appservice.appservice-authentication-enabled.appservice-authentication-enabled languages: - - javascript - message: | - Untrusted user input in express render() function can result in arbitrary file read if hbs templating is used. + - hcl + message: Enabling authentication ensures that all communications in the application are authenticated. The `auth_settings` block needs to be filled out with the appropriate auth backend settings metadata: category: security - cwe: CWE-23 + confidence: MEDIUM + cwe: + - 'CWE-287: Improper Authentication' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Relative path traversal + - A02:2017 - Broken Authentication + - A07:2021 - Identification and Authentication Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#auth_settings + subcategory: + - vuln + technology: + - terraform + - azure patterns: + - pattern: resource - pattern-not-inside: | - require('hbs') + resource "azurerm_app_service" "..." { ... - - pattern-inside: | - require('express') + auth_settings { + ... + enabled = true + ... + } ... + } - pattern-either: - - pattern: | - $INP = <... $REQ.$QUERY ...>; + - pattern-inside: | + resource "azurerm_app_service" "..." { ... - $RES.render($VIEW, <... $INP ...>) - - pattern: | - $INP = <... $REQ.$QUERY.$FOO ...>; + } + - pattern-inside: | + resource "azurerm_app_service" "..." { ... - $RES.render($VIEW, <... $INP ...>) - - pattern: $RES.render($VIEW, <... $REQ.$QUERY.$FOO ...>) - - pattern: $RES.render($VIEW, <... $REQ.$BODY ...>) - severity: WARNING - - id: rules_lgpl_javascript_traversal_rule-generic-path-traversal - languages: - - javascript - message: "This application is using untrusted user input with the readFile() and\nreadFileSync() functions. \nThis can lead to directory traversal attacks, as reading files with untrusted input enables arbitrary file access.\nAn attacker could craft malicious input that traverses the file system and exposes sensitive files. \nPlease consider sanitizing and validating all user input before passing it to readFile() or readFileSync() to prevent unwanted file reads.\nHere is an example of a safer usage in readFileAsync():\n```\napp.get('/foo', function (req, res) {\n var fileName = config.dirName + '/' + data;\n fs.readFileAsync(\"fileName\")\n .then(function (data) {\n res.download(fileName, downloadFileName);\n })\n })\n```\nFor more details see: \nhttps://owasp.org/www-community/attacks/Path_Traversal\n" - metadata: - category: security - cwe: CWE-23 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Relative path traversal - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $FS = require('fs') + auth_settings { ... - - pattern-inside: | - import $FS from 'fs' + enabled = false ... - - pattern-either: - - pattern: $FS.createReadStream(...) - - patterns: - - pattern: $FS.readFile($REQ, ...) - - focus-metavariable: $REQ - - patterns: - - pattern: $FS.readFileSync($REQ,...) - - focus-metavariable: $REQ - - patterns: - - pattern: $FS.readFileAsync($REQ,...) - - focus-metavariable: $REQ - pattern-sources: - - patterns: - - focus-metavariable: $REQ - - pattern: function ($REQ, $RES, ...) {...} - severity: WARNING - - id: rules_lgpl_javascript_traversal_rule-join-resolve-path-traversal + } + ... + } + severity: ERROR + - id: terraform.azure.security.appservice.appservice-enable-http2.appservice-enable-http2 languages: - - javascript - message: | - 'Path constructed with user input can result in Path Traversal. Ensure that user input does not reach `join()` or `resolve()`. ' + - hcl + message: Use the latest version of HTTP to ensure you are benefiting from security fixes. Add `http2_enabled = true` to your appservice resource block metadata: category: security - cwe: CWE-22 + confidence: MEDIUM + cwe: + - 'CWE-444: Inconsistent Interpretation of HTTP Requests (''HTTP Request/Response Smuggling'')' + impact: MEDIUM + likelihood: LOW owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + - A04:2021 - Insecure Design + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#http2_enabled + subcategory: + - vuln + technology: + - terraform + - azure patterns: - - pattern-inside: | - require('path') + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { ... - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: $PATH.join(...,<... $REQ.$BODY ...>,...) - - pattern: $PATH.join(...,<... $REQ.$QUERY.$FOO ...>,...) - - pattern: | - $VAR = <... $REQ.$BODY ...>; - ... - $PATH.join(...,<... $VAR ...>,...) - - pattern: | - $VAR = <... $REQ.$QUERY.$FOO ...>; - ... - $PATH.join(...,<... $VAR ...>,...) - - pattern: $PATH.resolve(...,<... $REQ.$BODY ...>,...) - - pattern: $PATH.resolve(...,<... $REQ.$QUERY.$FOO ...>,...) - - pattern: | - $VAR = <... $REQ.$BODY ...>; + site_config { ... - $PATH.resolve(...,<... $VAR ...>,...) - - pattern: |- - $VAR = <... $REQ.$QUERY.$FOO ...>; + http2_enabled = true ... - $PATH.resolve(...,<... $VAR ...>,...) - severity: WARNING - - id: rules_lgpl_javascript_traversal_rule-tar-path-overwrite - languages: - - javascript - message: | - Insecure TAR archive extraction can result in arbitrary path over write and can result in code injection. - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - patterns: - - pattern-inside: | - $X = require('tar-stream') + } ... - - pattern-not-inside: | - $Y.pipe($UNZIP.Parse(...)).on('entry', function $FUNC(...) { - ... - }, ...) - - pattern-inside: | - $EXTRACT.on('entry', function $FUNC(...) { - ... - }, ...) - - pattern-not: | - if ($FILENAME.indexOf('..')) - - pattern-not: | - $FS.createWriteStream($PATH.join(..., $PATH.basename($FILENAME, ...))) - - pattern-not: | - $FS.writeFile($PATH.join(..., $PATH.basename($FILENAME, ...))) - - pattern-not: | - $FS.writeFileSync($PATH.join(..., $PATH.basename($FILENAME, ...))) - - pattern-either: - - pattern: | - $FS.createWriteStream($FIL, ...) - - pattern: | - $FS.writeFile($FIL, ...) - - pattern: | - $FS.writeFileSync($FIL, ...) - severity: WARNING - - id: rules_lgpl_javascript_traversal_rule-zip-path-overwrite - languages: - - javascript - message: "This application is extracting ZIP archives without sanitizing paths or writing files to a dedicated extraction directory. \nThis allows attackers to overwrite sensitive files or inject malicious code by manipulating TAR archive contents.\n\nTo fix, sanitize all paths from ZIP archives before writing extracted files using path.basename and path.join.\n\nExample of extracting tar files safely:\n```\napp.get(\"/extract\", async (req, res) => {\n fs.createReadStream(zipPath)\n .pipe(unzipper.Parse())\n .on('entry', entry => {\n const directory = 'assets/tar/extracted/';\n const filename = entry.path;\n entry.pipe(fs.createWriteStream(path.join(directory, filename)));\n });\n});\n```\n\nWrite extracted files only to a dedicated extraction directory, not the global filesystem. Limit extracts to allowed file type.\n\nSee OWASP Path Traversal (https://owasp.org/www-community/attacks/Path_Traversal) and Unrestricted Upload of File with \nDangerous Type (https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload) for more details.\n" - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - patterns: + } - pattern-either: - pattern-inside: | - import $X from 'unzipper' + resource "azurerm_app_service" "..." { ... + } - pattern-inside: | - $X = require('unzipper') - ... - - pattern-inside: | - $Y.pipe($X.Parse(...)).on('entry', function $FUNC(...) { - ... - }, ...) - - pattern-not-inside: "if (<... $FILENAME.indexOf(...) ...>){ \n...\n}\n" - - pattern-not-inside: | - $BASE = $PATH.basename($FILENAME, ...) - ... - $JOIN = $PATH.join(..., $BASE) - ... - - pattern-not: | - $FS.$MTD($PATH.join(..., $PATH.basename($FILENAME, ...))) - - pattern: | - $FS.$MTD($FIL, ...) - - metavariable-regex: - metavariable: $MTD - regex: ^(writeFileSync|writeFile|createWriteStream)$ - severity: WARNING - - id: rules_lgpl_javascript_xml_rule-node-entity-expansion - languages: - - javascript - message: | - User controlled data in XML Parsers can result in XML Internal Entity Processing vulnerabilities like in DoS. - metadata: - category: security - cwe: CWE-776 - owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration - security-severity: CRITICAL - shortDescription: Improper restriction of recursive entity references in DTDs (XML Entity Expansion) - patterns: - - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $PARSER = new expat.Parser() - ... - $PARSER.write(..., <... $REQ.$QUERY ...>, ...) - - pattern: | - $PARSER = new expat.Parser() - ... - $PARSER.write(..., <... $REQ.$QUERY.$FOO ...>, ...) - - pattern: | - $PARSER = new expat.Parser() + resource "azurerm_app_service" "..." { ... - $PARSER.write(..., <... $REQ.$QUERY.$FOO.$FILE ...>, ...) - severity: ERROR - - id: rules_lgpl_javascript_xml_rule-node-xpath-injection - languages: - - javascript - message: "Passing untrusted user input in `xpath.parse()` can result in XPATH injection\nvulnerability. This could be abused by malicious actors to execute expressions on\non XML files to capture unauthorized information.\nTo prevent XPATH injection vulnerabilities:\n\n- Always validate and sanitize user inputs, especially parameters\nor query strings that may influence the flow of the application.\n- Avoid directly using user input for parsing. If unavoidable, ensure\nstrict validation against an allowlist. \n- Use allowlists (lists of permitted expressions) to validate user input \nagainst known, trusted expressions before performing the parse.\n\n\nFollowing is an example of secure validation against allowlist to prevent the vulnerability:\n```\n// Define a list of explicitly allowed expressions for parsing\nconst allowedExpr = [\n 'expression1',\n 'expression2',\n 'expression3'\n];\n\napp.get('/xml/xpath/1', (req, res) => {\n var expression = req.params.exp;\n var isAllowed = allowedExpr.includes(expression);\n let xml_string = fs.readFileSync(\"books.xml\", \"utf8\");\n var doc = new dom().parseFromString(xml_string, 'text/xml');\n if (isAllowed) {\n // If the expression is allowed, proceed with the parsing\n var evaluator = xpath.parse(\"//\"+expression);\n var nodes = evaluator.select({ node: doc }); \n res.send(nodes[0].firstChild.data);\n } else {\n res.status(400).send('Invalid expression');\n }\n});\n```\n" - metadata: - category: security - cwe: CWE-643 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of data within XPath expressions (XPath Injection) - mode: taint - pattern-sanitizers: - - patterns: - - pattern-either: - - pattern: "if($VALIDATION){\n...\n$XPATH.parse($REQ, ...) \n...\n} \n" - - pattern: "$A = $VALIDATION\n...\nif($A){\n...\n$XPATH.parse($REQ, ...) \n...\n}\n" - - metavariable-pattern: - metavariable: $VALIDATION - pattern-either: - - pattern: "$AL.includes(...) \n" - - pattern: | - $AL.indexOf(...) !== -1 - - pattern: | - $AL.find(...) !== undefined - - pattern: | - $ALS.has(...) - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: | - $XPATH = require('xpath') - ... - - pattern-inside: | - import { $XPATH } from 'xpath' + site_config { ... - - pattern-inside: | - import { $K as $XPATH } from 'xpath' + http2_enabled = false ... - - pattern: "$XPATH.parse($REQ, ...) \n" - - focus-metavariable: $REQ - pattern-sources: - - patterns: - - pattern-either: - - pattern: | - function ($REQ, $RES, ...) {...} - - pattern: | - function $FUNC($REQ, $RES, ...) {...} - - focus-metavariable: $REQ - severity: ERROR - - id: rules_lgpl_javascript_xml_rule-node-xxe + } + ... + } + severity: INFO + - id: terraform.azure.security.appservice.appservice-enable-https-only.appservice-enable-https-only languages: - - javascript - message: | - User controlled data in XML parsers can result in XML External or Internal Entity (XXE) Processing vulnerabilities + - hcl + message: By default, clients can connect to App Service by using both HTTP or HTTPS. HTTP should be disabled enabling the HTTPS Only setting. metadata: category: security - cwe: CWE-611 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration - security-severity: CRITICAL - shortDescription: Improper restriction of XML external entity reference + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#https_only + - https://docs.microsoft.com/en-us/azure/app-service/configure-ssl-bindings#enforce-https + subcategory: + - vuln + technology: + - terraform + - azure patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + https_only = true + ... + } - pattern-either: - - pattern-inside: function ($REQ, $RES, ...) {...} - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) - - pattern-either: - - pattern: | - $LIBXML.parseXmlString(..., <... $REQ.$QUERY.$VAR.$FILE ...>, ...) - - pattern: | - $LIBXML.parseXmlString(..., <... $REQ.$QUERY.$VAR ...>, ...) - - pattern: | - $LIBXML.parseXmlString(..., <... $REQ.$QUERY ...>, ...) - - pattern: | - $FOO = <... $REQ.$QUERY.$VAR.$FILE ...>; ... $LIBXML.parseXmlString(..., <... $FOO ...>, ...) - - pattern: | - $FOO = <... $REQ.$QUERY.$VAR ...>; ... $LIBXML.parseXmlString(..., <... $FOO ...>, ...) - - pattern: | - $FOO = <... $REQ.$QUERY ...>; ... $LIBXML.parseXmlString(..., <... $FOO ...>, ...) - - pattern: | - $LIBXML.parseXml(..., <... $REQ.$QUERY.$VAR.$FILE ...>, ...) - - pattern: | - $LIBXML.parseXml(..., <... $REQ.$QUERY.$VAR ...>, ...) - - pattern: | - $LIBXML.parseXml(..., <... $REQ.$QUERY ...>, ...) - - pattern: | - $FOO = <... $REQ.$QUERY.$VAR.$FILE ...>; ... $LIBXML.parseXml(..., <... $FOO ...>, ...) - - pattern: | - $FOO = <... $REQ.$QUERY.$VAR ...>; ... $LIBXML.parseXml(..., <... $FOO ...>, ...) - - pattern: | - $FOO = <... $REQ.$QUERY ...>; - ... - $LIBXML.parseXml(..., <... $FOO ...>, ...) - - pattern: | - $PARSER = new libxmljs.SaxParser() - ... - $PARSER.parseString(..., <... $REQ.$QUERY ...>, ...) - - pattern: | - $PARSER = new libxmljs.SaxParser() - ... - $PARSER.parseString(..., <... $REQ.$QUERY.$BAR ...>, ...) - - pattern: | - $PARSER = new libxmljs.SaxParser() - ... - $PARSER.parseString(..., <... $REQ.$QUERY.$BAR.$FILE ...>, ...) - - pattern: | - $PARSER = new libxmljs.SaxPushParser() - ... - $PARSER.push(..., <... $REQ.$QUERY ...>, ...) - - pattern: | - $PARSER = new libxmljs.SaxPushParser() - ... - $PARSER.push(..., <... $REQ.$QUERY.$FOO ...> , ...) - - pattern: | - $PARSER = new libxmljs.SaxPushParser() - ... - $PARSER.push(..., <... $REQ.$QUERY.$FOO.$FILE ...> , ...) - - pattern: | - $PARSER = new libxmljs.SaxParser() - ... - $FOO = <... $REQ.$QUERY ...>; - ... - $PARSER.parseString(..., <... $FOO ...>, ...) - - pattern: | - $PARSER = new libxmljs.SaxParser() - ... - $FOO = <... $REQ.$QUERY.$BAR ...>; - ... - $PARSER.parseString(..., <... $FOO ...>, ...) - - pattern: | - $PARSER = new libxmljs.SaxParser() - ... - $FOO = <... $REQ.$QUERY.$BAR.$FILE ...>; - ... - $PARSER.parseString(..., <... $FOO ...>, ...) - - pattern: | - $PARSER = new libxmljs.SaxPushParser() - ... - $FOO = <... $REQ.$QUERY ...>; - ... - $PARSER.push(..., <... $FOO ...>, ...) - - pattern: | - $PARSER = new libxmljs.SaxPushParser() - ... - $FOO = <... $REQ.$QUERY.$BAR ...>; + - pattern-inside: | + resource "azurerm_app_service" "..." { ... - $PARSER.push(..., <... $FOO ...> , ...) - - pattern: | - $PARSER = new libxmljs.SaxPushParser() + } + - pattern-inside: | + resource "azurerm_app_service" "..." { ... - $FOO = <... $REQ.$QUERY.$BAR.$FILE ...>; + https_only = false ... - $PARSER.push(..., <... $FOO ...> , ...) + } severity: ERROR - - id: rules_lgpl_javascript_xml_rule-xxe-expat + - id: terraform.azure.security.appservice.appservice-require-client-cert.appservice-require-client-cert languages: - - javascript - message: | - Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities. + - hcl + message: Detected an AppService that was not configured to use a client certificate. Add `client_cert_enabled = true` in your resource block. metadata: category: security - cwe: CWE-611 + confidence: MEDIUM + cwe: + - 'CWE-295: Improper Certificate Validation' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A4:2017-XML External Entities (XXE) - - A05:2021-Security Misconfiguration - security-severity: CRITICAL - shortDescription: Improper restriction of XML external entity reference + - A03:2017 - Sensitive Data Exposure + - A07:2021 - Identification and Authentication Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#client_cert_enabled + subcategory: + - vuln + technology: + - terraform + - azure patterns: - - pattern-inside: | - require('node-expat') + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { ... - - pattern-either: - - pattern-inside: function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...} - - pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...}; - - pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...}) + client_cert_enabled = true + ... + } - pattern-either: - pattern-inside: | - $PARSER = new $EXPAT.Parser(...) + resource "azurerm_app_service" "..." { ... + } - pattern-inside: | - $PARSER = new Parser(...) - ... - - pattern-either: - - pattern: $PARSER.parse(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PARSER.parse(<... $REQ.$BODY ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; - ... - $PARSER.parse(<... $INPUT ...>,...) - - pattern: | - $INPUT = <... $REQ.$BODY ...>; - ... - $PARSER.parse(<... $INPUT ...>,...) - - pattern: $PARSER.write(<... $REQ.$QUERY.$FOO ...>,...) - - pattern: $PARSER.write(<... $REQ.$BODY ...>,...) - - pattern: | - $INPUT = <... $REQ.$QUERY.$FOO ...>; + resource "azurerm_app_service" "..." { ... - $PARSER.write(<... $INPUT ...>,...) - - pattern: |- - $INPUT = <... $REQ.$BODY ...>; + client_cert_enabled = false ... - $PARSER.write(<... $INPUT ...>,...) - severity: ERROR - - id: rules_lgpl_javascript_xss_rule-express-xss - languages: - - javascript - message: "This application accepts user input directly from the client side without validation. \nThis could lead to Cross Site Scripting (XSS) if the input contains malicious script code and \nthe application server does not properly escape or sanitize the output. \nConsider encoding input data before sending it to the client side. \n\n```\n// safe method of sending user input data\nrouter.get('/safe/1', (req, res) => {\n var name = encodeURI(req.query.name); \n res.send(name);\n})\n```\n\nXSS is an attack that exploits a web application or system to treat user input as markup or script code. \nIt is important to encode the data depending on the specific context in which it is used. \n" - metadata: - category: security - cwe: CWE-79 - owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - mode: taint - options: - taint_unify_mvars: true - pattern-propagators: - - from: $IN - pattern: $ARR.push($IN) - to: $ARR - pattern-sanitizers: - - pattern: encodeURI(...) - - pattern: encodeURIComponent(...) - pattern-sinks: - - patterns: - - focus-metavariable: $INPUT - - pattern-either: - - pattern: $RES. ... .send($INPUT) - - pattern: $RES. ... .write($INPUT) - pattern-sources: - - patterns: - - patterns: - - metavariable-regex: - metavariable: $LIB - regex: (?Handlebars safe string\" + Handlebars.escapeExpression(req.query.message))\n res.send(returnObj.string)\n```\n" + - hcl + message: Detected an AppService that was not configured to use TLS 1.2. Add `site_config.min_tls_version = "1.2"` in your resource block. metadata: category: security - cwe: CWE-79 + confidence: HIGH + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation (Cross-site Scripting) - mode: taint - pattern-sanitizers: - - pattern-either: - - patterns: - - pattern-inside: | - $HB = require('handlebars') - ... - - pattern: $HB.escapeExpression(...) - - patterns: - - pattern-inside: | - import $HB from "handlebars"; - ... - - pattern: $HB.escapeExpression(...) - pattern-sinks: - - pattern-either: - - patterns: - - pattern-inside: | - $HB = require('handlebars') - ... - - pattern: new $HB.SafeString(...) - - patterns: - - pattern-inside: | - import $HB from "handlebars"; - ... - - pattern: new $HB.SafeString(...) - pattern-sources: - - patterns: - - focus-metavariable: $REQ - - pattern: function ($REQ, $RES, ...) {...} - severity: WARNING - - id: rules_lgpl_javascript_xss_rule-squirrelly-autoescape + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#min_tls_version + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: min_tls_version = $ANYTHING + - pattern-inside: | + resource "azurerm_app_service" "$NAME" { + ... + } + - pattern-not-inside: min_tls_version = "1.2" + severity: ERROR + - id: terraform.azure.security.appservice.azure-appservice-detailed-errormessages-enabled.azure-appservice-detailed-errormessages-enabled languages: - - javascript - message: "This application is rendering HTML with vulnerable \nconfigurations by setting Sqrl.autoEscaping(false) in squirrelly.\n\nThis could lead to Cross Site Scripting (XSS) if the input is malicious \nscript code and the application server is not properly validating the output.\n\n```\n// safe use of squirrelly render\nvar myTemplate = \"

    My Message is: {{message}}

    \"\nSqrl.Render(myTemplate, {message: req.query.message})\n```\n\nXSS is an attack that exploits a web application or system to treat user input as markup or script code. \nIt is important to encode the data depending on the specific context it is used in.\n\nBy default, squirrelly autoEscaping(true) escapes input values to prevent XSS attacks. \nConsider using squirrelly with default autoEscaping settings.\n" + - hcl + message: Ensure that App service enables detailed error messages metadata: category: security - cwe: CWE-79 + confidence: MEDIUM + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + likelihood: LOW owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') - pattern-either: - - patterns: - - pattern-inside: | - $SQLY = require('squirrelly') - ... - - pattern: $SQLY.autoEscaping(false) - - patterns: - - pattern-inside: | - import $SQLY from 'squirrelly'; - ... - - pattern: $SQLY.autoEscaping(false) + - A10:2017 - Insufficient Logging & Monitoring + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + logs { + ... + detailed_error_messages_enabled = true + ... + } + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } severity: WARNING - - id: rules_lgpl_javascript_xss_rule-xss-disable-mustache-escape + - id: terraform.azure.security.appservice.azure-appservice-https-only.azure-appservice-https-only languages: - - javascript - message: | - Markup escaping disabled. This can be used with some template engines to escape disabling of HTML entities, which can lead to XSS attacks. + - hcl + message: Ensure web app redirects all HTTP traffic to HTTPS in Azure App Service Slot metadata: category: security - cwe: CWE-116 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: LOW owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper encoding or escaping of output - pattern: $OBJ.escapeMarkup = false + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln + technology: + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_app_service" "..." { + ... + https_only = true + ... + } + - pattern-inside: | + resource "azurerm_app_service" "..." { + ... + } severity: WARNING - - id: rules_lgpl_javascript_xss_rule-xss-serialize-javascript + - id: terraform.azure.security.appservice.azure-appservice-min-tls-version.azure-appservice-min-tls-version languages: - - javascript - message: "This application is serializing Javascript objects with vulnerable \nconfigurations by setting `{unsafe: true}` in serialize-javascript. \n\nThis could lead to Cross Site Scripting (XSS) if the input was malicious \nscript code and the application server is not properly validating the output.\n\n```\n// safe use of serialize-javascript\nconst jsObj = serialize({\n foo: htmlResponse\n }\n);\n```\n\nXSS is an attack which exploits a web application or system to treat user input as markup or script code. \nIt is important to encode the data depending on the specific context it is used in. \n\nBy default, serialize-javascript encodes input values to prevent XSS attacks. \nConsider using serialize-javascript with default settings or set `{unsafe: false}` to encode\ninput data.\n" + - hcl + message: Ensure web app is using the latest version of TLS encryption metadata: category: security - cwe: CWE-80 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper neutralization of script-related HTML tags in a web page (basic XSS) - pattern-either: - - patterns: - - pattern-inside: | - $S = require('serialize-javascript') - ... - - pattern: '$S(..., {...,unsafe: true,...})' - - patterns: - - pattern-inside: | - import serialize from "serialize-javascript"; - ... - - pattern: 'serialize(..., {...,unsafe: true,...})' + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - audit + technology: + - terraform + - azure + patterns: + - pattern-either: + - pattern: | + "1.0" + - pattern: | + "1.1" + - pattern-inside: min_tls_version = ... + - pattern-inside: | + $RESOURCE "azurerm_app_service" "..." { + ... + } severity: WARNING - - id: kotlin_cookie_rule-CookieHTTPOnly + - id: terraform.azure.security.azure-key-no-expiration-date.azure-key-no-expiration-date languages: - - kotlin - message: | - A new cookie is created without the HttpOnly flag set. The HttpOnly flag is a directive to the - browser to make sure that the cookie can not be red by malicious script. When a user is the - target of a "Cross-Site Scripting", the attacker would benefit greatly from getting the session - id for example. + - hcl + message: Ensure that the expiration date is set on all keys metadata: category: security - cwe: CWE-1004 + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: LOW + likelihood: LOW owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Sensitive cookie without 'HttpOnly' flag + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln technology: - - kotlin + - terraform + - azure patterns: - - pattern: | - $C = $X.servlet.http.Cookie(..., ...) - ...; - ($RESP: $X.servlet.http.HttpServletResponse).addCookie($C) + - pattern: resource - pattern-not-inside: | - $C = $X.servlet.http.Cookie(..., ...) + resource "azurerm_key_vault_key" "..." { + ... + expiration_date = "..." + ... + } + - pattern-inside: | + resource "azurerm_key_vault_key" "..." { ... - $C.setHttpOnly(true) - ...; - ($RESP: $X.servlet.http.HttpServletResponse).addCookie($C) + } severity: WARNING - - id: kotlin_cookie_rule-CookieInsecure + - id: terraform.azure.security.azure-mssql-service-mintls-version.azure-mssql-service-mintls-version languages: - - kotlin - message: | - "A new cookie is created without the Secure flag set. The Secure flag is a - directive to the browser to make sure that the cookie is not sent for insecure communication - (http://)" + - hcl + message: Ensure MSSQL is using the latest version of TLS encryption metadata: category: security - cwe: CWE-614 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Sensitive cookie in HTTPS session without 'Secure' attribute + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln technology: - - kotlin + - terraform + - azure patterns: - - pattern: | - $C = $X.servlet.http.Cookie(..., ...) - ...; - ($RESP: $X.servlet.http.HttpServletResponse).addCookie($C) - - pattern-not-inside: | - $C = $X.servlet.http.Cookie(..., ...) + - pattern-either: + - pattern: | + "1.0" + - pattern: | + "1.1" + - pattern-inside: minimum_tls_version = ... + - pattern-inside: | + $RESOURCE "azurerm_mssql_server" "..." { ... - $C.setSecure(true) - ...; - ($RESP: $X.servlet.http.HttpServletResponse).addCookie($C) + } severity: WARNING - - id: kotlin_cookie_rule-HttpResponseSplitting + - id: terraform.azure.security.azure-mysql-encryption-enabled.azure-mysql-encryption-enabled languages: - - kotlin - message: | - When an HTTP request contains unexpected CR and LF characters, the server may respond with an - output stream that is interpreted as two different HTTP responses (instead of one). An attacker - can control the second response and mount attacks such as cross-site scripting and cache - poisoning attacks. + - hcl + message: Ensure that MySQL server enables infrastructure encryption metadata: category: security - cwe: CWE-113 + confidence: MEDIUM + cwe: + - 'CWE-320: CWE CATEGORY: Key Management Errors' + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') + - A03:2017 - Sensitive Data Exposure + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln technology: - - kotlin - mode: taint - pattern-sanitizers: - - patterns: - - metavariable-pattern: - metavariable: $S0 - pattern-either: - - pattern: '...' - - pattern: '""' - - metavariable-pattern: - metavariable: $PATTERN - patterns: - - pattern: '...' - - pattern-regex: .*\[\]?(?=[^]]*\\r)(?=[^]]*\\n)[^]]*\]\+ - - pattern-inside: | - $STR.replace($PATTERN, $S0) - ... - - pattern: org.apache.commons.text.StringEscapeUtils.escapeJava(...) - pattern-sinks: - - pattern: javax.servlet.http.Cookie("$KEY", ...) - - patterns: - - pattern-inside: | - $C = javax.servlet.http.Cookie("$KEY", ...) - ... - - pattern: $C.setValue(...) - pattern-sources: - - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameter(...)' - - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameterNames()' - - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameterValues(...)' - - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameterMap()' - - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getHeader(...)' - - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getPathInfo()' + - terraform + - azure + patterns: + - pattern: resource + - pattern-inside: | + resource "azurerm_mysql_server" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_mysql_server" "..." { + ... + infrastructure_encryption_enabled = true + ... + } severity: WARNING - - id: kotlin_cookie_rule-RequestParamToHeader + - id: terraform.azure.security.azure-mysql-mintls-version.azure-mysql-mintls-version languages: - - kotlin - message: | - This code directly writes an HTTP parameter to an HTTP header, which allows for a HTTP - response splitting vulnerability. See http://en.wikipedia.org/wiki/HTTP_response_splitting for - more information. + - hcl + message: Ensure MySQL is using the latest version of TLS encryption metadata: category: security - cwe: CWE-113 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln technology: - - kotlin - mode: taint - pattern-sanitizers: - - patterns: - - metavariable-pattern: - metavariable: $S0 - pattern-either: - - pattern: '...' - - pattern: '""' - - metavariable-pattern: - metavariable: $PATTERN - patterns: - - pattern: '...' - - pattern-regex: .*\[\]?(?=[^]]*\\r)(?=[^]]*\\n)[^]]*\]\+ - - pattern-inside: | - $STR.replace($PATTERN, $S0); - ... - - pattern: org.apache.commons.text.StringEscapeUtils.unescapeJava(...); - pattern-sinks: - - pattern: '($RES: $X.servlet.http.HttpServletResponse).setHeader("$KEY", ...);' - - pattern: '($RES: $X.servlet.http.HttpServletResponse).addHeader("$KEY", ...);' - - pattern: '($WRP: $X.servlet.http.HttpServletResponseWrapper).setHeader("$KEY", ...);' - - pattern: '($WRP: $X.servlet.http.HttpServletResponseWrapper).addHeader("$KEY", ...);' - pattern-sources: - - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameter(...);' - - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameterNames();' - - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameterValues(...);' - - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getParameterMap();' - - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getHeader(...);' - - pattern: '($REQ: $X.servlet.http.HttpServletRequest).getPathInfo();' - severity: ERROR - - id: kotlin_cors_rule-PermissiveCORSInjection + - terraform + - azure + patterns: + - pattern-either: + - pattern: | + "TLS1_0" + - pattern: | + "TLS1_1" + - pattern-inside: ssl_minimal_tls_version_enforced = ... + - pattern-inside: | + $RESOURCE "azurerm_mysql_server" "..." { + ... + } + severity: WARNING + - id: terraform.azure.security.keyvault.keyvault-ensure-key-expires.keyvault-ensure-key-expires languages: - - kotlin - message: | - Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for - JavaScript to access the contents of a Web page, both the JavaScript and the Web page must - originate from the same domain. Without the Same Origin Policy, a malicious website could serve - up JavaScript that loads sensitive information from other websites using a client's - credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible - for JavaScript to access data across domains if a new HTTP header called - Access-Control-Allow-Origin is defined. With this header, a Web server defines which other - domains are allowed to access its domain using cross-origin requests. However, caution should - be taken when defining the header because an overly permissive CORS policy will allow a - malicious application to communicate with the victim application in an inappropriate way, - leading to spoofing, data theft, relay and other attacks. + - hcl + message: Ensure that the expiration date is set on all keys metadata: category: security - cwe: CWE-942 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Permissive cross-domain policy with untrusted domains + confidence: MEDIUM + cwe: + - 'CWE-262: Not Using Password Aging' + impact: MEDIUM + likelihood: LOW + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key#expiration_date + - https://docs.microsoft.com/en-us/powershell/module/az.keyvault/update-azkeyvaultkey?view=azps-5.8.0#example-1--modify-a-key-to-enable-it--and-set-the-expiration-date-and-tags + subcategory: + - vuln technology: - - kotlin - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: '($RES: HttpServletResponse).setHeader("$HEADER", ...)' - - pattern: '($RES: HttpServletResponse).addHeader("$HEADER", ...)' - - metavariable-regex: - metavariable: $HEADER - regex: (?i)(Access-Control-Allow-Origin) - pattern-sources: - - pattern: '($REQ: HttpServletRequest).getParameter(...)' - - pattern: '($REQ: HttpServletRequest).getHeader(...)' - - pattern: '($REQ: HttpServletRequest).getPathInfo()' - - pattern: '($REQ: HttpServletRequest).getQueryString()' - - pattern: '($REQ: HttpServletRequest).getAttribute(...)' - - pattern: '($REQ: HttpServletRequest).getSession().getAttribute(...)' - - pattern: '($REQ: HttpServletRequest).getServletContext().getAttribute(...)' - - pattern: '($REQ: HttpServletRequest).getParameterValues(...)' - - pattern: '($REQ: HttpServletRequest).getParameterNames()' - - pattern: '($REQ: HttpServletRequest).getParameterMap()' - severity: ERROR - - id: kotlin_crypto_rule-BlowfishKeySize + - terraform + - azure + patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault_key" "..." { + ... + expiration_date = "..." + ... + } + - pattern-inside: | + resource "azurerm_key_vault_key" "..." { + ... + } + severity: INFO + - id: terraform.azure.security.keyvault.keyvault-ensure-secret-expires.keyvault-ensure-secret-expires languages: - - kotlin - message: | - A small key size makes the ciphertext vulnerable to brute force attacks. At least 128 bits of - entropy should be used when generating the key if use of Blowfish is required. + - hcl + message: Ensure that the expiration date is set on all secrets metadata: category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Inadequate encryption strength + confidence: MEDIUM + cwe: + - 'CWE-262: Not Using Password Aging' + impact: MEDIUM + likelihood: LOW + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret#expiration_date + - https://docs.microsoft.com/en-us/azure/key-vault/secrets/about-secrets + subcategory: + - vuln technology: - - kotlin + - terraform + - azure patterns: + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault_secret" "..." { + ... + expiration_date = "..." + ... + } - pattern-inside: | - $KEYGEN = javax.crypto.KeyGenerator.getInstance("Blowfish", ...); + resource "azurerm_key_vault_secret" "..." { ... - $KEYGEN.init($KEY_SIZE); - - metavariable-comparison: - comparison: $KEY_SIZE < 128 - metavariable: $KEY_SIZE - severity: WARNING - - id: kotlin_crypto_rule-CipherDESInsecure + } + severity: INFO + - id: terraform.azure.security.keyvault.keyvault-purge-enabled.keyvault-purge-enabled languages: - - kotlin - message: | - DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage - of AES block ciphers instead of DES. + - hcl + message: Key vault should have purge protection enabled metadata: category: security - cwe: CWE-326 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Inadequate encryption strength + confidence: MEDIUM + cwe: + - 'CWE-693: Protection Mechanism Failure' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault#purge_protection_enabled + - https://docs.microsoft.com/en-us/azure/key-vault/general/soft-delete-overview#purge-protection + subcategory: + - vuln technology: - - kotlin + - terraform + - azure patterns: - - pattern-inside: javax.crypto.Cipher.getInstance($TRANSFORMATION, ...) - - metavariable-regex: - metavariable: $TRANSFORMATION - regex: ^"DES(/|"$) + - pattern: resource + - pattern-not-inside: | + resource "azurerm_key_vault" "..." { + ... + purge_protection_enabled = true + ... + } + - pattern-either: + - pattern-inside: | + resource "azurerm_key_vault" "..." { + ... + } + - pattern-inside: | + resource "azurerm_key_vault" "..." { + ... + purge_protection_enabled = false + ... + } severity: WARNING - - id: kotlin_crypto_rule-CipherDESedeInsecure + - id: terraform.azure.security.storage.storage-enforce-https.storage-enforce-https languages: - - kotlin - message: | - Triple DES (also known as 3DES or DESede) is considered strong ciphers for modern - applications. NIST recommends the usage of AES block ciphers instead of 3DES. + - hcl + message: Detected a Storage that was not configured to deny action by default. Add `enable_https_traffic_only = true` in your resource block. metadata: category: security - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Use of a broken or risky cryptographic algorithm + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#enable_https_traffic_only + - https://docs.microsoft.com/en-us/azure/storage/common/storage-require-secure-transfer + subcategory: + - vuln technology: - - kotlin + - terraform + - azure patterns: - - pattern-inside: javax.crypto.Cipher.getInstance($ALG, ...) - - metavariable-regex: - metavariable: $ALG - regex: (?i)^"DESede(/|"$) + - pattern-not-inside: | + resource "azurerm_storage_account" "..." { + ... + enable_https_traffic_only = true + ... + } + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + enable_https_traffic_only = false + ... + } severity: WARNING - - id: kotlin_crypto_rule-CipherECBMode - languages: - - kotlin - message: | - An authentication cipher mode which provides better confidentiality of the encrypted data - should be used instead of Electronic Code Book (ECB) mode, which does not provide good - confidentiality. Specifically, ECB mode produces the same output for the same input each time. - This allows an attacker to intercept and replay the data. - metadata: - category: security - cwe: CWE-326 - security-severity: CRITICAL - shortDescription: Inadequate Encryption Strength - technology: - - kotlin - patterns: - - pattern: javax.crypto.Cipher.getInstance($TRANSFORMATION, ...) - - metavariable-regex: - metavariable: $TRANSFORMATION - regex: ^"[^/]*/ECB(/.*)?"$ - severity: ERROR - - id: kotlin_crypto_rule-CipherIntegrity + - id: terraform.azure.security.storage.storage-use-secure-tls-policy.storage-use-secure-tls-policy languages: - - kotlin - message: | - The ciphertext produced is susceptible to alteration by an adversary. This mean that the - cipher provides no way to detect that the data has been tampered with. If the ciphertext can be - controlled by an attacker, it could be altered without detection. + - hcl + message: 'Azure Storage currently supports three versions of the TLS protocol: 1.0, 1.1, and 1.2. Azure Storage uses TLS 1.2 on public HTTPS endpoints, but TLS 1.0 and TLS 1.1 are still supported for backward compatibility. This check will warn if the minimum TLS is not set to TLS1_2.' metadata: category: security - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: CRITICAL - shortDescription: Use of a broken or risky cryptographic algorithm + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#min_tls_version + - https://docs.microsoft.com/en-us/azure/storage/common/transport-layer-security-configure-minimum-version + subcategory: + - vuln technology: - - kotlin + - terraform + - azure patterns: - - pattern: | - javax.crypto.Cipher.getInstance($TRANSFORMATION, ...) - - metavariable-pattern: - metavariable: $TRANSFORMATION - patterns: - - pattern-regex: ^"[^/]*(/(CBC|OFB|CTR|ECB)(/.*)?)?"$ - - pattern-not-regex: ^"(ECIES|RSA)(/|"$) + - pattern-either: + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + min_tls_version = "$ANYTHING" + ... + } + - pattern-inside: | + resource "azurerm_storage_account" "..." { + ... + } + - pattern-not-inside: | + resource "azurerm_storage_account" "..." { + ... + min_tls_version = "TLS1_2" + ... + } severity: ERROR - - id: kotlin_crypto_rule-CipherPaddingOracle + - id: terraform.gcp.security.gcp-cloud-storage-logging.gcp-cloud-storage-logging languages: - - kotlin - message: | - This specific mode of CBC with PKCS5Padding is susceptible to padding oracle attacks. An - adversary could potentially decrypt the message if the system exposed the difference between - plaintext with invalid padding or valid padding. The distinction between valid and invalid - padding is usually revealed through distinct error messages being returned for each condition. + - hcl + message: Ensure bucket logs access. metadata: category: security - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-778: Insufficient Logging' + impact: LOW + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: CRITICAL - shortDescription: Use of a broken or risky cryptographic algorithm + - A10:2017 - Insufficient Logging & Monitoring + - A09:2021 - Security Logging and Monitoring Failures + references: + - https://docs.bridgecrew.io/docs/google-cloud-policy-index + subcategory: + - vuln technology: - - java + - terraform + - gcp patterns: - - pattern: javax.crypto.Cipher.getInstance($TRANSFORMATION) - - metavariable-regex: - metavariable: $TRANSFORMATION - regex: ^"[^/]*/CBC/PKCS5Padding - - metavariable-pattern: - metavariable: $TRANSFORMATION - patterns: - - pattern-not-regex: ^"(RSA|ECIES)/ - severity: ERROR - - id: kotlin_crypto_rule-CustomMessageDigest + - pattern: | + resource "google_storage_bucket" $ANYTHING { + ... + } + - pattern-not-inside: "resource \"google_storage_bucket\" $ANYTHING {\n ...\n logging {\n log_bucket = ...\n } \n ...\n}\n" + severity: WARNING + - id: terraform.gcp.security.gcp-dns-key-specs-rsasha1.gcp-dns-key-specs-rsasha1 languages: - - kotlin - message: | - Implementing a custom MessageDigest is error-prone. National Institute of Standards and - Technology(NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or - SHA-512/256. + - hcl + message: "Ensure that RSASHA1 is not used for the zone-signing and key-signing keys in Cloud DNS DNSSEC\t" metadata: category: security - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW owasp: - - A6:2017-Security Misconfiguration - - A04:2021-Insecure Design - security-severity: MEDIUM - shortDescription: Use of a broken or risky cryptographic algorithm + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln technology: - - kotlin - pattern: | - class $CLAZZ : java.security.MessageDigest(...) { - ... - } + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_dns_managed_zone" "..." { + ... + dnssec_config { + ... + default_key_specs { + ... + algorithm = "rsasha1" + key_type = "zoneSigning" + ... + } + ... + } + ... + } + - pattern-inside: | + resource "google_dns_managed_zone" "..." { + ... + dnssec_config { + ... + default_key_specs { + ... + algorithm = "rsasha1" + key_type = "keySigning" + ... + } + ... + } + ... + } severity: WARNING - - id: kotlin_crypto_rule-HazelcastSymmetricEncryption + - id: terraform.gcp.security.gcp-sql-database-require-ssl.gcp-sql-database-require-ssl languages: - - kotlin - message: | - The network communications for Hazelcast is configured to use a symmetric cipher (probably DES - or Blowfish). Those ciphers alone do not provide integrity or secure authentication. The use of - asymmetric encryption is preferred. + - hcl + message: Ensure all Cloud SQL database instance requires all incoming connections to use SSL metadata: category: security - cwe: CWE-326 + confidence: MEDIUM + cwe: + - 'CWE-326: Inadequate Encryption Strength' + impact: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Inadequate encryption strength + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + subcategory: + - vuln technology: - - kotlin - pattern: com.hazelcast.config.SymmetricEncryptionConfig() + - terraform + - gcp + patterns: + - pattern: resource + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + } + - pattern-not-inside: | + resource "google_sql_database_instance" "..." { + ... + ip_configuration { + ... + require_ssl = true + ... + } + ... + } severity: WARNING - - id: kotlin_crypto_rule-InsufficientKeySizeRsa + - id: terraform.gcp.security.gcp-sql-public-database.gcp-sql-public-database languages: - - kotlin - message: | - Detected an insufficient key size for DSA. NIST recommends a key size - of 2048 or higher. + - hcl + message: Ensure that Cloud SQL database Instances are not open to the world metadata: category: security - cwe: CWE-326 + confidence: MEDIUM + cwe: + - 'CWE-284: Improper Access Control' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Inadequate encryption strength + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + subcategory: + - vuln + technology: + - terraform + - gcp patterns: + - pattern: resource - pattern-either: - - patterns: - - pattern-inside: | - $GEN = KeyPairGenerator.getInstance($ALG, ...); + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + ip_configuration { + ... + authorized_networks { ... - - pattern-either: - - pattern: $VAR.initialize($SIZE, ...); - - pattern: java.security.spec.RSAKeyGenParameterSpec($SIZE,...); - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - - metavariable-regex: - metavariable: $ALG - regex: '"(RSA|DSA)"' + value = "0.0.0.0/0" + ... + } + ... + } + ... + } + - pattern-inside: | + resource "google_sql_database_instance" "..." { + ... + ip_configuration { + ... + dynamic "authorized_networks" { + ... + content { + ... + value = "0.0.0.0/0" + ... + } + ... + } + ... + } + ... + } severity: WARNING - - id: kotlin_crypto_rule-NullCipher + - id: terraform.lang.security.ec2-imdsv1-optional.ec2-imdsv1-optional languages: - - kotlin - message: | - The NullCipher implements the Cipher interface by returning ciphertext identical to the - supplied plaintext. In a few contexts, such as testing, a NullCipher may be appropriate. Avoid - using the NullCipher. Its accidental use can introduce a significant confidentiality risk. + - hcl + message: AWS EC2 Instance allowing use of the IMDSv1 metadata: category: security - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-918: Server-Side Request Forgery (SSRF)' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Use of a broken or risky cryptographic algorithm + - A10:2021 - Server-Side Request Forgery (SSRF) + references: + - https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#metadata-options + subcategory: + - vuln technology: - - kotlin - pattern: javax.crypto.NullCipher() - severity: WARNING - - id: kotlin_crypto_rule-RsaNoPadding + - terraform + - aws + pattern-either: + - patterns: + - pattern: http_tokens = "optional" + - pattern-inside: | + metadata_options { ... } + - patterns: + - pattern: | + resource "aws_instance" "$NAME" { + ... + } + - pattern-not: | + resource "aws_instance" "$NAME" { + ... + metadata_options { + ... + http_tokens = "required" + ... + } + ... + } + - pattern-not: | + resource "aws_instance" "$NAME" { + ... + metadata_options { + ... + http_tokens = "optional" + ... + } + ... + } + - pattern-not: | + resource "aws_instance" "$NAME" { + ... + metadata_options { + ... + http_endpoint = "disabled" + ... + } + ... + } + severity: ERROR + - id: terraform.lang.security.rds-insecure-password-storage-in-source-code.rds-insecure-password-storage-in-source-code languages: - - kotlin - message: | - The software uses the RSA algorithm but does not incorporate Optimal Asymmetric - Encryption Padding (OAEP), which might weaken the encryption. + - hcl + message: RDS instance or cluster with hardcoded credentials in source code. It is recommended to pass the credentials at runtime, or generate random credentials using the random_password resource. metadata: category: security - cwe: CWE-780 + confidence: MEDIUM + cwe: + - 'CWE-522: Insufficiently Protected Credentials' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Use of RSA algorithm without OAEP + - A02:2017 - Broken Authentication + - A04:2021 - Insecure Design + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#master_password + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster#master_password + - https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password + subcategory: + - vuln + technology: + - terraform + - aws pattern-either: - patterns: - - pattern: | - $VAR = "$ALG"; - ... - javax.crypto.Cipher.getInstance($VAR); - - metavariable-regex: - metavariable: $ALG - regex: .*RSA.*NoPadding.* + - pattern: password = "..." + - pattern-inside: | + resource "aws_db_instance" "..." { + ... + } - patterns: - - pattern: javax.crypto.Cipher.getInstance($ALG,...); - - metavariable-regex: - metavariable: $ALG - regex: .*RSA.*NoPadding.* + - pattern: master_password = "..." + - pattern-inside: | + resource "aws_rds_cluster" "..." { + ... + } severity: WARNING - - id: kotlin_crypto_rule-WeakMessageDigest + - id: terraform.lang.security.s3-public-rw-bucket.s3-public-rw-bucket languages: - - kotlin - message: | - DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage - of AES block ciphers instead of DES. + - hcl + message: S3 bucket with public read-write access detected. metadata: category: security - cwe: CWE-327 + confidence: MEDIUM + cwe: + - 'CWE-200: Exposure of Sensitive Information to an Unauthorized Actor' + cwe2021-top25: true + impact: MEDIUM + likelihood: LOW owasp: - - A6:2017-Security Misconfiguration - - A04:2021-Insecure Design - security-severity: MEDIUM - shortDescription: Use of a broken or risky cryptographic algorithm (SHA1/MD5) + - A01:2021 - Broken Access Control + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#acl + - https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl + subcategory: + - vuln technology: - - kotlin - patterns: - - pattern-either: - - pattern: MessageDigest.getInstance($ALG, ...) - - pattern: Signature.getInstance($ALG, ...) - - metavariable-regex: - metavariable: $ALG - regex: .*(MD5|MD4|MD2|SHA1|SHA-1).* - severity: WARNING - - id: kotlin_crypto_rule-WeakTLSProtocol + - terraform + - aws + pattern: acl = "public-read-write" + severity: ERROR + - id: terraform.lang.security.s3-unencrypted-bucket.s3-unencrypted-bucket languages: - - kotlin - message: | - A HostnameVerifier that accept any host are often use because of certificate - reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middleattacks - attacks since the client will trust any certificate. + - hcl + message: This rule has been deprecated, as all s3 buckets are encrypted by default with no way to disable it. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration for more info. metadata: category: security - cwe: CWE-295 + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + deprecated: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Improper certificate validation + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#server_side_encryption_configuration + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html + subcategory: + - vuln + technology: + - terraform + - aws patterns: - - pattern-either: - - pattern: org.apache.http.impl.client.DefaultHttpClient() - - pattern: javax.net.ssl.SSLContext.getInstance("SSL") - severity: WARNING - - id: kotlin_crypto_rule-WeakTLSProtocolVersion + - pattern: a + - pattern: b + severity: INFO + - id: typescript.angular.security.audit.angular-domsanitizer.angular-bypasssecuritytrust languages: - - kotlin - message: | - The application was found enabling insecure TLS protocol versions. When enabling protocol - versions for an `SSLContext`, only the following versions should be allowed: - - TLSv1.2 - - TLSv1.3 - - DTLSv1.2 - - DTLSv1.3 - - To mitigate potential security risks, it is strongly advised to enforce TLS 1.2 as the minimum - protocol version and disallow older versions such as TLS 1.0. Do note that newer versions of - Java do not even support TLS 1.0 and will throw `NoSuchAlgorithmException`. Versions of TLS - prior to 1.2 could expose the connection to downgrade attacks, where an adversary intercepts - the - connection and alters the requested protocol version to be a less secure one. - - In many scenarios, relying on the default system configuration does not meet compliance - standards. This is due to the application being deployed across diverse systems with varying - configurations and Java versions. While the default value may be secure on modern and - up-to-date systems, it may not hold true for older systems. Consequently, it is highly - recommended to explicitly define a secure configuration in all cases. - - Example configuring an SSLContext with TLSv1.2: - ``` - // Create an SSLContext with TLSv1.2 explicitly - SSLContext tlsContext = SSLContext.getInstance("TLSv1.2"); // or TLSv1.3, DTLSv1.2, DTLSv1.3 - - // Alternatively, set the enabled protocols - SSLContext serverSslContext = SSLContext.getInstance("TLS"); - SSLEngine serverEngine = serverSslContext.createSSLEngine(); - // Calling setEnabledProtocols will override the original context's configured protocol version - serverEngine.setEnabledProtocols(new String[]{ "TLSv1.2" }); - ``` - - For more information on `SSLContext` see: - - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/javax/net/ssl/SSLContext.html - - For more information on MiTM attacks see: - - https://owasp.org/www-community/attacks/Manipulator-in-the-middle_attack + - typescript + message: Detected the use of `$TRUST`. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. If you have to use `$TRUST`, ensure it does not come from user-input or use the appropriate prevention mechanism e.g. input validation or sanitization depending on the context. metadata: category: security - cwe: CWE-326 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: MEDIUM - shortDescription: Inadequate encryption strength - patterns: - - pattern-either: - - pattern-inside: | - import javax.net.ssl.*; - ... - - pattern-inside: | - import javax.net.ssl.SSLContext; - ... - - pattern-either: - - pattern-inside: | - SSLContext.getInstance("$UNSAFE_VERSION"); - - pattern-inside: | - SSLContext.getInstance(...); - ... - $ENGINE.setEnabledProtocols(arrayOf(...,"$UNSAFE_VERSION",...)); - - pattern-not: - patterns: + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://angular.io/api/platform-browser/DomSanitizer + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + subcategory: + - vuln + technology: + - angular + - browser + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: - pattern-inside: | - $C = SSLContext.getInstance(...); + import $S from "underscore.string" ... - $ENGINE.setEnabledProtocols(arrayOf(...,"$DT_GOODNESS",...)); - - metavariable-regex: - metavariable: $DT_GOODNESS - regex: ^D?TLSv1\.[23]$ - - pattern-not: - patterns: - pattern-inside: | - $C = SSLContext.getInstance(...); + import * as $S from "underscore.string" ... - $E = $C.createSSLEngine() + - pattern-inside: | + import $S from "underscore.string" ... - $E.enabledProtocols = arrayOf(...,"$DT_GOODNESS",...) - - metavariable-regex: - metavariable: $DT_GOODNESS - regex: ^DTLSv1\.[23]$ - - metavariable-regex: - metavariable: $UNSAFE_VERSION - regex: ^(TLS|(D)?TLSv1.(0|1))$ - severity: WARNING - - id: kotlin_csrf_rule-SpringCSRFDisabled - languages: - - kotlin - message: | - The application fails to protect against Cross-Site Request Forgery (CSRF) - due to disabling Spring's CSRF protection features. - metadata: - category: security - cwe: CWE-352 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Cross-Site Request Forgery (CSRF) - pattern-either: - - pattern: '($H: org.springframework.security.config.annotation.web.builders.HttpSecurity). ... .csrf().disable()' - - pattern: '($C: CsrfConfigurer).disable()' - severity: WARNING - - id: kotlin_endpoint_rule-UnvalidatedRedirect - languages: - - kotlin - message: | - Unvalidated redirects occur when an application redirects a user to a - destination URL specified by a user supplied parameter that is not validated. - Such vulnerabilities can be used to facilitate phishing attacks. - metadata: - category: security - cwe: CWE-601 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: URL redirection to untrusted site ('Open Redirect') - mode: taint - pattern-sanitizers: + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) - patterns: - - pattern-inside: | - if ($SAFE.contains($URL)){ - ... - } - pattern-either: - - pattern: | - ($RES: $X.servlet.http.HttpServletResponse).sendRedirect($URL) - - pattern: | - ($RES: $X.servlet.http.HttpServletResponse).addHeader("Location", $URL) + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) + - patterns: + - pattern: sanitizer.sanitize(...) + - pattern-not: sanitizer.sanitize(SecurityContext.NONE, ...); pattern-sinks: - - pattern-either: - - pattern: | - ($RES: $X.servlet.http.HttpServletResponse).sendRedirect($URL) - - pattern: | - ($RES: $X.servlet.http.HttpServletResponse).addHeader("Location", $URL) - pattern-sources: - patterns: - - pattern: | - $URL = ($REQ: $X.servlet.http.HttpServletRequest).$M(...); - - metavariable-regex: - metavariable: $M - regex: (getParameter|getCookies|getHeader|getHeaders|getHeaderNames|getPathInfo|getPathTranslated|getContextPath|getQueryString|getRemoteUser|getRequestedSessionId|getRequestURI|getRequestURL|getServletPath|getParts|getPart|getReader) - severity: ERROR - - id: kotlin_endpoint_rule-WeakHostNameVerification - languages: - - kotlin - message: | - A HostnameVerifier that accept any host are often use because of certificate - reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middle - attacks since the client will trust any certificate. - metadata: - category: security - cwe: CWE-295 - security-severity: MEDIUM - shortDescription: Improper Certificate Validation - patterns: - - pattern-either: - - patterns: + - pattern-either: + - pattern: $X.$TRUST($Y) + - focus-metavariable: $Y + - pattern-not: | + $X.$TRUST(`...`) + - pattern-not: | + $X.$TRUST("...") + - metavariable-regex: + metavariable: $TRUST + regex: (bypassSecurityTrustHtml|bypassSecurityTrustStyle|bypassSecurityTrustScript|bypassSecurityTrustUrl|bypassSecurityTrustResourceUrl) + pattern-sources: + - patterns: + - pattern-either: - pattern-inside: | - class $V : HostnameVerifier { - ... - } - - pattern: | - fun verify(...): Boolean { - return true - } - - patterns: + function ...({..., $X: string, ...}) { ... } - pattern-inside: | - class $V : X509TrustManager { - ... - } - - pattern-either: - - pattern: fun checkClientTrusted(...) {} - - pattern: fun checkServerTrusted(...) {} - - pattern: 'fun getAcceptedIssuers(): Array? {return null}' + function ...(..., $X: string, ...) { ... } + - focus-metavariable: $X severity: WARNING - - id: kotlin_file_rule-FileUploadFileName + - id: typescript.aws-cdk.security.audit.awscdk-bucket-encryption.awscdk-bucket-encryption languages: - - kotlin - message: | - The filename provided by the FileUpload API can be tampered with by the client to reference - unauthorized files. The provided filename should be properly validated to ensure it's properly - structured, contains no unauthorized path characters (e.g., / \), and refers to an authorized - file. + - typescript + message: 'Add "encryption: $Y.BucketEncryption.KMS_MANAGED" or "encryption: $Y.BucketEncryption.S3_MANAGED" to the bucket props for Bucket construct $X' metadata: category: security - cwe: CWE-22 + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html + subcategory: + - vuln technology: - - kotlin + - AWS-CDK pattern-either: - patterns: - pattern-inside: | - $FILES = ($SFU: ServletFileUpload).parseRequest(($REQ: $X.servlet.http.HttpServletRequest?)) + import {Bucket} from '@aws-cdk/aws-s3' ... - for($ITEM in $FILES) { - ... - } - - pattern: $ITEM.getName() - - pattern: '($PART: $X.servlet.http.Part).getSubmittedFileName()' + - pattern: const $X = new Bucket(...) + - pattern-not: | + const $X = new Bucket(..., {..., encryption: BucketEncryption.KMS_MANAGED, ...}) + - pattern-not: | + const $X = new Bucket(..., {..., encryption: BucketEncryption.KMS, ...}) + - pattern-not: | + const $X = new Bucket(..., {..., encryption: BucketEncryption.S3_MANAGED, ...}) + - patterns: + - pattern-inside: | + import * as $Y from '@aws-cdk/aws-s3' + ... + - pattern: const $X = new $Y.Bucket(...) + - pattern-not: | + const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.KMS_MANAGED, ...}) + - pattern-not: | + const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.KMS, ...}) + - pattern-not: | + const $X = new $Y.Bucket(..., {..., encryption: $Y.BucketEncryption.S3_MANAGED, ...}) severity: ERROR - - id: kotlin_file_rule-FilenameUtils + - id: typescript.aws-cdk.security.audit.awscdk-bucket-enforcessl.aws-cdk-bucket-enforcessl languages: - - kotlin - message: | - A file is opened to read its content. The filename comes from an input - parameter. If an unfiltered parameter is passed to this file API, files from an - arbitrary filesystem location could be read. + - ts + message: Bucket $X is not set to enforce encryption-in-transit, if not explictly setting this on the bucket policy - the property "enforceSSL" should be set to true metadata: category: security - cwe: CWE-22 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html + subcategory: + - vuln technology: - - kotlin - patterns: - - pattern-inside: | - import org.apache.commons.io.FilenameUtils - ... - - pattern-either: - - pattern: normalize(...) - - pattern: getExtension(...) - - pattern: isExtensions(...) - - pattern: getName(...) - - pattern: getBaseName(...) - - pattern: org.apache.commons.io.FilenameUtils.normalize(...) - - pattern: org.apache.commons.io.FilenameUtils.getExtension(...) - - pattern: org.apache.commons.io.FilenameUtils.isExtensions(...) - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - - pattern: org.apache.commons.io.FilenameUtils.getBaseName(...) - severity: WARNING - - id: kotlin_inject_rule-CommandInjection + - AWS-CDK + pattern-either: + - patterns: + - pattern-inside: | + import {Bucket} from '@aws-cdk/aws-s3'; + ... + - pattern: const $X = new Bucket(...) + - pattern-not: | + const $X = new Bucket(..., {enforceSSL: true}, ...) + - patterns: + - pattern-inside: | + import * as $Y from '@aws-cdk/aws-s3'; + ... + - pattern: const $X = new $Y.Bucket(...) + - pattern-not: | + const $X = new $Y.Bucket(..., {..., enforceSSL: true, ...}) + severity: ERROR + - id: typescript.aws-cdk.security.audit.awscdk-sqs-unencryptedqueue.awscdk-sqs-unencryptedqueue languages: - - kotlin - message: | - The highlighted API is used to execute a system command. If unfiltered input is passed to this - API, it can lead to arbitrary command execution. + - ts + message: 'Queue $X is missing encryption at rest. Add "encryption: $Y.QueueEncryption.KMS" or "encryption: $Y.QueueEncryption.KMS_MANAGED" to the queue props to enable encryption at rest for the queue.' metadata: category: security - cwe: CWE-78 + confidence: MEDIUM + cwe: + - 'CWE-311: Missing Encryption of Sensitive Data' + impact: HIGH + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + - A03:2017 - Sensitive Data Exposure + - A04:2021 - Insecure Design + references: + - https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-data-protection.html + subcategory: + - vuln technology: - - kotlin + - AWS-CDK pattern-either: - patterns: - pattern-inside: | - fun $FUNC(..., $PARAM: String, ...) { - ... - } - - pattern-inside: | - $R = Runtime.getRuntime() + import {Queue} from '@aws-cdk/aws-sqs' ... - - pattern-either: - - pattern: $R.exec(<...$PARAM...>,...) - - patterns: - - pattern-either: - - pattern: | - $CMDARR = arrayOf("$SHELL",...,<...$PARAM...>,...) - ... - $R.exec($CMDARR,...) - - pattern: $R.exec(arrayOf("$SHELL",...,<...$PARAM...>,...), ...) - - pattern: $R.exec(java.util.String.format("...", ...,<...$PARAM...>,...)) - - pattern: '$R.exec(($A: String) + ($B: String))' - - metavariable-regex: - metavariable: $SHELL - regex: (/.../)?(sh|bash|ksh|csh|tcsh|zsh)$ - - pattern-not: $R.exec("...","...","...",...) + - pattern: const $X = new Queue(...) + - pattern-not: | + const $X = new Queue(..., {..., encryption: QueueEncryption.KMS_MANAGED, ...}) - pattern-not: | - $R.exec(arrayOf("...","...","...",...),...) + const $X = new Queue(..., {..., encryption: QueueEncryption.KMS, ...}) - patterns: - pattern-inside: | - fun $FUNC(..., $PARAM: String, ...) { - ... - } - - pattern-inside: | - $PB = ProcessBuilder() + import * as $Y from '@aws-cdk/aws-sqs' ... - - pattern-either: - - pattern: $PB.command(<...$PARAM...>,...) - - patterns: - - pattern-inside: $VAL = <...$PARAM...>; ... - - pattern: $PB.command(<...$VAL...>,...) - - patterns: - - pattern-either: - - pattern: $PB.command("$SHELL",...,<...$PARAM...>,...) - - pattern: | - $CMDARR = java.util.Arrays.asList("$SHELL",...,<...$PARAM...>,...) - ... - $PB.command($CMDARR,...) - - pattern: $PB.command(java.util.Arrays.asList("$SHELL",...,<...$PARAM...>,...),...) - - pattern: $PB.command(java.util.String.format("...", ...,<...$PARAM...>,...)) - - pattern: '$PB.command(($A: String) + ($B: String))' - - metavariable-regex: - metavariable: $SHELL - regex: (/.../)?(sh|bash|ksh|csh|tcsh|zsh)$ - - pattern-not: $PB.command("...","...","...",...) + - pattern: const $X = new $Y.Queue(...) + - pattern-not: | + const $X = new $Y.Queue(..., {..., encryption: $Y.QueueEncryption.KMS_MANAGED, ...}) - pattern-not: | - $PB.command(java.util.Arrays.asList("...","...","...",...)) + const $X = new $Y.Queue(..., {..., encryption: $Y.QueueEncryption.KMS, ...}) severity: WARNING - - id: kotlin_inject_rule-ELInjection + - id: typescript.aws-cdk.security.awscdk-bucket-grantpublicaccessmethod.awscdk-bucket-grantpublicaccessmethod languages: - - kotlin - message: | - An expression is built with a dynamic value. The source of the value(s) should be verified to - avoid that unfiltered values fall into this risky code evaluation. + - ts + message: Using the GrantPublicAccess method on bucket contruct $X will make the objects in the bucket world accessible. Verify if this is intentional. metadata: category: security - cwe: CWE-917 + confidence: MEDIUM + cwe: + - 'CWE-306: Missing Authentication for Critical Function' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper neutralization of special elements used in an expression language statement ('Expression Language Injection') + - A07:2021 - Identification and Authentication Failures + references: + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-overview.html + subcategory: + - vuln technology: - - kotlin + - AWS-CDK pattern-either: - patterns: - - metavariable-regex: - metavariable: $METHOD - regex: ^create(Method|Value)Expression$ - - metavariable-pattern: - metavariable: $EXPR - patterns: - - pattern-not: '"..."' + - pattern-inside: | + import {Bucket} from '@aws-cdk/aws-s3' + ... - pattern: | - ($EXP: ExpressionFactory ).$METHOD(($CTX: $X.el.ELContext), $EXPR, ...) + const $X = new Bucket(...) + ... + $X.grantPublicAccess(...) - patterns: + - pattern-inside: | + import * as $Y from '@aws-cdk/aws-s3' + ... - pattern: | - ($P: $X.el.ELProcessor).$METHOD(...) - - pattern-not: | - ($P: $X.el.ELProcessor).$METHOD("...", ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(eval|(get|set)Value)$ + const $X = new $Y.Bucket(...) + ... + $X.grantPublicAccess(...) severity: WARNING - - id: kotlin_inject_rule-FileDisclosure + - id: typescript.aws-cdk.security.awscdk-codebuild-project-public.awscdk-codebuild-project-public languages: - - kotlin - message: | - Constructing a server-side redirect path with user input could allow an - attacker to download application binaries (including application classes or - jar files) or view arbitrary files within protected directories. + - ts + message: CodeBuild Project $X is set to have a public URL. This will make the build results, logs, artifacts publically accessible, including builds prior to the project being public. Ensure this is acceptable for the project. metadata: category: security - cwe: CWE-552 + confidence: MEDIUM + cwe: + - 'CWE-306: Missing Authentication for Critical Function' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Files or directories accessible to external parties - mode: taint - pattern-sinks: - - patterns: - - pattern: org.springframework.web.servlet.ModelAndView($FST); - - pattern: $FST - - patterns: - - pattern: org.springframework.web.servlet.ModelAndView($FST, $SND); - - pattern: $FST - - patterns: - - pattern: org.springframework.web.servlet.ModelAndView($FST, $SND, $TRD); - - pattern: $FST - - patterns: - - pattern: org.apache.struts.action.ActionForward($FST) - - pattern: $FST - - patterns: - - pattern: org.apache.struts.action.ActionForward($FST, $SND) - - pattern: $FST - - patterns: - - pattern: org.apache.struts.action.ActionForward($FST, $SND, $TRD) - - pattern: $SND - - patterns: - - pattern: org.apache.struts.action.ActionForward($FST, $SND, $TRD) - - pattern: $TRD - - patterns: - - pattern-inside: | - $ACTION = org.apache.struts.action.ActionForward(); - ... - - pattern: $ACTION.setPath(...) + - A07:2021 - Identification and Authentication Failures + references: + - https://docs.aws.amazon.com/codebuild/latest/userguide/public-builds.html + subcategory: + - vuln + technology: + - AWS-CDK + pattern-either: - patterns: - pattern-inside: | - $MVC = org.springframework.web.servlet.ModelAndView(); + import {Project} from '@aws-cdk/aws-codebuild' ... - - pattern: $MVC.setViewName(...); + - pattern: | + const $X = new Project(..., {..., badge: true, ...}) - patterns: - pattern-inside: | - $REQ = $HTTP.getRequestDispatcher(...); + import * as $Y from '@aws-cdk/aws-codebuild' ... - - pattern-either: - - pattern: $REQ.include($FST, $SND) - - pattern: $REQ.forward($FST, $SND) - pattern-sources: - - pattern: '($VAR: javax.servlet.http.HttpServletRequest).getParameter(...)' - severity: ERROR - - id: kotlin_inject_rule-HttpParameterPollution + - pattern: | + const $X = new $Y.Project(..., {..., badge: true, ...}) + severity: WARNING + - id: typescript.react.security.audit.react-dangerouslysetinnerhtml.react-dangerouslysetinnerhtml languages: - - kotlin - message: | - Concatenating unvalidated user input into a URL can allow an attacker to override the value of - a request parameter. Attacker may be able to override existing parameter values, inject a new - parameter or exploit variables out of a direct reach. HTTP Parameter Pollution (HPP) attacks - consist of injecting encoded query string delimiters into other existing parameters. If a web - application does not properly sanitize the user input, a malicious user may compromise the - logic of the application to perform either client-side or server-side attacks. + - typescript + - javascript + message: Detection of dangerouslySetInnerHTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use dangerouslySetInnerHTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. metadata: category: security - cwe: CWE-88 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of argument delimiters in a command ('Argument Injection') + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html + subcategory: + - vuln technology: - - kotlin + - react mode: taint pattern-sanitizers: - - pattern: java.net.URLEncoder.encode(...) - - pattern: com.google.common.net.UrlEscapers.urlPathSegmentEscaper().escape(...) - pattern-sinks: - - pattern: org.apache.http.client.methods.HttpGet(...) - - pattern: org.apache.commons.httpclient.methods.GetMethod(...) - - pattern: '($GM: org.apache.commons.httpclient.methods.GetMethod).setQueryString(...)' - pattern-sources: - - pattern: '($REQ: HttpServletRequest).getParameter(...)' - severity: ERROR - - id: kotlin_inject_rule-LDAPInjection - languages: - - kotlin - message: | - Just like SQL, all inputs passed to an LDAP query need to be passed in safely. Unfortunately, - LDAP doesn't have prepared statement interfaces like SQL. Therefore, the primary defense - against LDAP injection is strong input validation of any untrusted data before including it in - an LDAP query. - metadata: - category: security - cwe: CWE-90 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper neutralization of special elements used in an LDAP query ('LDAP Injection') - technology: - - kotlin - mode: taint - pattern-sinks: - - pattern: javax.naming.ldap.LdapName(...) - - pattern: '($C: javax.naming.directory.Context).lookup(...)' - - pattern: '($C: javax.naming.Context).lookup(...)' - patterns: - - pattern-inside: '($C: com.unboundid.ldap.sdk.LDAPConnection).search($QUERY, ...)' - - pattern: $QUERY + - pattern-either: + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) - patterns: + - pattern-either: + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... - pattern-either: - patterns: - - pattern-either: - - pattern: $CTX.lookup(...) - - patterns: - - pattern-inside: $CTX.search($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.search($NAME, $FILTER, ...) - - pattern: $FILTER - - metavariable-pattern: - metavariable: $CTX - pattern-either: - - pattern: '($C: DirContext)' - - pattern: '($IDC: InitialDirContext)' - - pattern: '($LC: LdapContext)' - - pattern: '($EDC: EventDirContext)' - - pattern: '($LC: LdapCtx)' - - pattern: '($C: javax.naming.directory.DirContext)' - - pattern: '($IDC: javax.naming.directory.InitialDirContext)' - - pattern: '($LC: javax.naming.ldap.LdapContext)' - - pattern: '($EDC: javax.naming.event.EventDirContext)' - - pattern: '($LC: com.sun.jndi.ldap.LdapCtx)' + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) - patterns: - - pattern-either: - - pattern: $CTX.lookup(...) - - patterns: - - pattern-inside: $CTX.search($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.search($NAME, $FILTER, ...) - - pattern: $FILTER - - pattern-inside: - pattern-either: - - pattern: $CTX = DirContext(...);... - - pattern: $CTX = InitialDirContext(...);... - - pattern: $CTX = LdapContext(...);... - - pattern: $CTX = EventDirContext(...);... - - pattern: $CTX = LdapCtx(...);... - - pattern: $CTX = javax.naming.directory.DirContext(...);... - - pattern: $CTX = javax.naming.directory.InitialDirContext(...);... - - pattern: $CTX = javax.naming.ldap.LdapContext(...);... - - pattern: $CTX = javax.naming.event.EventDirContext(...);... - - pattern: $CTX = com.sun.jndi.ldap.LdapCtx(...);... - - pattern-either: - - patterns: - - pattern-either: - - patterns: - - pattern-inside: $CTX.list($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.lookup($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.search($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.search($NAME, $FILTER, ...) - - pattern: $FILTER - - metavariable-pattern: - metavariable: $CTX - pattern-either: - - pattern: '($LT: LdapTemplate)' - - pattern: '($LO: LdapOperations)' - - pattern: '($LT: org.springframework.ldap.core.LdapTemplate)' - - pattern: '($LO: org.springframework.ldap.core.LdapOperations)' - - patterns: - - pattern-either: - - patterns: - - pattern-inside: $CTX.list($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.lookup($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.search($QUERY, ...) - - pattern: $QUERY - - patterns: - - pattern-inside: $CTX.search($NAME, $FILTER, ...) - - pattern: $FILTER - - pattern-inside: - pattern-either: - - pattern: $CTX = LdapTemplate(...);... - - pattern: $CTX = LdapOperations(...);... - - pattern: $CTX = org.springframework.ldap.core.LdapTemplate(...);... - - pattern: $CTX = org.springframework.ldap.core.LdapOperations(...);... - pattern-sources: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) - patterns: - - pattern-inside: | - fun $FUNC(..., $VAR: String, ...) { - ... - } - - pattern: $VAR + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) - patterns: - - pattern-inside: | - fun $FUNC(..., $X: String, ...) { - ... - $VAR = ... + $X - ... - } - - pattern: $VAR - severity: WARNING - - id: kotlin_inject_rule-OgnlInjection - languages: - - kotlin - message: | - "A expression is built with a dynamic value. The source of the value(s) should be verified to - avoid that unfiltered values fall into this risky code evaluation." - metadata: - category: security - cwe: CWE-917 - security-severity: MEDIUM - shortDescription: Expression injection (OGNL) - technology: - - kotlin - patterns: - - pattern-either: - - pattern-inside: | - fun $FUNC(..., $VAR: String, ...) { - ... - } - - pattern-inside: | - fun $FUNC(..., $VAR: Map<$K,$V>, ...) { - ... - } - - pattern-inside: | - fun $FUNC(..., $VAR: Map<$K,*>, ...) { - ... - } - - pattern-inside: | - fun $FUNC(..., $VAR: java.util.HashMap<$K,$V>, ...) { - ... - } - - pattern-either: - - pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariables(...,$VAR, ...) - - pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariablesCollection(..., $VAR, ...) - - pattern: com.opensymphony.xwork2.util.TextParseUtil.shallBeIncluded(..., $VAR, ...) - - pattern: com.opensymphony.xwork2.util.TextParseUtil.commaDelimitedStringToSet(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.TextParser).evaluate(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.OgnlTextParser).evaluate(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getGetMethod(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getSetMethod(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getField(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setProperties(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setProperty(...,$VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getValue(...,$VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setValue(...,$VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getGetMethod(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getSetMethod(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getField(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setProperties(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setProperty(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getValue(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setValue(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setProperties(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setProperty(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).getValue(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setValue(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).callMethod(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).compile(..., $VAR, ...) - - pattern: ($P:org.apache.struts2.util.VelocityStrutsUtil).evaluate(...) - - pattern: org.apache.struts2.util.StrutsUtil.findString(...) - - pattern: org.apache.struts2.util.StrutsUtil.findValue(..., $VAL) - - pattern: org.apache.struts2.util.StrutsUtil.getText(...) - - pattern: org.apache.struts2.util.StrutsUtil.translateVariables(...) - - pattern: org.apache.struts2.util.StrutsUtil.makeSelectList(..., $VAR, ...) - - pattern: ($T:org.apache.struts2.views.jsp.ui.OgnlTool).findValue(..., $VAR, ...) - - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).findString(...) - - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).findValue(..., $VAR, ...) - - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).setValue(..., $VAR, ...) - - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).setParameter(..., $VAR, ...) + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) + - patterns: + - pattern-either: + - pattern-inside: | + $S = new Remarkable() + ... + - pattern: $S.render(...) + pattern-sinks: + - patterns: + - focus-metavariable: $X + - pattern-either: + - pattern: | + {...,dangerouslySetInnerHTML: {__html: $X},...} + - pattern: | + <$Y ... dangerouslySetInnerHTML={{__html: $X}} /> + - pattern-not: | + <$Y ... dangerouslySetInnerHTML={{__html: "..."}} /> + - pattern-not: | + {...,dangerouslySetInnerHTML:{__html: "..."},...} + - metavariable-pattern: + metavariable: $X + patterns: + - pattern-not: | + {...} + - pattern-not: | + <... {__html: "..."} ...> + - pattern-not: | + <... {__html: `...`} ...> + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + function ...({..., $X, ...}) { ... } + - pattern-inside: | + function ...(..., $X, ...) { ... } + - focus-metavariable: $X + - pattern-not-inside: | + $F. ... .$SANITIZEUNC(...) severity: WARNING - - id: kotlin_inject_rule-SpotbugsPathTraversalAbsolute + - id: typescript.react.security.audit.react-unsanitized-method.react-unsanitized-method languages: - - kotlin - message: | - The software uses an HTTP request parameter to construct a pathname that should be within a - restricted directory, but it does not properly neutralize absolute path sequences such as - "/abs/path" that can resolve to a location that is outside of that directory. See - http://cwe.mitre.org/data/definitions/36.html for more information. + - typescript + - javascript + message: Detection of $HTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use $HTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. metadata: category: security - cwe: CWE-22 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://developer.mozilla.org/en-US/docs/Web/API/Document/writeln + - https://developer.mozilla.org/en-US/docs/Web/API/Document/write + - https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML + subcategory: + - vuln technology: - - kotlin + - react mode: taint pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - patterns: - - pattern-inside: | - $U = java.net.URI($VAR) - pattern-either: - - pattern-inside: java.io.File($U) - - pattern-inside: java.nio.file.Paths.get($U) - - pattern: $VAR - - patterns: - - pattern-inside: java.io.RandomAccessFile($INPUT,...) - - pattern: $INPUT - - pattern: java.io.FileReader(...) - - pattern: javax.activation.FileDataSource(...) - - pattern: java.io.FileInputStream(...) - - pattern: java.io.File(...) - - pattern: java.nio.file.Paths.get(...) - - pattern: java.io.File.createTempFile(...) - - pattern: java.io.File.createTempDirectory(...) - - pattern: java.nio.file.Files.createTempFile(...) - - pattern: java.nio.file.Files.createTempDirectory(...) - - patterns: - - pattern: $SRC.$METHOD(...) - - metavariable-pattern: - metavariable: $SRC - pattern-either: - - pattern: getClass() - - pattern: getClass().getClassLoader() - - pattern: '($C: ClassLoader)' - - pattern: '($C: Class)' - - pattern: $CLZ.getClassLoader() - - metavariable-pattern: - metavariable: $METHOD - pattern-either: - - pattern: getResourceAsStream - - pattern: getResource + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) + - patterns: + - pattern-either: + - pattern-inside: | + import $S from "dompurify" + ... + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) - patterns: - - pattern-inside: java.io.FileWriter($PATH, ...) - - pattern: $PATH + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) - patterns: - - pattern-inside: java.io.FileOutputStream($PATH, ...) - - pattern: $PATH - pattern-sources: - - pattern: '($REQ: HttpServletRequest).getParameter(...)' + - pattern-either: + - pattern-inside: | + import $S from 'sanitize-html'; + ... + - pattern-inside: | + import * as $S from "sanitize-html"; + ... + - pattern-inside: | + $S = require("sanitize-html") + ... + - pattern: $S(...) - patterns: - - pattern-inside: fun $FUNC(..., @RequestParam $REQ:$TYPE, ...) {...} - - focus-metavariable: $REQ - severity: WARNING - - id: kotlin_inject_rule-SqlInjection - languages: - - kotlin - message: | - The input values included in SQL queries need to be passed in safely. Bind - variables in prepared statements can be used to easily mitigate the risk of - SQL injection. - metadata: - category: security - cwe: CWE-89 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') - technology: - - java - mode: taint - options: - taint_assume_safe_functions: true - pattern-propagators: - - from: $SRC - pattern: $SB.append($SRC) - to: $SB - - from: $SRC - patterns: - - pattern: $F(..., $SRC, ...) - - focus-metavariable: $F - pattern-either: - - pattern: String.format - - pattern: StringBuilder - to: $F + - pattern-inside: | + $S = new Remarkable() + ... + - pattern: $S.render(...) pattern-sinks: - patterns: - pattern-either: - - pattern: '($PM: javax.jdo.PersistenceManager).newQuery($ARG)' - - pattern: '($PM: javax.jdo.PersistenceManager).newQuery(..., $ARG)' - - pattern: '($Q: javax.jdo.Query).setFilter($ARG)' - - pattern: '($Q: javax.jdo.Query).setGrouping($ARG)' - - pattern: org.hibernate.criterion.Restrictions.sqlRestriction($ARG, ...) - - pattern: '($S: org.hibernate.Session).createQuery($ARG, ...)' - - pattern: '($S: org.hibernate.Session).createSQLQuery($ARG, ...)' - - pattern: '($S: java.sql.Statement).executeQuery($ARG, ...)' - - pattern: '($S: java.sql.Statement).execute($ARG, ...)' - - pattern: '($S: java.sql.Statement).executeUpdate($ARG, ...)' - - pattern: '($S: java.sql.Statement).executeLargeUpdate($ARG, ...)' - - pattern: '($S: java.sql.Statement).addBatch($ARG, ...)' - - pattern: '($S: java.sql.PreparedStatement).executeQuery($ARG, ...)' - - pattern: '($S: java.sql.PreparedStatement).execute($ARG, ...)' - - pattern: '($S: java.sql.PreparedStatement).executeUpdate($ARG, ...)' - - pattern: '($S: java.sql.PreparedStatement).executeLargeUpdate($ARG, ...)' - - pattern: '($S: java.sql.PreparedStatement).addBatch($ARG, ...)' - - pattern: '($S: java.sql.Connection).prepareCall($ARG, ...)' - - pattern: '($S: java.sql.Connection).prepareStatement($ARG, ...)' - - pattern: '($S: java.sql.Connection).nativeSQL($ARG, ...)' - - pattern: org.springframework.jdbc.core.PreparedStatementCreatorFactory($ARG, ...) - - pattern: '($F: org.springframework.jdbc.core.PreparedStatementCreatorFactory).newPreparedStatementCreator($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).batchUpdate($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).execute($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).query($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForList($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForMap($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForRowSet($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForInt($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForLong($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).update($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).batchUpdate($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).execute($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).query($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForList($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForMap($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForObject($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForRowSet($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForInt($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForLong($ARG, ...)' - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).update($ARG, ...)' - - pattern: '($O: io.vertx.sqlclient.SqlClient).query($ARG, ...)' - - pattern: '($O: io.vertx.sqlclient.SqlClient).preparedQuery($ARG, ...)' - - pattern: '($O: io.vertx.sqlclient.SqlConnection).prepare($ARG, ...)' - - pattern: '($O: org.apache.turbine.om.peer.BasePeer).executeQuery($ARG, ...)' - - pattern: '($O: org.apache.torque.util.BasePeer).executeQuery($ARG, ...)' - - pattern: '($O: javax.persistence.EntityManager).createQuery($ARG, ...)' - - pattern: '($O: javax.persistence.EntityManager).createNativeQuery($ARG, ...)' - - pattern: '($H: org.jdbi.v3.core.Handle).createQuery($ARG, ...)' - - pattern: '($H: org.jdbi.v3.core.Handle).createScript($ARG, ...)' - - pattern: '($H: org.jdbi.v3.core.Handle).createUpdate($ARG, ...)' - - pattern: '($H: org.jdbi.v3.core.Handle).execute($ARG, ...)' - - pattern: '($H: org.jdbi.v3.core.Handle).prepareBatch($ARG, ...)' - - pattern: '($H: org.jdbi.v3.core.Handle).select($ARG, ...)' - - pattern: org.jdbi.v3.core.statement.Script($H, $ARG) - - pattern: org.jdbi.v3.core.statement.Update($H, $ARG) - - pattern: org.jdbi.v3.core.statement.PreparedBatch($H, $ARG) - - focus-metavariable: $ARG + - pattern: "this.window.document. ... .$HTML('...',$SINK) \n" + - pattern: "window.document. ... .$HTML('...',$SINK) \n" + - pattern: "document.$HTML($SINK) \n" + - metavariable-regex: + metavariable: $HTML + regex: (writeln|write) + - focus-metavariable: $SINK + - patterns: + - pattern-either: + - pattern: "$PROP. ... .$HTML('...',$SINK) \n" + - metavariable-regex: + metavariable: $HTML + regex: (insertAdjacentHTML) + - focus-metavariable: $SINK pattern-sources: - patterns: - - pattern-inside: 'fun $FUNC(..., $SRC: String, ...) { ... }' - - pattern: $SRC - severity: ERROR - - id: kotlin_ldap_rule-AnonymousLDAP - languages: - - kotlin - message: | - Without proper access control, executing an LDAP statement that contains a - user-controlled value can allow an attacker to abuse poorly configured LDAP - context - metadata: - category: security - cwe: CWE-306 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: MEDIUM - shortDescription: Missing authentication for critical function (LDAP) - patterns: - - pattern-inside: | - import javax.naming.Context - ... - - pattern: $ENV[Context.SECURITY_AUTHENTICATION] = "none" + - pattern-either: + - pattern-inside: | + function ...({..., $X, ...}) { ... } + - pattern-inside: | + function ...(..., $X, ...) { ... } + - focus-metavariable: $X + - pattern-either: + - pattern: $X.$Y + - pattern: $X[...] severity: WARNING - - id: kotlin_password_rule-ConstantDBPassword - languages: - - kotlin - message: | - A potential hard-coded password was identified in a database connection string. - Passwords should not be stored directly in code - but loaded from secure locations such as a Key Management System (KMS). - - The purpose of using a Key Management System is so access can be audited and keys easily - rotated - in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine - when or if, a key is compromised. - - The recommendation on which KMS to use depends on the environment the application is running - in: - - - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - - For on premise or other alternatives to cloud providers, consider [Hashicorp's - Vault](https://www.vaultproject.io/) - - For other cloud providers, please see their documentation - metadata: - category: security - cwe: CWE-259 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: Critical - shortDescription: Use of hard-coded password - technology: - - kotlin - pattern: java.sql.DriverManager.getConnection($URI, $USR, "...") - severity: ERROR - - id: kotlin_password_rule-EmptyDBPassword + - id: typescript.react.security.audit.react-unsanitized-property.react-unsanitized-property languages: - - kotlin - message: | - The application does not provide authentication when communicating a database - server. It is strongly recommended that the database server be configured with - authentication and restrict what queries users can execute. - - Please see your database server's documentation on how to configure a password. - - Additionally, passwords should not be stored directly in code - but loaded from secure locations such as a Key Management System (KMS). - - The purpose of using a Key Management System is so access can be audited and keys easily - rotated - in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine - when or if, a key is compromised. - - The recommendation on which KMS to use depends on the environment the application is running - in: - - - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - - For on premise or other alternatives to cloud providers, consider [Hashicorp's - Vault](https://www.vaultproject.io/) - - For other cloud providers, please see their documentation + - typescript + - javascript + message: Detection of $HTML from non-constant definition. This can inadvertently expose users to cross-site scripting (XSS) attacks if this comes from user-provided input. If you have to use $HTML, consider using a sanitization library such as DOMPurify to sanitize your HTML. metadata: category: security - cwe: CWE-306 + confidence: MEDIUM + cwe: + - 'CWE-79: Improper Neutralization of Input During Web Page Generation (''Cross-site Scripting'')' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: Critical - shortDescription: Missing authentication for critical function (database) + - A07:2017 - Cross-Site Scripting (XSS) + - A03:2021 - Injection + references: + - https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html + subcategory: + - vuln technology: - - kotlin - pattern: java.sql.DriverManager.getConnection($URI, $USR, ""); - severity: ERROR - - id: kotlin_perm_rule-DangerousPermissions - languages: - - kotlin - message: | - Do not grant dangerous combinations of permissions. - metadata: - category: security - confidence: HIGH - cwe: CWE-277 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Insecure inherited permissions - patterns: - - pattern-either: - - patterns: + - react + mode: taint + pattern-sanitizers: + - patterns: + - pattern-either: - pattern-inside: | - $PC = $X.getPermissions(...) + import $S from "underscore.string" ... - - pattern: $PC.add($PERMISSION) - - pattern: | - $REFVAR = $PERMISSION - ...; - ($PC: PermissionCollection).add($REFVAR) - - pattern: '($PC: PermissionCollection).add($PERMISSION)' - - metavariable-pattern: - metavariable: $PERMISSION - pattern-either: - - pattern: ReflectPermission("suppressAccessChecks") - - pattern: RuntimePermission("createClassLoader") - severity: WARNING - - id: kotlin_perm_rule-OverlyPermissiveFilePermissionInline - languages: - - kotlin - message: | - Overly permissive file permission - metadata: - category: security - confidence: HIGH - cwe: CWE-732 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Incorrect permission assignment for critical resource - patterns: - - pattern-either: - - pattern: java.nio.file.Files.setPosixFilePermissions(..., java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING")); - - pattern: | - $PERMISSIONS = java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING"); - ... - java.nio.file.Files.setPosixFilePermissions(..., $PERMISSIONS); - - metavariable-regex: - metavariable: $PERM_STRING - regex: '[rwx-]{6}[rwx]{1,}' - severity: WARNING - - id: kotlin_script_rule-ScriptInjection - languages: - - kotlin - message: | - The software constructs all or part of a code segment using externally-influenced - input from an upstream component, but it does not neutralize or incorrectly - neutralizes special elements that could modify the syntax or behavior of the - intended code segment. - metadata: - category: security - cwe: CWE-94 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code ('Code Injection') - mode: taint - pattern-sinks: + - pattern-inside: | + import * as $S from "underscore.string" + ... + - pattern-inside: | + import $S from "underscore.string" + ... + - pattern-inside: | + $S = require("underscore.string") + ... + - pattern-either: + - pattern: $S.escapeHTML(...) - patterns: - - patterns: + - pattern-either: - pattern-inside: | - $ENGINE = $F.getEngineByExtension(...) + import $S from "dompurify" ... - - pattern: $ENGINE.eval($ARG, ...); - - pattern-not: $ENGINE.eval("..."); - - pattern-not: '$ENGINE.eval("...", ($BINDING: javax.script.Bindings));' - - patterns: - - pattern: '($ENGINE: javax.script.ScriptEngine).eval($ARG, ...);' - - pattern-not: '($ENGINE: javax.script.ScriptEngine).eval("...");' - - pattern-not: '($ENGINE: javax.script.ScriptEngine).eval("...", ($BINDING: javax.script.Bindings));' - - pattern: '($INVC: javax.script.Invocable).invokeFunction(..., $ARG)' - - pattern: '($INVC: javax.script.Invocable).invokeMethod(..., $ARG)' - pattern-sources: + - pattern-inside: | + import { ..., $S,... } from "dompurify" + ... + - pattern-inside: | + import * as $S from "dompurify" + ... + - pattern-inside: | + $S = require("dompurify") + ... + - pattern-inside: | + import $S from "isomorphic-dompurify" + ... + - pattern-inside: | + import * as $S from "isomorphic-dompurify" + ... + - pattern-inside: | + $S = require("isomorphic-dompurify") + ... + - pattern-either: + - patterns: + - pattern-inside: | + $VALUE = $S(...) + ... + - pattern: $VALUE.sanitize(...) + - patterns: + - pattern-inside: | + $VALUE = $S.sanitize + ... + - pattern: $S(...) + - pattern: $S.sanitize(...) + - pattern: $S(...) - patterns: - - pattern-inside: 'fun $FUNC(..., $VAR: String, ...) { ... }' - - pattern: $VAR - severity: ERROR - - id: kotlin_smtp_rule-InsecureSmtp - languages: - - kotlin - message: | - Server identity verification is disabled when making SSL connections. - metadata: - category: security - cwe: CWE-297 - owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: CRITICAL - shortDescription: Improper validation of certificate with host mismatch - patterns: - - pattern-either: - - pattern-inside: | - $E = org.apache.commons.mail.SimpleEmail(...) - ... - - pattern-inside: | - $E = org.apache.commons.mail.Email(...) - ... - - pattern-inside: | - $E = org.apache.commons.mail.MultiPartEmail(...) - ... - - pattern-inside: | - $E = org.apache.commons.mail.HtmlEmail(...) - ... - - pattern-inside: | - $E = org.apache.commons.mail.ImageHtmlEmail(...) - ... - - pattern-not: | - $E.setSSLOnConnect(true) - ... - $E.setSSLCheckServerIdentity(true) - severity: ERROR - - id: kotlin_smtp_rule-SmtpClient - languages: - - kotlin - message: | - Simple Mail Transfer Protocol (SMTP) is a the text based protocol used for - email delivery. Like with HTTP, headers are separate by new line separator. If - kuser input is place in a header line, the application should remove or replace - new line characters (CR / LF). You should use a safe wrapper such as Apache - Common Email and Simple Java Mail which filter special characters that can lead - to header injection. - metadata: - category: security - cwe: CWE-77 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of special elements used in a command - patterns: - - pattern-inside: | - $M = MimeMessage(...); - ... - - pattern-either: - - patterns: - - pattern-either: - - pattern: $M.setSubject($VAR) - - pattern: $M.addHeader($ARG, $VAR) - - pattern: $M.addHeader($VAR, $ARG) - - pattern: $M.setDescription($VAR) - - pattern: $M.setDisposition($VAR) - - metavariable-regex: - metavariable: $VAR - regex: ^[a-zA-Z_$][a-zA-Z0-9_$]*$ - - patterns: - - pattern-either: - - pattern: $M.setSubject($OBJ.$GETTER(...)) - - pattern: $M.setSubject($OBJ.$GETTER(...) + ...) - - pattern: $M.setSubject(... + $OBJ.$GETTER(...)) - - pattern: $M.setSubject(... + $OBJ.$GETTER(...) + ...) - - pattern: $M.addHeader($ARG, $OBJ.$GETTER(...)) - - pattern: $M.addHeader($ARG, $OBJ.$GETTER(...) + ...) - - pattern: $M.addHeader($ARG, ... + $OBJ.$GETTER(...)) - - pattern: $M.addHeader($ARG, ... + $OBJ.$GETTER(...) + ...) - - pattern: $M.addHeader($OBJ.$GETTER(...), $ARG) - - pattern: $M.addHeader($OBJ.$GETTER(...) + ..., $ARG) - - pattern: $M.addHeader(... + $OBJ.$GETTER(...), $ARG) - - pattern: $M.addHeader(... + $OBJ.$GETTER(...) + ..., $ARG) - - pattern: $M.setDescription($OBJ.$GETTER(...)) - - pattern: $M.setDisposition($OBJ.$GETTER(...) + ...) - - pattern: $M.setDisposition(... + $OBJ.$GETTER(...)) - - pattern: $M.setDisposition(... + $OBJ.$GETTER(...) + ...) - - metavariable-regex: - metavariable: $GETTER - regex: ^get - severity: ERROR - - id: kotlin_ssrf_rule-SSRF - languages: - - kotlin - message: | - Server-Side Request Forgery occur when a web server executes a request to a user supplied - destination parameter that is not validated. Such vulnerabilities could allow an attacker to - access internal services or to launch attacks from your web server. - metadata: - category: security - cwe: CWE-918 - owasp: - - A1:2017-Injection - - A10:2021-Server-Side Request Forgery - security-severity: CRITICAL - shortDescription: Server-Side Request Forgery (SSRF) - pattern-either: + - pattern-either: + - pattern-inside: | + import $S from 'xss'; + ... + - pattern-inside: | + import * as $S from 'xss'; + ... + - pattern-inside: | + $S = require("xss") + ... + - pattern: $S(...) - patterns: - pattern-either: - pattern-inside: | - import java.net.*; + import $S from 'sanitize-html'; ... - pattern-inside: | - import java.net.URL; + import * as $S from "sanitize-html"; ... - pattern-inside: | - import java.net.URI; + $S = require("sanitize-html") ... - - pattern: $TYPE(...). ... .$FUNC - - pattern-not: $TYPE("..."). ... .$FUNC - - metavariable-pattern: - metavariable: $FUNC - pattern-either: - - pattern: connect - - pattern: GetContent - - pattern: openConnection - - pattern: openStream - - pattern: getContent - - pattern: content - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: URL - - pattern: java.net.URL - - pattern: URI - - pattern: java.net.URI + - pattern: $S(...) - patterns: - pattern-either: - pattern-inside: | - import java.net.*; + $S = new Remarkable() ... + - pattern: $S.render(...) + pattern-sinks: + - patterns: + - pattern-either: - pattern-inside: | - import java.net.InetSocketAddress; + $BODY = $REACT.useRef(...) ... - - pattern: | - InetSocketAddress(..., $PORT) - - pattern-not: | - InetSocketAddress("...", $PORT) - severity: ERROR - - id: kotlin_strings_rule-BadHexConversion - languages: - - kotlin - message: | - When converting a byte array containing a hash signature to a human readable string, a - conversion mistake can be made if the array is read byte by byte. - metadata: - category: security - confidence: HIGH - cwe: CWE-704 - owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Incorrect type conversion or cast - patterns: - - pattern-inside: | - $B_ARR = ($MD: java.security.MessageDigest).digest(...); - ... - - pattern-either: - - pattern: | - for($B in $B_ARR) { - ... - $B_TOSTR - } - - pattern: | - while(...) { - ... - $B_TOSTR - } - - pattern: | - do { - ... - $B_TOSTR - } while(...) - - metavariable-pattern: - metavariable: $B_TOSTR - patterns: - - pattern-either: - - pattern: java.lang.Integer.toHexString($B_TOINT) - - pattern: Integer.toHexString($B_TOINT) - - pattern: $B_TOINT.toHexString(...) - - metavariable-pattern: - metavariable: $B_TOINT - pattern-either: - - pattern: $B_ARR[...].toInt() - - pattern: $B_ARR[...] - - pattern: $B.toInt() - - pattern: $B + - pattern-inside: | + $BODY = useRef(...) + ... + - pattern-inside: | + $BODY = findDOMNode(...) + ... + - pattern-inside: | + $BODY = createRef(...) + ... + - pattern-inside: | + $BODY = $REACT.findDOMNode(...) + ... + - pattern-inside: | + $BODY = $REACT.createRef(...) + ... + - pattern-either: + - pattern: "$BODY. ... .$HTML = $SINK \n" + - pattern: "$BODY.$HTML = $SINK \n" + - metavariable-regex: + metavariable: $HTML + regex: (innerHTML|outerHTML) + - focus-metavariable: $SINK + - patterns: + - pattern-either: + - pattern: ReactDOM.findDOMNode(...).$HTML = $SINK + - metavariable-regex: + metavariable: $HTML + regex: (innerHTML|outerHTML) + - focus-metavariable: $SINK + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + function ...({..., $X, ...}) { ... } + - pattern-inside: | + function ...(..., $X, ...) { ... } + - focus-metavariable: $X + - pattern-either: + - pattern: $X.$Y + - pattern: $X[...] severity: WARNING - - id: kotlin_strings_rule-FormatStringManipulation + - id: typescript.react.security.react-insecure-request.react-insecure-request languages: - - kotlin - message: | - Allowing user input to control format parameters could enable an attacker to cause exceptions - to be thrown or leak information.Attackers may be able to modify the format string argument, - such that an exception is thrown. If this exception is left uncaught, it may crash the - application. Alternatively, if sensitive information is used within the unused arguments, - attackers may change the format string to reveal this information. + - typescript + - javascript + message: Unencrypted request over HTTP detected. metadata: category: security - confidence: HIGH - cwe: CWE-134 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: LOW owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Use of externally-controlled format string - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $INPUT = ($REQ: HttpServletRequest).getParameter(...) - ... - - pattern-inside: | - $FORMAT_STR = ... + $INPUT - ... - - patterns: + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://www.npmjs.com/package/axios + subcategory: + - vuln + technology: + - react + vulnerability: Insecure Transport + pattern-either: + - patterns: + - pattern-either: - pattern-inside: | - $INPUT = ($REQ: HttpServletRequest).getParameter(...) + import $AXIOS from 'axios'; ... + $AXIOS.$METHOD(...) - pattern-inside: | - $FORMAT_STR = ... + $INPUT + ... + $AXIOS = require('axios'); ... - - pattern-inside: | - $FORMAT_STR = ... + ($REQ: HttpServletRequest).getParameter(...) + ... - ... - - pattern-inside: | - $FORMAT_STR = ... + ($REQ: HttpServletRequest).getParameter(...) - ... - - pattern-either: - - pattern: String.format($FORMAT_STR, ...) - - pattern: String.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) - - patterns: + $AXIOS.$METHOD(...) + - pattern-either: + - pattern: $AXIOS.get("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.post("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.delete("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.head("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.patch("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.put("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - pattern: $AXIOS.options("=~/[Hh][Tt][Tt][Pp]:\/\/.*/",...) + - patterns: + - pattern-either: - pattern-inside: | - $F = java.util.Formatter(...) + import $AXIOS from 'axios'; ... - - pattern-either: - - pattern: $F.format($FORMAT_STR, ...) - - pattern: $F.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) - - pattern: '($F: java.io.PrintStream).printf($FORMAT_STR, ...)' - - pattern: '($F: java.io.PrintStream).printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...)' - - pattern: '($F: java.io.PrintStream).format($FORMAT_STR, ...)' - - pattern: '($F: java.io.PrintStream).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...)' - - pattern: System.out.printf($FORMAT_STR, ...) - - pattern: System.out.printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...) - - pattern: System.out.format($FORMAT_STR, ...) - - pattern: System.out.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) + $AXIOS(...) + - pattern-inside: | + $AXIOS = require('axios'); + ... + $AXIOS(...) + - pattern-either: + - pattern: '$AXIOS({url: "=~/[Hh][Tt][Tt][Pp]:\/\/.*/"}, ...)' + - pattern: | + $OPTS = {url: "=~/[Hh][Tt][Tt][Pp]:\/\/.*/"} + ... + $AXIOS($OPTS, ...) + - pattern: fetch("=~/[Hh][Tt][Tt][Pp]:\/\/.*/", ...) severity: ERROR - - id: kotlin_strings_rule-ModifyAfterValidation + - id: yaml.argo.security.argo-workflow-parameter-command-injection.argo-workflow-parameter-command-injection languages: - - kotlin - message: | - CERT: IDS11-J. Perform any string modifications before validation + - yaml + message: Using input or workflow parameters in here-scripts can lead to command injection or code injection. Convert the parameters to env variables instead. metadata: category: security - confidence: HIGH - cwe: CWE-182 + confidence: MEDIUM + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + impact: HIGH + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Collapse of data into unsafe value + - A03:2021 – Injection + references: + - https://github.com/argoproj/argo-workflows/issues/5061 + - https://github.com/argoproj/argo-workflows/issues/5114#issue-808865370 + subcategory: + - vuln + technology: + - ci + - argo patterns: - pattern-inside: | - $PATTERN = Pattern.compile(...) - ... - - pattern-inside: | - $PATTERN.matcher($VAR) + apiVersion: $VERSION ... + - metavariable-regex: + metavariable: $VERSION + regex: (argoproj.io.*) - pattern-either: - - pattern: | - $VAR + $OTHER - patterns: - - pattern: | - $VAR.$METHOD(...) + - pattern-inside: "command:\n ...\n - python\n ...\n...\nsource: \n $SCRIPT\n" + - focus-metavariable: $SCRIPT + - metavariable-pattern: + language: python + metavariable: $SCRIPT + patterns: + - pattern: | + $FUNC(..., $PARAM, ...) + - metavariable-pattern: + metavariable: $PARAM + pattern-either: + - pattern-regex: (.*{{.*inputs.parameters.*}}.*) + - pattern-regex: (.*{{.*workflow.parameters.*}}.*) + - patterns: + - pattern-inside: "command:\n ...\n - $LANG\n ...\n...\nsource: \n $SCRIPT\n" - metavariable-regex: - metavariable: $METHOD - regex: (replace|replaceAll|replaceFirst|concat) - severity: WARNING - - id: kotlin_strings_rule-NormalizeAfterValidation + metavariable: $LANG + regex: (bash|sh) + - focus-metavariable: $SCRIPT + - metavariable-pattern: + language: bash + metavariable: $SCRIPT + patterns: + - pattern: | + $CMD ... $PARAM ... + - metavariable-pattern: + metavariable: $PARAM + pattern-either: + - pattern-regex: (.*{{.*inputs.parameters.*}}.*) + - pattern-regex: (.*{{.*workflow.parameters.*}}.*) + - patterns: + - pattern-inside: | + container: + ... + command: $LANG + ... + args: $PARAM + - metavariable-regex: + metavariable: $LANG + regex: .*(sh|bash|ksh|csh|tcsh|zsh).* + - metavariable-pattern: + metavariable: $PARAM + pattern-either: + - pattern-regex: (.*{{.*inputs.parameters.*}}.*) + - pattern-regex: (.*{{.*workflow.parameters.*}}.*) + - focus-metavariable: $PARAM + severity: ERROR + - fix: | + false + id: yaml.docker-compose.security.privileged-service.privileged-service languages: - - kotlin - message: | - IDS01-J. Normalize strings before validating them + - yaml + message: Service '$SERVICE' is running in privileged mode. This grants the container the equivalent of root capabilities on the host machine. This can lead to container escapes, privilege escalation, and other security concerns. Remove the 'privileged' key to disable this capability. metadata: category: security confidence: HIGH - cwe: CWE-180 + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: HIGH owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: 'Incorrect behavior order: validate before canonicalize' + - A06:2017 - Security Misconfiguration + - A05:2021 - Security Misconfiguration + references: + - https://www.trendmicro.com/en_us/research/19/l/why-running-a-privileged-container-in-docker-is-a-bad-idea.html + - https://containerjournal.com/topics/container-security/why-running-a-privileged-container-is-not-a-good-idea/ + subcategory: + - vuln + technology: + - docker-compose patterns: - - pattern: | - $Y = java.util.regex.Pattern.compile("[<>]"); - ... - $Y.matcher($VAR); + - pattern-inside: | + version: ... ... - java.text.Normalizer.normalize($VAR, ...); - severity: WARNING - - id: kotlin_templateinjection_rule-TemplateInjection - languages: - - kotlin - message: | - A malicious user in control of a template can run malicious code on the - server-side. Velocity templates should be seen as scripts. - metadata: - category: security - cwe: CWE-94 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper control of generation of code ('Code Injection') - pattern-either: - - patterns: - - pattern: org.apache.velocity.app.Velocity.evaluate(..., $VAR) - - pattern-not: org.apache.velocity.app.Velocity.evaluate(..., "...") - - patterns: - - pattern-not-inside: | - $C = ($CFG: freemarker.template.Configuration).getTemplate("..."); - ... - - pattern-inside: | - $C = ($CFG: freemarker.template.Configuration).getTemplate($IN); - ... - - pattern: $C.process(...) - - patterns: - - pattern-inside: | - import com.mitchellbosecke.pebble.PebbleEngine; - ... - - pattern-inside: | - $C = $T.getTemplate($IN); - ... - - pattern-not-inside: | - $C = $T.getTemplate("..."); + services: + ... + $SERVICE: ... - - pattern: $C.evaluate(...) - severity: ERROR - - id: kotlin_unsafe_rule-ExternalConfigControl + privileged: $TRUE + - focus-metavariable: $TRUE + - metavariable-regex: + metavariable: $TRUE + regex: (true) + severity: WARNING + - id: yaml.github-actions.security.allowed-unsecure-commands.allowed-unsecure-commands languages: - - kotlin - message: | - Allowing external control of system settings can disrupt service or cause an application to - behave in unexpected, and potentially malicious ways. An attacker could cause an error by - providing a nonexistent catalog name or connect to an unauthorized portion of the database. + - yaml + message: The environment variable `ACTIONS_ALLOW_UNSECURE_COMMANDS` grants this workflow permissions to use the `set-env` and `add-path` commands. There is a vulnerability in these commands that could result in environment variables being modified by an attacker. Depending on the use of the environment variable, this could enable an attacker to, at worst, modify the system path to run a different command than intended, resulting in arbitrary code execution. This could result in stolen code or secrets. Don't use `ACTIONS_ALLOW_UNSECURE_COMMANDS`. Instead, use Environment Files. See https://github.com/actions/toolkit/blob/main/docs/commands.md#environment-files for more information. metadata: category: security - cwe: CWE-15 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: External control of system or configuration setting + confidence: MEDIUM + cwe: + - 'CWE-749: Exposed Dangerous Method or Function' + impact: MEDIUM + likelihood: LOW + owasp: A06:2017 - Security Misconfiguration + references: + - https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/ + - https://github.com/actions/toolkit/security/advisories/GHSA-mfwh-5m23-j46w + - https://github.com/actions/toolkit/blob/main/docs/commands.md#environment-files + subcategory: + - vuln technology: - - kotlin + - github-actions patterns: - - metavariable-pattern: - metavariable: $GET_PARAMETER - pattern-either: - - pattern: '($REQ: HttpServletRequest).getParameter' - - pattern: '($REQ: HttpServletRequest?)?.getParameter' - - metavariable-pattern: - metavariable: $SET_CATALOG - pattern-either: - - pattern: '($CONN: java.sql.Connection).setCatalog' - - pattern: '($CONN: java.sql.Connection?)?.setCatalog' - - pattern: |- - $TAINTED = $GET_PARAMETER(...) - ... - $SET_CATALOG($TAINTED) + - pattern-either: + - patterns: + - pattern-inside: '{env: ...}' + - pattern: 'ACTIONS_ALLOW_UNSECURE_COMMANDS: true' severity: WARNING - - id: rules_lgpl_kotlin_other_rule-android-kotlin-webview-debug + - id: yaml.github-actions.security.github-script-injection.github-script-injection languages: - - kotlin - message: "Remote WebView debugging is enabled.This can introduce security \nrisks as it allows remote debugging tools, such as Chrome DevTools, \nto inspect and manipulate the WebView content. This can potentially \nexpose sensitive information, including user data, session tokens, \nand other confidential data, to unauthorized parties.\n\nTo fix this security issue, you should disable remote WebView \ndebugging in production builds of your app. Here's how you can do it:\n```\nimport WebKit\n\nclass ViewController: UIViewController {\n\n override func viewDidLoad() {\n super.viewDidLoad()\n\n // Disable remote WebView debugging in production builds\n #if DEBUG\n WebViewConfiguration.shared().preferences.setValue(true, forKey: \"developerExtrasEnabled\")\n #else\n WebViewConfiguration.shared().preferences.setValue(false, forKey: \"developerExtrasEnabled\")\n #endif\n\n // Other setup code...\n }\n\n // Other methods...\n}\n```\n" + - yaml + message: 'Using variable interpolation `${{...}}` with `github` context data in a `actions/github-script`''s `script:` step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. `github` context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with `env:` to store the data and use the environment variable in the `run:` script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".' metadata: category: security - cwe: CWE-489 + confidence: HIGH + cwe: + - 'CWE-94: Improper Control of Generation of Code (''Code Injection'')' + cwe2022-top25: true + impact: HIGH + likelihood: HIGH owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Leftover debug code + - A03:2021 - Injection + references: + - https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections + - https://securitylab.github.com/research/github-actions-untrusted-input/ + - https://github.com/actions/github-script + subcategory: + - vuln + technology: + - github-actions patterns: - - pattern: | - $X.setWebContentsDebuggingEnabled(true) + - pattern-inside: 'steps: [...]' - pattern-inside: | - WebView + uses: $ACTION ... - severity: WARNING - - id: kotlin_xml_rule-SAMLIgnoreComments - languages: - - kotlin - message: | - Ignoring XML comments in SAML may lead to authentication bypass - metadata: - category: security - cwe: CWE-1390 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: MEDIUM - shortDescription: Weak authentication - pattern: '($POOL: org.opensaml.xml.parse.BasicParserPool).setIgnoreComments(false);' - severity: WARNING - - id: kotlin_xml_rule-XmlDecoder + - pattern-inside: | + with: + ... + script: ... + ... + - pattern: 'script: $SHELL' + - metavariable-regex: + metavariable: $ACTION + regex: actions/github-script@.* + - metavariable-pattern: + language: generic + metavariable: $SHELL + patterns: + - pattern-either: + - pattern: ${{ github.event.issue.title }} + - pattern: ${{ github.event.issue.body }} + - pattern: ${{ github.event.pull_request.title }} + - pattern: ${{ github.event.pull_request.body }} + - pattern: ${{ github.event.comment.body }} + - pattern: ${{ github.event.review.body }} + - pattern: ${{ github.event.review_comment.body }} + - pattern: ${{ github.event.pages. ... .page_name}} + - pattern: ${{ github.event.head_commit.message }} + - pattern: ${{ github.event.head_commit.author.email }} + - pattern: ${{ github.event.head_commit.author.name }} + - pattern: ${{ github.event.commits ... .author.email }} + - pattern: ${{ github.event.commits ... .author.name }} + - pattern: ${{ github.event.pull_request.head.ref }} + - pattern: ${{ github.event.pull_request.head.label }} + - pattern: ${{ github.event.pull_request.head.repo.default_branch }} + - pattern: ${{ github.head_ref }} + - pattern: ${{ github.event.inputs ... }} + severity: ERROR + - id: yaml.github-actions.security.run-shell-injection.run-shell-injection languages: - - kotlin - message: | - Avoid using XMLDecoder to parse content from an untrusted source. + - yaml + message: 'Using variable interpolation `${{...}}` with `github` context data in a `run:` step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. `github` context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with `env:` to store the data and use the environment variable in the `run:` script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".' metadata: category: security - cwe: CWE-502 + confidence: HIGH + cwe: + - 'CWE-78: Improper Neutralization of Special Elements used in an OS Command (''OS Command Injection'')' + cwe2021-top25: true + cwe2022-top25: true + impact: HIGH + likelihood: HIGH owasp: - - A8:2017-Insecure Deserialization - - A08:2021-Software and Data Integrity Failures - security-severity: MEDIUM - shortDescription: Deserialization of untrusted data + - A01:2017 - Injection + - A03:2021 - Injection + references: + - https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections + - https://securitylab.github.com/research/github-actions-untrusted-input/ + subcategory: + - vuln + technology: + - github-actions patterns: - - pattern-either: - - pattern: '($D: java.beans.XMLDecoder).readObject()' - - patterns: - - pattern: $D.readObject() - - pattern-inside: | - $D = XMLDecoder(...) - ... - - pattern-not: - pattern-either: - - patterns: - - pattern-inside: | - $DEC = java.beans.XMLDecoder(..., $CL) - ... - - pattern: $DEC.readObject() - - metavariable-pattern: - metavariable: $CL - patterns: - - pattern: | - object : ClassLoader() { - ... - fun loadClass(name: String, resolve: Boolean): $RET { - if($X){ - throw ... - } - ... - } - ... - } - - metavariable-pattern: - metavariable: $X - pattern-either: - - pattern: | - name != ... - - pattern: | - !$LIST.contains(name) - - patterns: - - pattern-inside: | - $CLASS_LOADER = $CL - ... - - pattern-inside: | - $DEC = java.beans.XMLDecoder(..., $CLASS_LOADER) - ... - - pattern: $DEC.readObject() - - metavariable-pattern: - metavariable: $CL - patterns: - - pattern: | - object : ClassLoader(){ - ... - fun loadClass(name: String, resolve: Boolean): $RET{ - if($X){ - throw ... - } - ... - } - ... - } - - metavariable-pattern: - metavariable: $X - pattern-either: - - pattern: | - name != ... - - pattern: | - !$LIST.contains(name) - severity: WARNING - - id: kotlin_xml_rule-XsltTransform + - pattern-inside: 'steps: [...]' + - pattern-inside: | + - run: ... + ... + - pattern: 'run: $SHELL' + - metavariable-pattern: + language: generic + metavariable: $SHELL + patterns: + - pattern-either: + - pattern: ${{ github.event.issue.title }} + - pattern: ${{ github.event.issue.body }} + - pattern: ${{ github.event.pull_request.title }} + - pattern: ${{ github.event.pull_request.body }} + - pattern: ${{ github.event.comment.body }} + - pattern: ${{ github.event.review.body }} + - pattern: ${{ github.event.review_comment.body }} + - pattern: ${{ github.event.pages. ... .page_name}} + - pattern: ${{ github.event.head_commit.message }} + - pattern: ${{ github.event.head_commit.author.email }} + - pattern: ${{ github.event.head_commit.author.name }} + - pattern: ${{ github.event.commits ... .author.email }} + - pattern: ${{ github.event.commits ... .author.name }} + - pattern: ${{ github.event.pull_request.head.ref }} + - pattern: ${{ github.event.pull_request.head.label }} + - pattern: ${{ github.event.pull_request.head.repo.default_branch }} + - pattern: ${{ github.head_ref }} + - pattern: ${{ github.event.inputs ... }} + severity: ERROR + - id: yaml.github-actions.security.third-party-action-not-pinned-to-commit-sha.third-party-action-not-pinned-to-commit-sha languages: - - kotlin - message: | - It is possible to attach malicious behavior to those style sheets. Therefore, if an attacker - can control the content or the source of the style sheet, he might be able to trigger remote - code execution. + - yaml + message: An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. metadata: category: security - cwe: CWE-91 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: XML injection (aka Blind XPath injection) - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: '($T: javax.xml.transform.TransformerFactory).newTransformer($SRC, ...)' - - pattern-inside: '($T: javax.xml.transform.Transformer).transform($SRC, ...)' - - patterns: - - pattern-inside: |- - $FACTORY = javax.xml.transform.TransformerFactory.newInstance(...) - ... - - pattern-inside: $FACTORY.newTransformer($SRC, ...) - - patterns: - - pattern-inside: |- - $FACTORY = javax.xml.transform.TransformerFactory(...) - ... - - pattern-inside: |- - $T = $FACTORY.newTransformer(...) - ... - - pattern-inside: $T.transform($SRC, ...) - - pattern: $SRC - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - fun $FUNC(...,$VAR: String, ...) { - ... - } - - pattern-either: - - pattern: FileInputStream(<... $VAR ...>); - - pattern: javaClass.getResourceAsStream(<... $VAR ...>) - - patterns: - - pattern-inside: | - class $CLZ { - var $X = "..."; - ... - } - - pattern-inside: | - fun $FUNC(...,$Y: String, ...) { - ... - } - - pattern-either: - - pattern: FileInputStream($X + $Y); - - pattern: javaClass.getResourceAsStream($X + $Y) + confidence: HIGH + cwe: + - 'CWE-1357: Reliance on Insufficiently Trustworthy Component' + - 'CWE-353: Missing Support for Integrity Check' + impact: LOW + likelihood: LOW + owasp: A06:2021 - Vulnerable and Outdated Components + references: + - https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components + - https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions + subcategory: + - vuln + technology: + - github-actions + patterns: + - pattern-inside: '{steps: ...}' + - pattern: | + uses: "$USES" + - metavariable-pattern: + language: generic + metavariable: $USES + patterns: + - pattern-not-regex: ^[.]/ + - pattern-not-regex: ^actions/ + - pattern-not-regex: ^github/ + - pattern-not-regex: '@[0-9a-f]{40}$' + - pattern-not-regex: ^docker://.*@sha256:[0-9a-f]{64}$ severity: WARNING - - id: kotlin_xpathi_rule-XpathInjection + - id: yaml.github-actions.security.workflow-run-target-code-checkout.workflow-run-target-code-checkout languages: - - kotlin - message: | - The input values included in SQL queries need to be passed in safely. Bind - variables in prepared statements can be used to easily mitigate the risk of - SQL injection. + - yaml + message: This GitHub Actions workflow file uses `workflow_run` and checks out code from the incoming pull request. When using `workflow_run`, the Action runs in the context of the target repository, which includes access to all repository secrets. Normally, this is safe because the Action only runs code from the target repository, not the incoming PR. However, by checking out the incoming PR code, you're now using the incoming code for the rest of the action. You may be inadvertently executing arbitrary code from the incoming PR with access to repository secrets, which would let an attacker steal repository secrets. This normally happens by running build scripts (e.g., `npm build` and `make`) or dependency installation scripts (e.g., `python setup.py install`). Audit your workflow file to make sure no code from the incoming PR is executed. Please see https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ for additional mitigations. metadata: category: security - cwe: CWE-643 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper neutralization of data within XPath expressions ('XPath Injection') - mode: taint - pattern-sanitizers: - - pattern-either: - - pattern-inside: | - $X.xPathVariableResolver = ...; - ...; - $X.compile("..."); - - pattern-inside: | - $X.setXPathVariableResolver(...); - ...; - $X.compile("..."); - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: "import javax.xml.xpath.*; \n...\n" - - pattern-inside: "import javax.xml.xpath.XPath; \n...\n" - - patterns: - - pattern-either: - - patterns: - - pattern: $X.compile($VAR) - - pattern-not: $X.compile("...") - - patterns: - - pattern: $X.evaluate($VAR, ...) - - pattern-not: $X.evaluate("...", ...) - pattern-sources: - - patterns: - - pattern-inside: | - fun $FUNC(..., $VAR: $T, ...) { + confidence: MEDIUM + cwe: 'CWE-913: Improper Control of Dynamically-Managed Code Resources' + impact: MEDIUM + likelihood: MEDIUM + owasp: A01:2017 - Injection + references: + - https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ + - https://github.com/justinsteven/advisories/blob/master/2021_github_actions_checkspelling_token_leak_via_advice_symlink.md + - https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability + subcategory: + - vuln + technology: + - github-actions + patterns: + - pattern-inside: | + on: + ... + workflow_run: ... + ... + ... + - pattern-inside: | + jobs: + ... + $JOBNAME: + ... + steps: ... - } - - pattern: $VAR - severity: ERROR - - id: kotlin_xss_rule-WicketXSS + - pattern: | + ... + uses: "$ACTION" + with: + ... + ref: $EXPR + - metavariable-regex: + metavariable: $ACTION + regex: actions/checkout@.* + - metavariable-pattern: + language: generic + metavariable: $EXPR + patterns: + - pattern: ${{ github.event.workflow_run ... }} + severity: WARNING + - fix: | + securityContext: + allowPrivilegeEscalation: false + $NAME + id: yaml.kubernetes.security.allow-privilege-escalation-no-securitycontext.allow-privilege-escalation-no-securitycontext languages: - - kotlin - message: | - Disabling HTML escaping put the application at risk for Cross-Site Scripting (XSS). + - yaml + message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. By adding a `securityContext` to your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. metadata: category: security - cwe: CWE-79 + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag + subcategory: + - vuln + technology: + - kubernetes patterns: - pattern-inside: | - import org.apache.wicket.$A - ... + containers: + ... + - pattern-inside: | + - $NAME: $CONTAINER + ... - pattern: | - $OBJ.setEscapeModelStrings(false); + image: ... + ... + - pattern-not: | + image: ... + ... + securityContext: + ... + - metavariable-regex: + metavariable: $NAME + regex: name + - focus-metavariable: $NAME severity: WARNING - - id: kotlin_xss_rule-XSSReqParamToServletWriter + - fix: | + false + id: yaml.kubernetes.security.allow-privilege-escalation-true.allow-privilege-escalation-true languages: - - kotlin - message: | - Servlet reflected cross site scripting vulnerability + - yaml + message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. In the container `$CONTAINER` this parameter is set to `true` which makes this container much more vulnerable to privelege escalation attacks. metadata: category: security - cwe: CWE-79 + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: MEDIUM - shortDescription: Improper neutralization of input during web page generation ('Cross-site Scripting') + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag + subcategory: + - vuln technology: - - kotlin - mode: taint - pattern-sanitizers: - - patterns: - - pattern-inside: org.owasp.encoder.Encode.forHtml($TAINTED); - - pattern: $TAINTED - pattern-sinks: - - patterns: - - pattern-inside: 'fun $FUNC(..., $RES: HttpServletResponse , ...) {...}' - - pattern-inside: | - $WRITER = $RES.getWriter(); - ... - - pattern: $WRITER.write($DATA,...); - - pattern: $DATA - - patterns: - - pattern-inside: 'fun $FUNC(..., $RES: HttpServletResponse , ...) {...}' - - pattern: $RES.getWriter().write($DATA,...); - - pattern: $DATA - pattern-sources: - - patterns: - - pattern-inside: 'fun $FUNC(..., $REQ: HttpServletRequest , ...) {...}' - - pattern: $REQ.getParameter(...); + - kubernetes + patterns: + - pattern-inside: | + containers: + ... + - pattern-inside: | + - name: $CONTAINER + ... + - pattern-inside: | + image: ... + ... + - pattern-inside: | + securityContext: + ... + - pattern: | + allowPrivilegeEscalation: $TRUE + - metavariable-pattern: + metavariable: $TRUE + pattern: | + true + - focus-metavariable: $TRUE severity: WARNING - - id: kotlin_xxe_rule-SaxParserXXE + - fix: | + securityContext: + allowPrivilegeEscalation: false # + id: yaml.kubernetes.security.allow-privilege-escalation.allow-privilege-escalation languages: - - kotlin - message: | - XML External Entity (XXE) attacks can occur when an XML parser supports XML - entities while processing XML received from an untrusted source. + - yaml + message: In Kubernetes, each pod runs in its own isolated environment with its own set of security policies. However, certain container images may contain `setuid` or `setgid` binaries that could allow an attacker to perform privilege escalation and gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container in the pod, with the parameter `allowPrivilegeEscalation` set to `false`. This will prevent the container from running any privileged processes and limit the impact of any potential attacks. By adding the `allowPrivilegeEscalation` parameter to your the `securityContext`, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. metadata: category: security - cwe: CWE-611 + confidence: MEDIUM + cwe: + - 'CWE-732: Incorrect Permission Assignment for Critical Resource' + cwe2021-top25: true + impact: MEDIUM + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper restriction of XML external entity reference ('XXE') + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-4-add-no-new-privileges-flag + subcategory: + - vuln + technology: + - kubernetes patterns: - pattern-inside: | - $SF = SAXParserFactory.newInstance() + containers: + ... + - pattern-inside: | + - name: $CONTAINER + ... + - pattern: | + image: ... ... - - pattern-not-inside: | - $SF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + - pattern-inside: | + image: ... ... + $SC: + ... + - metavariable-regex: + metavariable: $SC + regex: ^(securityContext)$ - pattern-not-inside: | - $SF.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - ... - - pattern-inside: | - $P = $SFP.newSAXParser(); + image: ... ... - - pattern: $P.parse(...); - severity: ERROR - - id: kotlin_xxe_rule-XMLRdr + securityContext: + ... + allowPrivilegeEscalation: $VAL + - focus-metavariable: $SC + severity: WARNING + - id: yaml.kubernetes.security.exposing-docker-socket-hostpath.exposing-docker-socket-hostpath languages: - - kotlin - message: | - XML External Entity (XXE) attacks can occur when an XML parser supports XML - entities while processing XML received from an untrusted source. + - yaml + message: Exposing host's Docker socket to containers via a volume. The owner of this socket is root. Giving someone access to it is equivalent to giving unrestricted root access to your host. Remove 'docker.sock' from hostpath to prevent this. metadata: category: security - cwe: CWE-611 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper restriction of XML external entity reference ('XXE') + confidence: MEDIUM + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: HIGH + likelihood: LOW + references: + - https://kubernetes.io/docs/concepts/storage/volumes/#hostpath + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#volumes-and-file-systems + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-1-do-not-expose-the-docker-daemon-socket-even-to-the-containers + subcategory: + - vuln + technology: + - kubernetes patterns: - pattern-inside: | - $R = XMLReaderFactory.createXMLReader() - ... - - pattern-not-inside: | - $R.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) - ... - - pattern: $R.parse(...) - severity: ERROR - - id: kotlin_xxe_rule-XMLStreamRdr + volumes: + ... + - pattern: | + hostPath: + ... + path: /var/run/docker.sock + severity: WARNING + - id: yaml.kubernetes.security.legacy-api-clusterrole-excessive-permissions.legacy-api-clusterrole-excessive-permissions languages: - - kotlin - message: | - XML External Entity (XXE) attacks can occur when an XML parser supports XML - entities while processing XML received from an untrusted source. + - yaml + message: 'Semgrep detected a Kubernetes core API ClusterRole with excessive permissions. Attaching excessive permissions to a ClusterRole associated with the core namespace allows the V1 API to perform arbitrary actions on arbitrary resources attached to the cluster. Prefer explicit allowlists of verbs/resources when configuring the core API namespace. ' metadata: category: security - cwe: CWE-611 + confidence: HIGH + cwe: + - 'CWE-269: Improper Privilege Management' + cwe2021-top25: false + impact: HIGH + likelihood: MEDIUM owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: CRITICAL - shortDescription: Improper restriction of XML external entity reference ('XXE') + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole + - https://kubernetes.io/docs/concepts/security/rbac-good-practices/#general-good-practice + - https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#api-groups + subcategory: + - vuln + technology: + - kubernetes patterns: + - pattern: | + "*" - pattern-inside: | - $SF = XMLInputFactory.newFactory(); - ... - - pattern-not-inside: | - $SF.setProperty(XMLInputFactory.SUPPORT_DTD, false); + resources: $A ... - - pattern-not-inside: | - $SF.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); + - pattern-inside: | + verbs: $A ... - - pattern-not-inside: | - $SF.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); + - pattern-inside: | + - apiGroups: [""] + ... + - pattern-inside: | + apiVersion: rbac.authorization.k8s.io/v1 ... - - pattern-not-inside: | - $SF.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); + - pattern-inside: | + kind: ClusterRole ... - - pattern: $SF.createXMLStreamReader(...) - severity: ERROR - - id: rules_lgpl_swift_other_rule-ios-biometric-acl + severity: WARNING + - id: yaml.kubernetes.security.privileged-container.privileged-container languages: - - swift - message: "Weak biometric ACL flag is associated with a key stored in Keychain. \nWith '.biometryAny/.userPresence/.touchIDAny' flag, an attacker with \nthe ability to add a biometry to the device can authenticate as the \nuser. It is recommended to use more specific and secure authentication \nmechanisms like '.biometryCurrentSet' and '.touchIDCurrentSet'.\n\nHere's an example of how to fix the problem by using .biometryCurrentSet \nfor biometric authentication in Swift:\n```\nimport LocalAuthentication\n\n// Create an instance of LAContext for biometric authentication\nlet context = LAContext()\n\n// Check if biometric authentication is available\nif context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {\n // Use biometryCurrentSet for biometric authentication\n context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, \n localizedReason: \"Authenticate with biometrics\", \n reply: { success, error in\n if success {\n print(\"Biometric authentication successful.\")\n // Proceed with authenticated actions\n } else {\n print(\"Biometric authentication failed: \n \\(error?.localizedDescription ?? \"Unknown error\")\")\n // Handle authentication failure\n }\n })\n} else {\n print(\"Biometric authentication not available.\")\n // Fallback to alternative authentication method\n}\n\n```\n" + - yaml + message: Container or pod is running in privileged mode. This grants the container the equivalent of root capabilities on the host machine. This can lead to container escapes, privilege escalation, and other security concerns. Remove the 'privileged' key to disable this capability. + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: MEDIUM + likelihood: MEDIUM + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privileged + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html + subcategory: + - vuln + technology: + - kubernetes + pattern-either: + - patterns: + - pattern-inside: | + containers: + ... + - pattern: | + image: ... + ... + securityContext: + ... + privileged: true + - patterns: + - pattern-inside: | + spec: + ... + - pattern-not-inside: | + image: ... + ... + - pattern: | + privileged: true + severity: WARNING + - fix: | + true + id: yaml.kubernetes.security.run-as-non-root-unsafe-value.run-as-non-root-unsafe-value + languages: + - yaml + message: When running containers in Kubernetes, it's important to ensure that they are properly secured to prevent privilege escalation attacks. One potential vulnerability is when a container is allowed to run applications as the root user, which could allow an attacker to gain access to sensitive resources. To mitigate this risk, it's recommended to add a `securityContext` to the container, with the parameter `runAsNonRoot` set to `true`. This will ensure that the container runs as a non-root user, limiting the damage that could be caused by any potential attacks. By adding a `securityContext` to the container in your Kubernetes pod, you can help to ensure that your containerized applications are more secure and less vulnerable to privilege escalation attacks. metadata: category: security - cwe: CWE-305 + confidence: MEDIUM + cwe: + - 'CWE-250: Execution with Unnecessary Privileges' + impact: HIGH + likelihood: MEDIUM owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: CRITICAL - shortDescription: Authentication bypass by primary weakness + - A05:2021 - Security Misconfiguration + - A06:2017 - Security Misconfiguration + references: + - https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/ + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + - https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user + subcategory: + - audit + technology: + - kubernetes patterns: - pattern-either: - - pattern: .biometryAny - - pattern: .userPresence - - pattern: .touchIDAny - - pattern: SecAccessControlCreateWithFlags(...) - severity: ERROR - - id: rules_lgpl_swift_other_rule-ios-dtls1-used + - pattern: | + spec: + ... + securityContext: + ... + runAsNonRoot: $VALUE + - patterns: + - pattern-inside: | + containers: + ... + - pattern: | + image: ... + ... + securityContext: + ... + runAsNonRoot: $VALUE + - metavariable-pattern: + metavariable: $VALUE + pattern: | + false + - focus-metavariable: $VALUE + severity: INFO + - id: yaml.kubernetes.security.seccomp-confinement-disabled.seccomp-confinement-disabled languages: - - swift - message: "DTLS 1.2 should be used. Detected old version - DTLS 1.0.\nDTLS (Datagram Transport Layer Security) 1.0 suffers from \nvarious security vulnerabilities and weaknesses, as it is \nan outdated and less secure protocol compared to newer \nversions such as DTLS 1.2 or 1.3.\n\nHere's an example of how to use DTLS 1.2:\n```\nimport Network\n\n// Create a NWConnection instance with DTLS 1.2\nlet connection = NWConnection(host: NWEndpoint.Host(\"example.com\"), port: NWEndpoint.Port(\"443\"), using: .dtls)\n\n// Start the connection\nconnection.start(queue: .main)\n\n// Handle connection state changes\nconnection.stateUpdateHandler = { newState in\n switch newState {\n case .ready:\n print(\"Connection ready.\")\n // Perform data transfer or other operations\n case .failed(let error):\n print(\"Connection failed with error: \\(error)\")\n default:\n break\n }\n}\n```\n" + - yaml + message: 'Container is explicitly disabling seccomp confinement. This runs the service in an unrestricted state. Remove ''seccompProfile: unconfined'' to prevent this.' metadata: category: security - cwe: CWE-757 + confidence: MEDIUM + cwe: + - 'CWE-284: Improper Access Control' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: MEDIUM - shortDescription: Selection of less-secure algorithm during negotiation ('algorithm downgrade') + - A05:2017 - Broken Access Control + - A01:2021 - Broken Access Control + references: + - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + - https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + subcategory: + - vuln + technology: + - kubernetes patterns: - - pattern: $Y.TLSMinimumSupportedProtocolVersion - pattern-inside: | + containers: + ... + - pattern: | + image: ... ... - $X = "tls_protocol_version_t.DTLSv10" + securityContext: + ... + seccompProfile: unconfined + severity: WARNING + - id: yaml.kubernetes.security.secrets-in-config-file.secrets-in-config-file + languages: + - yaml + message: 'Secrets ($VALUE) should not be stored in infrastructure as code files. Use an alternative such as Bitnami Sealed Secrets or KSOPS to encrypt Kubernetes Secrets. ' + metadata: + category: security + confidence: MEDIUM + cwe: + - 'CWE-798: Use of Hard-coded Credentials' + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A07:2021 - Identification and Authentication Failures + references: + - https://kubernetes.io/docs/concepts/configuration/secret/ + - https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/0/CTR_Kubernetes_Hardening_Guidance_1.1_20220315.PDF + - https://docs.gitlab.com/ee/user/clusters/agent/gitops/secrets_management.html + - https://www.cncf.io/blog/2021/04/22/revealing-the-secrets-of-kubernetes-secrets/ + - https://github.com/bitnami-labs/sealed-secrets + - https://www.cncf.io/blog/2022/01/25/secrets-management-essential-when-using-kubernetes/ + - https://blog.oddbit.com/post/2021-03-09-getting-started-with-ksops/ + subcategory: + - vuln + technology: + - kubernetes + patterns: + - pattern: | + $KEY: $VALUE + - pattern-inside: | + data: ... + - pattern-inside: | + kind: Secret ... + - metavariable-regex: + metavariable: $VALUE + regex: (?i)^[aA-zZ0-9+/]+={0,2}$ + - metavariable-analysis: + analyzer: entropy + metavariable: $VALUE severity: WARNING - - id: rules_lgpl_swift_other_rule-ios-file-no-special + - id: yaml.kubernetes.security.skip-tls-verify-cluster.skip-tls-verify-cluster languages: - - swift - message: "The file has no special protections associated with it.\nUsing .noFileProtection or FileProtectionType.none for \nfile protection means that the file is not encrypted on disk, \nleaving it vulnerable to unauthorized access if the device is \ncompromised or if the file is accessed outside of the app's \nsandbox. To enhance security, it's crucial to use appropriate \nfile protection attributes based on the sensitivity of the data \nbeing stored. For sensitive data, you should use file protection \noptions that encrypt the data on disk, such as \nFileProtectionType.complete or \nFileProtectionType.completeUnlessOpen.\n\nHere's an example of how to fix the problem:\n```\nimport Foundation \n// Define the file URL\nlet fileURL = URL(fileURLWithPath: \"path/to/file\")\n// Define data to be written to the file\nlet data = \"Sensitive data\".data(using: .utf8)!\n// Write data to the file with complete file protection\ndo {\n try data.write(to: fileURL, options: .completeFileProtection)\n print(\"Data written to file with complete file protection.\")\n} catch {\n print(\"Error writing data to file: \\(error)\")\n}\n```\n" + - yaml + message: 'Cluster is disabling TLS certificate verification when communicating with the server. This makes your HTTPS connections insecure. Remove the ''insecure-skip-tls-verify: true'' key to secure communication.' metadata: category: security - cwe: CWE-312 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A3:2017-Sensitive Data Exposure - - A02:2021-Cryptographic Failures - security-severity: CRITICAL - shortDescription: Cleartext storage of sensitive information - pattern-either: - - pattern: .noFileProtection - - pattern: FileProtectionType.none - severity: ERROR - - id: rules_lgpl_swift_other_rule-ios-keychain-weak-accessibility-value + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://kubernetes.io/docs/reference/config-api/client-authentication.v1beta1/#client-authentication-k8s-io-v1beta1-Cluster + subcategory: + - vuln + technology: + - kubernetes + pattern: | + cluster: + ... + insecure-skip-tls-verify: true + severity: WARNING + - id: yaml.kubernetes.security.skip-tls-verify-service.skip-tls-verify-service languages: - - swift - message: "A key stored in the Keychain is using a weak accessibility value. \n\nkSecAttrAccessibleAlways allows access to the keychain item at all \ntimes, even when the device is locked. Storing sensitive data with \nthis accessibility option means that the data is accessible to anyone \nwho gains physical access to the device, regardless of whether it's \nlocked or not. This increases the risk of unauthorized access to \nsensitive information. kSecAttrAccessibleAfterFirstUnlock allows access\nto the keychain item only after the device has been unlocked once after\na reboot. While this provides some level of protection, the data becomes\naccessible as soon as the device is unlocked for the first time after a\nreboot. If sensitive data is stored with this accessibility option, it \ncould still be accessed by an attacker who gains physical access to the\ndevice before it's unlocked for the first time after a reboot.\n\nTo mitigate these security risks, it's important to use the appropriate \naccessibility option based on the sensitivity of the data being stored. \nFor sensitive data that should only be accessible when the device is \nunlocked, the kSecAttrAccessibleWhenUnlocked or \nkSecAttrAccessibleWhenUnlockedThisDeviceOnly \noptions should be used.\n\nHere's an example code that fixes the problem by using the \nkSecAttrAccessibleWhenUnlocked option:\n```\nimport Foundation\nimport Security\n\n// Define the data to be stored in the keychain\nlet secretData = \"superSecretData\".data(using: .utf8)!\n\n// Create query dictionary to specify the keychain item\nlet query: [String: Any] = [\n kSecClass as String: kSecClassGenericPassword,\n kSecAttrService as String: \"com.example.myApp\",\n kSecAttrAccount as String: \"userPassword\",\n kSecValueData as String: secretData,\n kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked\n]\n\n// Add the keychain item\nlet status = SecItemAdd(query as CFDictionary, nil)\nif status == errSecSuccess {\n print(\"Secret data successfully stored in keychain.\")\n} else {\n print(\"Error storing secret data in keychain: \\(status)\")\n}\n```\n" + - yaml + message: 'Service is disabling TLS certificate verification when communicating with the server. This makes your HTTPS connections insecure. Remove the ''insecureSkipTLSVerify: true'' key to secure communication.' metadata: category: security - cwe: CWE-305 + confidence: MEDIUM + cwe: + - 'CWE-319: Cleartext Transmission of Sensitive Information' + impact: MEDIUM + likelihood: MEDIUM owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: MEDIUM - shortDescription: Authentication bypass by primary weakness - pattern-either: - - pattern: kSecAttrAccessibleAlways - - pattern: kSecAttrAccessibleAfterFirstUnlock + - A03:2017 - Sensitive Data Exposure + - A02:2021 - Cryptographic Failures + references: + - https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#apiservice-v1-apiregistration-k8s-io + subcategory: + - vuln + technology: + - kubernetes + pattern: | + spec: + ... + insecureSkipTLSVerify: true severity: WARNING - - id: rules_lgpl_swift_other_rule-ios-tls3-not-used + - id: yaml.openapi.security.use-of-basic-authentication.use-of-basic-authentication languages: - - swift - message: "The app uses TLS 1.0, TLS 1.1 or TLS 1.2. TLS 1.3 should be used instead.\nTLS versions 1.1 and 1.0 were deprecated by the IETF in June 2018 due to \na number of attacks against the vulnerable versions. Use of a deprecated \nTLS version may result in the unauthorized retrieval of sensitive \ninformation. It is strongly recommended that all TLS connections\nuse TLS 1.3\n\nTLS 1.3 includes several security improvements over previous versions, such\nas stronger cryptographic algorithms and negotiation mechanisms, reducing \nthe risk of security vulnerabilities and attacks like BEAST and POODLE.\n\n\nExample using TLS 1.3:\n```\nimport Foundation\n// Create a URLSession configuration with TLS 1.3 support\nlet configuration = URLSessionConfiguration.default\nconfiguration.tlsMinimumSupportedProtocol = .TLSv13\n// Create a URLSession with the custom configuration\nlet session = URLSession(configuration: configuration) \n// Define the URL to connect to\nlet url = URL(string: \"https://example.com\")!\n// Create a data task to fetch data from the URL\nlet task = session.dataTask(with: url) { data, response, error in\n // Handle response\n if let error = error {\n print(\"Error: \\(error)\")\n return\n }\n if let httpResponse = response as? HTTPURLResponse {\n print(\"Status code: \\(httpResponse.statusCode)\")\n } \n if let data = data {\n // Process received data\n print(\"Received data: \\(data)\")\n }\n}\n// Start the data task\ntask.resume()\n```\n" + - yaml + message: Basic authentication is considered weak and should be avoided. Use a different authentication scheme, such of OAuth2, OpenID Connect, or mTLS. metadata: category: security - cwe: CWE-757 + confidence: HIGH + cwe: 'CWE-287: Improper Authentication' + impact: HIGH + likelihood: MEDIUM owasp: - - A6:2017-Security Misconfiguration - - A05:2021-Security Misconfiguration - security-severity: CRITICAL - shortDescription: Selection of less-secure algorithm during negotiation ('algorithm downgrade') - pattern-either: - - patterns: - - pattern: $X.TLSMinimumSupportedProtocolVersion = $VAL - - metavariable-pattern: - metavariable: $VAL - pattern-either: - - pattern: | - .TLSv1_0 - - pattern: | - .TLSv1_1 - - pattern: | - .TLSv1_2 + - A04:2021 Insecure Design + - A07:2021 Identification and Authentication Failures + references: + - https://cwe.mitre.org/data/definitions/287.html + - https://owasp.org/Top10/A04_2021-Insecure_Design/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ + subcategory: + - vuln + technology: + - openapi + patterns: + - pattern-inside: | + openapi: $VERSION + ... + components: + ... + securitySchemes: + ... + $SCHEME: + ... + - metavariable-regex: + metavariable: $VERSION + regex: 3.* + - pattern: | + type: http + ... + scheme: basic severity: ERROR - - id: scala_cookie_rule-CookieHTTPOnly + - id: java_perm_rule-DangerousPermissions languages: - - scala + - java message: | - A new cookie is created without the HttpOnly flag set. The HttpOnly flag is a directive to the - browser to make sure that the cookie can not be red by malicious script. When a user is the - target of a "Cross-Site Scripting", the attacker would benefit greatly from getting the session - id for example. + The application was found to permit the `RuntimePermission` of `createClassLoader`, + `ReflectPermission` of `suppressAccessChecks`, or both. + + By granting the `RuntimePermission` of `createClassLoader`, a compromised application + could instantiate their own class loaders and load arbitrary classes. + + By granting the `ReflectPermission` of `suppressAccessChecks` an application will no longer + check Java language access checks on fields and methods of a class. This will effectively + grant access to protected and private members. + + For more information on `RuntimePermission` see: + https://docs.oracle.com/javase/8/docs/api/java/lang/RuntimePermission.html + + For more information on `ReflectPermission` see: + https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/ReflectPermission.html metadata: category: security - cwe: CWE-1004 - security-severity: Low - shortDescription: Sensitive Cookie Without 'HttpOnly' Flag - technology: - - scala + confidence: HIGH + cwe: CWE-732 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Incorrect permission assignment for critical resource pattern-either: - - patterns: - - pattern: | - val $C = new javax.servlet.http.Cookie(..., ...); - ... - $RESP.addCookie($C); - - pattern-not-inside: | - val $C = new javax.servlet.http.Cookie(..., ...); - ... - $C.setHttpOnly(true); - ... - $RESP.addCookie($C); - - pattern: (javax.servlet.http.Cookie $C).setHttpOnly(false); + - pattern: | + $RUNVAR = new RuntimePermission("createClassLoader"); + ... + (PermissionCollection $PC).add($RUNVAR); + - pattern: | + $REFVAR = new ReflectPermission("suppressAccessChecks"); + ... + (PermissionCollection $PC).add($REFVAR); + - pattern: (PermissionCollection $PC).add(new ReflectPermission("suppressAccessChecks")) + - pattern: (PermissionCollection $PC).add(new RuntimePermission("createClassLoader")) severity: WARNING - - id: scala_cookie_rule-CookieInsecure + - id: java_perm_rule-OverlyPermissiveFilePermissionInline languages: - - scala + - java message: | - "A new cookie is created without the Secure flag set. The Secure flag is a - directive to the browser to make sure that the cookie is not sent for insecure communication - (http://)" + The application was found setting file permissions to overly permissive values. Consider + using the following values if the application user is the only process to access + the file: + + - `r--` - read only access to the file + - `w--` - write only access to the file + - `rw-` - read/write access to the file + + Example setting read/write permissions for only the owner of a `Path`: + ``` + // Get a reference to the path + Path path = Paths.get("/tmp/somefile"); + // Create a PosixFilePermission set from java.nio.file.attribute + Set permissions = + java.nio.file.attribute.PosixFilePermissions.fromString("rw-------"); + // Set the permissions + java.nio.file.Files.setPosixFilePermissions(path, permissions); + ``` + + For all other values please see: + https://en.wikipedia.org/wiki/File-system_permissions#Symbolic_notation metadata: category: security - cwe: CWE-539 - security-severity: Low - shortDescription: Information Exposure Through Persistent Cookies - technology: - - scala + confidence: HIGH + cwe: CWE-732 + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + security-severity: Medium + shortDescription: Incorrect permission assignment for critical resource patterns: - - pattern-not-inside: | - val $C = new javax.servlet.http.Cookie(..., ...); - ... - $C.setSecure(true); - ... - $RESP.addCookie($C); - pattern-either: + - pattern: java.nio.file.Files.setPosixFilePermissions(..., java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING")); - pattern: | - val $C = new javax.servlet.http.Cookie(..., ...); + $PERMISSIONS = java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING"); ... - $RESP.addCookie($C); - - pattern: ($C:javax.servlet.http.Cookie).setSecure(false); - severity: WARNING - - id: scala_cookie_rule-CookiePersistent - languages: - - scala - message: | - "Storing sensitive data in a persistent cookie for an extended period can lead to a breach of - confidentiality or account compromise." - metadata: - category: security - cwe: CWE-614 - security-severity: Info - shortDescription: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute - technology: - - scala - patterns: - - pattern: | - ($C: Cookie).setMaxAge($AGE) - - metavariable-comparison: - comparison: $AGE >= 31536000 - metavariable: $AGE + java.nio.file.Files.setPosixFilePermissions(..., $PERMISSIONS); + - metavariable-regex: + metavariable: $PERM_STRING + regex: '[rwx-]{6}[rwx]{1,}' severity: WARNING - - id: scala_cookie_rule-CookieUsage + - id: java_strings_rule-BadHexConversion languages: - - scala + - java message: | - The information stored in a custom cookie should not be sensitive or related to the session. - In most cases, sensitive data should only be stored in session and referenced by the user's - session cookie. + The application is using `Integer.toHexString` on a digest array buffer which + may lead to an incorrect version of values. + + Consider using the `java.util.HexFormat` object introduced in Java 17. For older Java applications + consider using the `javax.xml.bind.DatatypeConverter`. + + Example using `HexFormat` to create a human-readable string: + ``` + // Create a MessageDigest using the SHA-384 algorithm + MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384"); + // Call update with your data + sha384Digest.update("some input".getBytes(StandardCharsets.UTF_8)); + // Only call digest once all data has been fed into the update sha384digest instance + byte[] output = sha384Digest.digest(); + // Create a JDK 17 HexFormat object + HexFormat hex = HexFormat.of(); + // Use formatHex on the byte array to create a string (note that alphabet characters are + lowercase) + String hexString = hex.formatHex(output); + ``` + + For more information on DatatypeConverter see: + https://docs.oracle.com/javase/9/docs/api/javax/xml/bind/DatatypeConverter.html#printHexBinary-byte:A- metadata: category: security - cwe: CWE-614 + confidence: HIGH + cwe: CWE-704 + owasp: + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration security-severity: Info - shortDescription: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute - technology: - - scala + shortDescription: Incorrect type conversion or cast patterns: - pattern-inside: | - def $FUNC(..., $REQ: HttpServletRequest, ...): $TYPE = { - ... - } + $B_ARR = (java.security.MessageDigest $MD).digest(...); + ... - pattern-either: - - patterns: - - pattern-inside: | - for ($C <- $REQ.getCookies) { - ... - } - - pattern-either: - - pattern: $C.getName - - pattern: $C.getValue - - pattern: $C.getPath - - pattern: '($C: Cookie).getName()' - - pattern: '($C: Cookie).getValue' - - pattern: '($C: Cookie).getPath' - severity: WARNING - - id: scala_cookie_rule-HttpResponseSplitting - languages: - - scala - message: | - When an HTTP request contains unexpected CR and LF characters, the server may respond with an - output stream that is interpreted as two different HTTP responses (instead of one). An attacker - can control the second response and mount attacks such as cross-site scripting and cache - poisoning attacks. - metadata: - category: security - cwe: CWE-113 - security-severity: High - shortDescription: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') - technology: - - scala - mode: taint - pattern-sanitizers: - - patterns: - - pattern-inside: $STR.replaceAll("$REPLACE_CHAR", "$REPLACE"); - - pattern: $STR - - metavariable-regex: - metavariable: $REPLACE_CHAR - regex: (.*\\r\\n.*) - - metavariable-regex: - metavariable: $REPLACE - regex: (?!(\\r\\n)) - - pattern: org.owasp.encoder.Encode.forUriComponent(...) - - pattern: org.owasp.encoder.Encode.forUri(...) - - pattern: java.net.URLEncoder.encode(..., $CHARSET) - pattern-sinks: - - pattern: new javax.servlet.http.Cookie("$KEY", ...) - - pattern: ($C:javax.servlet.http.Cookie).setValue(...) - pattern-sources: - - pattern: '($REQ: javax.servlet.http.HttpServletRequest).getParameter(...)' + - pattern: | + for(...) { + ... + $B = $B_ARR[...]; + ... + Integer.toHexString($B); + } + - pattern: | + for(...) { + ... + Integer.toHexString($B_ARR[...]); + } + - pattern: | + for(byte $B :$B_ARR) { + ... + Integer.toHexString($B); + } + - pattern: | + while(...) { + ... + Integer.toHexString($B_ARR[...]) + } + - pattern: | + do { + ... + Integer.toHexString($B_ARR[...]) + } while(...) + - pattern: | + while(...) { + ... + $B = $B_ARR[...]; + ... + Integer.toHexString($B); + } + - pattern: | + do { + ... + $B = $B_ARR[...]; + ... + Integer.toHexString($B); + } while(...) severity: WARNING - - id: scala_cookie_rule-RequestParamToCookie - languages: - - scala - message: | - This code constructs an HTTP Cookie using an untrusted HTTP parameter. If this cookie is added - to an HTTP response, it will allow a HTTP response splitting vulnerability. See - http://en.wikipedia.org/wiki/HTTP_response_splitting for more information. - metadata: - category: security - cwe: CWE-113 - security-severity: Info - shortDescription: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') - technology: - - scala - mode: taint - pattern-sanitizers: - - patterns: - - pattern-inside: $STR.replaceAll("$REPLACE_CHAR", "$REPLACE"); - - pattern: $STR - - metavariable-regex: - metavariable: $REPLACE_CHAR - regex: (.*\\r\\n.*) - - metavariable-regex: - metavariable: $REPLACE - regex: (?!(\\r\\n)) - - pattern: org.owasp.encoder.Encode.forUriComponent(...) - - pattern: org.owasp.encoder.Encode.forUri(...) - - pattern: java.net.URLEncoder.encode(..., $CHARSET) - pattern-sinks: - - pattern: new javax.servlet.http.Cookie("$KEY", ...); - - patterns: - - pattern-inside: | - $C = new javax.servlet.http.Cookie("$KEY", ...); - ... - - pattern: $C.setValue(...); - pattern-sources: - - pattern: '($REQ: HttpServletRequest).getParameter(...);' - severity: ERROR - - id: scala_cookie_rule-RequestParamToHeader - languages: - - scala - message: | - This code directly writes an HTTP parameter to an HTTP header, which allows for a HTTP - response splitting vulnerability. See http://en.wikipedia.org/wiki/HTTP_response_splitting for - more information. - metadata: - category: security - cwe: CWE-113 - security-severity: High - shortDescription: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') - technology: - - scala - mode: taint - pattern-sanitizers: - - patterns: - - pattern-inside: $STR.replaceAll("$REPLACE_CHAR", "$REPLACE"); - - pattern: $STR - - metavariable-regex: - metavariable: $REPLACE_CHAR - regex: (.*\\r\\n.*) - - metavariable-regex: - metavariable: $REPLACE - regex: (?!(\\r\\n)) - - pattern: org.owasp.encoder.Encode.forUriComponent(...) - - pattern: org.owasp.encoder.Encode.forUri(...) - - pattern: java.net.URLEncoder.encode(..., $CHARSET) - pattern-sinks: - - pattern: '($RES: HttpServletResponse).setHeader("$KEY", ...);' - - pattern: '($RES: HttpServletResponse).addHeader("$KEY", ...);' - - pattern: '($WRP: HttpServletResponseWrapper).setHeader("$KEY", ...);' - - pattern: '($WRP: HttpServletResponseWrapper).addHeader("$KEY", ...);' - pattern-sources: - - pattern: '($REQ: HttpServletRequest).getParameter(...);' - severity: ERROR - - id: scala_cookie_rule-TrustBoundaryViolation + - id: java_strings_rule-FormatStringManipulation languages: - - scala + - java message: | - A trust boundary can be thought of as line drawn through a program. On one side - of the line, data is untrusted. On the other side of the line, data is assumed - to be trustworthy. The purpose of validation logic is to allow data to safely - cross the trust boundary - to move from untrusted to trusted. A trust boundary - violation occurs when a program blurs the line between what is trusted and what - is untrusted. By combining trusted and untrusted data in the same data - structure, it becomes easier for programmers to mistakenly trust unvalidated - data. + The application allows user input to control format string parameters. By passing invalid + format + string specifiers an adversary could cause the application to throw exceptions or possibly + leak + internal information depending on application logic. + + Never allow user-supplied input to be used to create a format string. Replace all format + string + arguments with hardcoded format strings containing the necessary specifiers. + + Example of using `String.format` safely: + ``` + // Get untrusted user input + String userInput = request.getParameter("someInput"); + // Ensure that user input is not included in the first argument to String.format + String.format("Hardcoded string expecting a string: %s", userInput); + // ... + ``` metadata: category: security - cwe: CWE-501 - security-severity: Info - shortDescription: Trust Boundary Violation + confidence: HIGH + cwe: CWE-134 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Medium + shortDescription: Use of externally-controlled format string patterns: - pattern-either: - patterns: - - pattern: '($H: HttpServletRequest). ... .setAttribute($ARG1, $ARG2)' - - pattern-not: '($H: HttpServletRequest). ... .setAttribute("...", "...")' + - pattern-inside: | + String $INPUT = (HttpServletRequest $REQ).getParameter(...); + ... + - pattern-inside: | + String $FORMAT_STR = ... + $INPUT; + ... - patterns: - - pattern: '($H: HttpServletRequest). ... .putValue($ARG1, $ARG2)' - - pattern-not: '($H: HttpServletRequest). ... .putValue("...", "...")' - severity: WARNING - - id: scala_cors_rule-PermissiveCORS - languages: - - scala - message: | - Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for - JavaScript to access the contents of a Web page, both the JavaScript and the Web page must - originate from the same domain. Without the Same Origin Policy, a malicious website could serve - up JavaScript that loads sensitive information from other websites using a client's - credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible - for JavaScript to access data across domains if a new HTTP header called - Access-Control-Allow-Origin is defined. With this header, a Web server defines which other - domains are allowed to access its domain using cross-origin requests. However, caution should - be taken when defining the header because an overly permissive CORS policy will allow a - malicious application to communicate with the victim application in an inappropriate way, - leading to spoofing, data theft, relay and other attacks. - metadata: - category: security - cwe: CWE-942 - security-severity: Info - shortDescription: Permissive Cross-domain Policy with Untrusted Domains - technology: - - scala - pattern-either: - - patterns: - - pattern-either: - - pattern: ($RESP:javax.servlet.http.HttpServletResponse).setHeader("$HEADER", "$VAL") - - pattern: ($RESP:javax.servlet.http.HttpServletResponse).addHeader("$HEADER", "$VAL") - - metavariable-regex: - metavariable: $HEADER - regex: (?i)(Access-Control-Allow-Origin) - - metavariable-regex: - metavariable: $VAL - regex: (\*|null) - - patterns: + - pattern-inside: | + String $INPUT = (HttpServletRequest $REQ).getParameter(...); + ... + - pattern-inside: | + String $FORMAT_STR = ... + $INPUT + ...; + ... - pattern-inside: | - $REQVAL = ($REQ: javax.servlet.http.HttpServletRequest).getParameter(...) + String $FORMAT_STR = ... + (HttpServletRequest $REQ).getParameter(...) + ...; ... - - pattern-either: - - pattern-inside: ($RESP:javax.servlet.http.HttpServletResponse).setHeader("$HEADER", $REQVAL) - - pattern-inside: ($RESP:javax.servlet.http.HttpServletResponse).addHeader("$HEADER", $REQVAL) - - patterns: - - pattern-either: - - pattern-inside: '($RESP:javax.servlet.http.HttpServletResponse).setHeader("$HEADER",($REQ: javax.servlet.http.HttpServletRequest).getParameter(...))' - - pattern-inside: '($RESP:javax.servlet.http.HttpServletResponse).addHeader("$HEADER",($REQ: javax.servlet.http.HttpServletRequest).getParameter(...))' + - pattern-inside: | + String $FORMAT_STR = ... + (HttpServletRequest $REQ).getParameter(...); + ... + - pattern-either: + - pattern: String.format($FORMAT_STR, ...); + - pattern: String.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern: (java.util.Formatter $F).format($FORMAT_STR, ...); + - pattern: (java.util.Formatter $F).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern: (java.io.PrintStream $F).printf($FORMAT_STR, ...); + - pattern: (java.io.PrintStream $F).printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern: (java.io.PrintStream $F).format($FORMAT_STR, ...); + - pattern: (java.io.PrintStream $F).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern: System.out.printf($FORMAT_STR, ...); + - pattern: System.out.printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...); + - pattern: System.out.format($FORMAT_STR, ...); + - pattern: System.out.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...); severity: ERROR - - id: scala_cors_rule-PermissiveCORSInjection + - id: java_strings_rule-ModifyAfterValidation languages: - java - message: | - Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for - JavaScript to access the contents of a Web page, both the JavaScript and the Web page must - originate from the same domain. Without the Same Origin Policy, a malicious website could serve - up JavaScript that loads sensitive information from other websites using a client's - credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible - for JavaScript to access data across domains if a new HTTP header called - Access-Control-Allow-Origin is defined. With this header, a Web server defines which other - domains are allowed to access its domain using cross-origin requests. However, caution should - be taken when defining the header because an overly permissive CORS policy will allow a - malicious application to communicate with the victim application in an inappropriate way, - leading to spoofing, data theft, relay and other attacks. - metadata: - category: security - cwe: CWE-942 - security-severity: Low - shortDescription: Permissive Cross-domain Policy with Untrusted Domains - technology: - - java - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern: (HttpServletResponse $RES).setHeader("$HEADER", ...) - - pattern: (HttpServletResponse $RES).addHeader("$HEADER", ...) - - metavariable-regex: - metavariable: $HEADER - regex: (?i)(Access-Control-Allow-Origin) - pattern-sources: - - pattern: (HttpServletRequest $REQ).getParameter(...) - severity: ERROR - - id: scala_crypto_rule-BlowfishKeySize - languages: - - scala - message: | - A small key size makes the ciphertext vulnerable to brute force attacks. At least 128 bits of - entropy should be used when generating the key if use of Blowfish is required. + message: |+ + The application was found matching a variable during a regular expression + pattern match, and then calling string modification functions after validation has occurred. + This is usually indicative of a poor input validation strategy as an adversary may attempt to + exploit the removal of characters. + + For example a common mistake in attempting to remove path characters to protect against path + traversal is to match '../' and then remove any matches. However, if an adversary were to + include in their input: '....//' then the `replace` method would replace the first `../` but + cause the leading `..` and trailing `/` to join into the final string of `../`, effectively + bypassing the check. + + To remediate this issue always perform string modifications before any validation of a string. + It is strongly recommended that strings be encoded instead of replaced or removed prior to + validation. + + + Example replaces `..` before validation. Do note this is still not a recommended method for + protecting against directory traversal, always use randomly generated IDs or filenames instead: + ``` + // This is ONLY for demonstration purpose, never use untrusted input + // in paths, always use randomly generated filenames or IDs. + String input = "test../....//dir"; + // Use replaceAll _not_ replace + input = input.replaceAll("\\.\\.", ""); + // Input would be test///dir at this point + // Create a pattern to match on + Pattern pattern = Pattern.compile("\\.\\."); + // Create a matcher + Matcher match = pattern.matcher(input); + // Call find to see if .. is still in our string + if (match.find()) { + throw new Exception(".. detected"); + } + // Use the input (but do not modify the string) + System.out.println(input + " safe"); + ``` + + For more information see Carnegie Mellon University's Secure Coding Guide: + https://wiki.sei.cmu.edu/confluence/display/java/IDS11-J.+Perform+any+string+modifications+before+validation + metadata: category: security - cwe: CWE-326 - security-severity: Medium - shortDescription: Inadequate Encryption Strength - technology: - - scala + confidence: HIGH + cwe: CWE-182 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Info + shortDescription: Collapse of data into unsafe value patterns: - - pattern-inside: | - $KEYGEN = javax.crypto.KeyGenerator.getInstance("Blowfish", ...); + - pattern: | + (java.util.regex.Pattern $Y).matcher($VAR); ... - $KEYGEN.init($KEY_SIZE); - - metavariable-comparison: - comparison: $KEY_SIZE < 128 - metavariable: $KEY_SIZE - severity: WARNING - - id: scala_crypto_rule-CipherDESInsecure - languages: - - scala - message: | - DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage - of AES block ciphers instead of DES. - metadata: - category: security - cwe: CWE-326 - security-severity: Medium - shortDescription: Inadequate Encryption Strength - technology: - - scala - patterns: - - pattern-inside: javax.crypto.Cipher.getInstance("$ALG") + $VAR.$METHOD(...); - metavariable-regex: - metavariable: $ALG - regex: ^(DES)/.* + metavariable: $METHOD + regex: (replace|replaceAll|replaceFirst|concat) severity: WARNING - - id: scala_crypto_rule-CipherDESedeInsecure + - id: java_strings_rule-NormalizeAfterValidation languages: - - scala + - java message: | - Triple DES (also known as 3DES or DESede) is considered strong ciphers for modern - applications. NIST recommends the usage of AES block ciphers instead of 3DES. + The application was found matching a variable during a regular expression + pattern match, and then calling a Unicode normalize function after validation has occurred. + This is usually indicative of a poor input validation strategy as an adversary may attempt to + exploit the normalization process. + + To remediate this issue, always perform Unicode normalization before any validation of a + string. + + Example of normalizing a string before validation: + ``` + // User input possibly containing malicious unicode + String userInput = "\uFE64" + "tag" + "\uFE65"; + // Normalize the input + userInput = Normalizer.normalize(userInput, Normalizer.Form.NFKC); + // Compile our regex pattern looking for < or > characters + Pattern pattern = Pattern.compile("[<>]"); + // Create a matcher from the userInput + Matcher matcher = pattern.matcher(userInput); + // See if the matcher matches + if (matcher.find()) { + // It did so throw an error + throw new Exception("found banned characters in input"); + } + ``` + + For more information see Carnegie Mellon University's Secure Coding Guide: + https://wiki.sei.cmu.edu/confluence/display/java/IDS01-J.+Normalize+strings+before+validating+them metadata: category: security - cwe: CWE-326 - security-severity: Medium - shortDescription: Inadequate Encryption Strength - technology: - - scala + confidence: HIGH + cwe: CWE-180 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: Info + shortDescription: 'Incorrect behavior order: validate before canonicalize' patterns: - - pattern-inside: javax.crypto.Cipher.getInstance("$ALG") - - metavariable-regex: - metavariable: $ALG - regex: ^(DESede)/.* + - pattern: | + $Y = java.util.regex.Pattern.compile("[<>]"); + ... + $Y.matcher($VAR); + ... + java.text.Normalizer.normalize($VAR, ...); severity: WARNING - - id: scala_crypto_rule-CipherECBMode + - id: java_crypto_rule-DisallowOldTLSVersion languages: - - scala - message: | - An authentication cipher mode which provides better confidentiality of the encrypted data - should be used instead of Electronic Code Book (ECB) mode, which does not provide good - confidentiality. Specifically, ECB mode produces the same output for the same input each time. - This allows an attacker to intercept and replay the data. + - java + message: "This application sets the `jdk.tls.client.protocols` system property to\ninclude insecure TLS or SSL versions (SSLv3, TLSv1, TLSv1.1), which are\ndeprecated due to serious security vulnerabilities like POODLE attacks and\nsusceptibility to man-in-the-middle attacks. Continuing to use these\nprotocols can expose data to interception or manipulation. \n\nTo mitigate the issue, upgrade to TLSv1.2 or higher, which provide stronger \nencryption and improved security. Refrain from using any SSL versions as they \nare entirely deprecated.\n\nSecure Code Example:\n```\npublic void safe() {\n java.lang.System.setProperty(\"jdk.tls.client.protocols\", \"TLSv1.3\");\n}\n```\n" metadata: category: security + confidence: MEDIUM cwe: CWE-326 - security-severity: Medium - shortDescription: Inadequate Encryption Strength + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://stackoverflow.com/questions/26504653/is-it-possible-to-disable-sslv3-for-all-java-applications + security-severity: MEDIUM + shortDescription: Inadequate encryption strength + subcategory: + - vuln technology: - - scala + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information patterns: - - pattern-inside: javax.crypto.Cipher.getInstance("...") - - pattern-regex: (AES|DES(ede)?)(/ECB/*) - severity: ERROR - - id: scala_crypto_rule-CipherIntegrity + - pattern: $VALUE. ... .setProperty("jdk.tls.client.protocols", "$PATTERNS"); + - metavariable-pattern: + language: generic + metavariable: $PATTERNS + patterns: + - pattern-either: + - pattern-regex: ^(.*TLSv1|.*SSLv.*)$ + - pattern-regex: ^(.*TLSv1,.*|.*TLSv1.1.*) + severity: WARNING + - id: java_crypto_rule-HTTPUrlConnectionHTTPRequest languages: - - scala - message: | - The ciphertext produced is susceptible to alteration by an adversary. This mean that the - cipher provides no way to detect that the data has been tampered with. If the ciphertext can be - controlled by an attacker, it could be altered without detection. + - java + message: "Detected an HTTP request sent via HttpURLConnection or URLConnection.\nThis could lead to sensitive information being sent over an insecure \nchannel, as HTTP does not encrypt data. Transmitting data over HTTP \nexposes it to potential interception by attackers, risking data \nintegrity and confidentiality. Using HTTP for transmitting sensitive \ndata such as passwords, personal information, or financial details can \nlead to information disclosure.\n\nTo mitigate the issue, switch to HTTPS to ensure all data transmitted \nis securely encrypted. This helps protect against eavesdropping and \nman-in-the-middle attacks. Modify the URL in your code from HTTP to \nHTTPS and ensure the server supports HTTPS.\n\nSecure Code Example:\n```\nprivate static void safe() {\n try {\n URL url = new URL(\"https://example.com/api/data\"); // Changed to HTTPS\n HttpURLConnection con = (HttpURLConnection) url.openConnection();\n con.setRequestMethod(\"GET\");\n\n int status = con.getResponseCode();\n if (status == HttpURLConnection.HTTP_OK) { \n BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n String inputLine;\n StringBuilder response = new StringBuilder();\n while ((inputLine = in.readLine()) != null) {\n response.append(inputLine);\n }\n in.close();\n System.out.println(\"Response: \" + response.toString());\n } else {\n System.out.println(\"HTTP error code: \" + status);\n }\n con.disconnect();\n } catch (Exception e) {\n e.printStackTrace();\n }\n}\n```\n" metadata: category: security - cwe: CWE-353 - security-severity: Medium - shortDescription: Missing Support for Integrity Check + confidence: MEDIUM + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + subcategory: + - vuln technology: - - scala + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information patterns: - - pattern-inside: javax.crypto.Cipher.getInstance("...") + - pattern: | + "=~/[Hh][Tt][Tt][Pp]://.*/" - pattern-either: - - pattern-regex: (/CBC/PKCS5Padding) - - pattern-regex: (AES|DES(ede)?)(/ECB/*) - - pattern-regex: (AES|DES(ede)?)(/CBC/*) - - pattern-regex: (AES|DES(ede)?)(/OFB/*) - - pattern-regex: (AES|DES(ede)?)(/CTR/*) - - pattern-not-regex: .*/(CCM|CWC|OCB|EAX|GCM)/.* - - pattern-not-regex: ^(RSA)/.* - - pattern-not-regex: ^(ECIES)$ - severity: ERROR - - id: scala_crypto_rule-CipherPaddingOracle - languages: - - scala - message: | - This specific mode of CBC with PKCS5Padding is susceptible to padding oracle attacks. An - adversary could potentially decrypt the message if the system exposed the difference between - plaintext with invalid padding or valid padding. The distinction between valid and invalid - padding is usually revealed through distinct error messages being returned for each condition. - metadata: - category: security - cwe: CWE-696 - security-severity: Medium - shortDescription: Incorrect Behavior Order - technology: - - scala - patterns: - - pattern-inside: javax.crypto.Cipher.getInstance("...") - - pattern-regex: (/CBC/PKCS5Padding) - - pattern-not-regex: ^(RSA)/.* - - pattern-not-regex: ^(ECIES)$ - severity: ERROR - - id: scala_crypto_rule-CustomMessageDigest + - pattern-inside: | + URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); + ... + $CON = (HttpURLConnection) $URL.openConnection(...); + ... + $CON.$FUNC(...); + - pattern-inside: | + URL $URL = new URL ("=~/[Hh][Tt][Tt][Pp]://.*/", ...); + ... + $CON = $URL.openConnection(...); + ... + $CON.$FUNC(...); + severity: WARNING + - id: java_crypto_rule-HttpComponentsRequest languages: - - scala - message: | - Implementing a custom MessageDigest is error-prone. National Institute of Standards and - Technology(NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or - SHA-512/256. + - java + message: "Detected an HTTP GET request sent via Apache HTTP Components. Sending data\nover HTTP can expose sensitive information to interception or modification\nby attackers, as HTTP does not encrypt the data transmitted. It is critical\nto use HTTPS, which encrypts the communication, to protect the confidentiality\nand integrity of data in transit.\n\nTo mitigate the issue, ensure all data transmitted between the client and \nserver is sent over HTTPS. Update all HTTP URLs to HTTPS and configure your \nserver to redirect HTTP requests to HTTPS. Additionally, implement HSTS \n(HTTP Strict Transport Security) to enforce secure connections.\nSecure Code Example:\n```\nprivate static void safe() {\n CloseableHttpClient httpclient = HttpClients.createDefault();\n CloseableHttpResponse response = httpclient.execute(new HttpPost(\"https://example.com\"));\n}\n```\n" metadata: category: security - cwe: CWE-327 - security-severity: Medium - shortDescription: Use of a Broken or Risky Cryptographic Algorithm + confidence: MEDIUM + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://hc.apache.org/httpcomponents-client-ga/quickstart.html + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + subcategory: + - vuln technology: - - scala - patterns: + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information + mode: taint + pattern-sinks: + - pattern: (org.apache.http.impl.client.CloseableHttpClient $A).execute($HTTPREQ); + pattern-sources: - pattern: | - class $CLAZZ extends java.security.MessageDigest(...) { - ... - } + "=~/^http://.+/i" severity: WARNING - - id: scala_crypto_rule-DefaultHTTPClient + - id: java_crypto_rule-HttpGetHTTPRequest languages: - - scala - message: | - DefaultHttpClient with default constructor is not compatible with TLS 1.2 + - java + message: "Detected an HTTP GET request sent via HttpGet. Sending data over HTTP can\nexpose sensitive information to interception or modification by attackers,\nas HTTP does not encrypt the data transmitted. It is critical to use\nHTTPS, which encrypts the communication, to protect the confidentiality\nand integrity of data in transit.\n\nTo mitigate the issue, ensure all data transmitted between the client and \nserver is sent over HTTPS. Update all HTTP URLs to HTTPS and configure your \nserver to redirect HTTP requests to HTTPS. Additionally, implement HSTS \n(HTTP Strict Transport Security) to enforce secure connections.\n\nSecure Code Example:\n```\nprivate static void safe() throws IOException {\n HttpGet httpGet = new HttpGet(\"https://example.com\");\n HttpClients.createDefault().execute(httpGet);\n}\n```\n" metadata: category: security - cwe: CWE-326 - security-severity: Info - shortDescription: Inadequate encryption strength + confidence: MEDIUM + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html + - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URL.html#openConnection() + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + subcategory: + - vuln technology: - - scala - patterns: - - pattern: new org.apache.http.impl.client.DefaultHttpClient(...) + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information + mode: taint + pattern-sinks: + - patterns: + - pattern: | + $R = new org.apache.http.client.methods.HttpGet($PROT); + ... + $CLIENT. ... .execute($R, ...); + - focus-metavariable: $PROT + pattern-sources: + - pattern: | + "=~/^http:\/\/.+/i" severity: WARNING - - id: scala_crypto_rule-HazelcastSymmetricEncryption + - id: java_crypto_rule_JwtDecodeWithoutVerify languages: - - scala - message: | - The network communications for Hazelcast is configured to use a symmetric cipher (probably DES - or Blowfish). Those ciphers alone do not provide integrity or secure authentication. The use of - asymmetric encryption is preferred. + - java + message: Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token. metadata: category: security - cwe: CWE-326 - security-severity: Medium - shortDescription: Inadequate Encryption Strength - technology: - - scala + confidence: MEDIUM + cwe: CWE-347 + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + references: https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures + security-severity: MEDIUM + shortDescription: Improper verification of cryptographic signature + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: vuln + technology: jwt + vulnerability_class: Improper Authentication patterns: - - pattern: new com.hazelcast.config.SymmetricEncryptionConfig() + - pattern: | + com.auth0.jwt.JWT.decode(...); + - pattern-not-inside: |- + class $CLASS { + ... + $RETURNTYPE $FUNC (...) { + ... + $VERIFIER.verify(...); + ... + } + } severity: WARNING - - id: scala_crypto_rule-InsufficientKeySizeRsa + - id: java_crypto_rule-SpringFTPRequest languages: - - scala - message: | - Detected an insufficient key size for DSA. NIST recommends a key size - of 2048 or higher. + - java + message: "This pattern detects configurations where the Spring Integration FTP plugin \nis used to set up connections to FTP servers. FTP is an insecure protocol \nthat transmits data, including potentially sensitive information, in plaintext. \nThis can expose personal identifiable information (PII) or other sensitive data \nto interception by attackers during transmission. \n\nTo mitigate the vulnerability, switch to a secure protocol such as SFTP or FTPS \nthat encrypts the connection to prevent data exposure. Ensure that any method \nused to set the host for an FTP session does not use plaintext FTP. \n\nSecure Code Example:\n```\npublic SessionFactory safe(FtpSessionFactoryProperties properties) {\n DefaultFtpSessionFactory ftpSessionFactory = new DefaultFtpSessionFactory();\n ftpSessionFactory.setHost(\"sftp://example.com\");\n ftpSessionFactory.setPort(properties.getPort());\n ftpSessionFactory.setUsername(properties.getUsername());\n ftpSessionFactory.setPassword(properties.getPassword());\n ftpSessionFactory.setClientMode(properties.getClientMode().getMode());\n return ftpSessionFactory;\n}\n```\n" metadata: category: security - cwe: CWE-326 - security-severity: Medium - shortDescription: Inadequate Encryption Strength - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $GEN = KeyPairGenerator.getInstance($ALG, ...); - ... - - pattern-either: - - pattern: $VAR.initialize($SIZE, ...) - - pattern: new java.security.spec.RSAKeyGenParameterSpec($SIZE, ...) - - metavariable-comparison: - comparison: $SIZE < 2048 - metavariable: $SIZE - - metavariable-regex: - metavariable: $ALG - regex: '"(RSA|DSA)"' + confidence: MEDIUM + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://docs.spring.io/spring-integration/api/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.html#setClientMode-int- + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + subcategory: + - vuln + technology: + - spring + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information + mode: taint + pattern-sinks: + - patterns: + - pattern: | + (org.springframework.integration.ftp.session.DefaultFtpSessionFactory + $SF).setHost($URL); + - focus-metavariable: $URL + pattern-sources: + - pattern: | + "=~/^ftp://.+/i" severity: WARNING - - id: scala_crypto_rule-NullCipher + - id: java_crypto_rule-SpringHTTPRequestRestTemplate languages: - - scala - message: | - The NullCipher implements the Cipher interface by returning ciphertext identical to the - supplied plaintext. In a few contexts, such as testing, a NullCipher may be appropriate. Avoid - using the NullCipher. Its accidental use can introduce a significant confidentiality risk. + - java + message: "This rule detects instances where Java Spring's RestTemplate API sends \nrequests to non-secure (http://) URLs. Sending data over HTTP is vulnerable \nas it does not use TLS encryption, exposing the data to interception, \nmodification, or redirection by attackers. \n\nTo mitigate this vulnerability, modify the request URLs to use HTTPS instead, \nwhich ensures that the data is encrypted during transit and prevents from\nMITM attacks. \n\nSecure Code Example:\n```\npublic void safe(Object obj) throws Exception {\n RestTemplate restTemplate = new RestTemplate();\n restTemplate.put(URI.create(\"https://example.com\"), obj);\n}\n``` \n" metadata: category: security - cwe: CWE-327 - security-severity: Medium - shortDescription: Use of a Broken or Risky Cryptographic Algorithm + confidence: MEDIUM + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#delete-java.lang.String-java.util.Map- + - https://www.baeldung.com/rest-template + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + subcategory: + - vuln technology: - - scala - pattern: new javax.crypto.NullCipher() + - spring + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information + mode: taint + pattern-sinks: + - patterns: + - pattern: | + (org.springframework.web.client.RestTemplate $RESTTEMP).$FUNC($URL, ...); + - focus-metavariable: $URL + - metavariable-regex: + metavariable: $FUNC + regex: (delete|doExecute|exchange|getForEntity|getForObject|headForHeaders|optionsForAllow|patchForObject|postForEntity|postForLocation|postForObject|put|execute) + pattern-sources: + - pattern: | + "=~/^http:\/\/.+/i" severity: WARNING - - id: scala_crypto_rule-RsaNoPadding + - id: java_crypto_rule-TLSUnsafeRenegotiation languages: - - scala - message: | - The software uses the RSA algorithm but does not incorporate Optimal Asymmetric - Encryption Padding (OAEP), which might weaken the encryption. + - java + message: "This code enables unsafe renegotiation in SSL/TLS connections, which is\nvulnerable to man-in-the-middle attacks. In such attacks, an attacker\ncould inject chosen plaintext at the beginning of the secure\ncommunication, potentially compromising the security of data transmission. If \nexploited, this vulnerability can lead to unauthorized access to sensitive \ndata, data manipulation, and potentially full system compromise depending on \nthe data and operations protected by the TLS session.\n\nTo mitigate this vulnerability, disable unsafe renegotiation in the Java \napplication. Ensure that only secure renegotiation is allowed by setting the \nsystem property `sun.security.ssl.allowUnsafeRenegotiation` to `false`. \n\nSecure code example:\n```\npublic void safe() {\n java.lang.System.setProperty(\"sun.security.ssl.allowUnsafeRenegotiation\", false);\n}\n```\n" metadata: category: security - cwe: CWE-780 + confidence: MEDIUM + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW owasp: - A3:2017-Sensitive Data Exposure - A02:2021-Cryptographic Failures - security-severity: Medium - shortDescription: Use of RSA Algorithm without OAEP + references: + - https://www.oracle.com/java/technologies/javase/tlsreadme.html + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + subcategory: + - vuln + technology: + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information patterns: - - pattern: javax.crypto.Cipher.getInstance("$ALG",...) - - metavariable-regex: - metavariable: $ALG - regex: .*NoPadding.* + - pattern: | + java.lang.System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", $TRUE); + - metavariable-pattern: + metavariable: $TRUE + pattern-either: + - pattern: | + true + - pattern: | + "true" + - pattern: | + Boolean.TRUE severity: WARNING - - id: scala_crypto_rule-WeakMessageDigest + - id: java_crypto_rule-TelnetRequest languages: - - scala - message: | - DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage - of AES block ciphers instead of DES. + - java + message: "Checks for attempts to connect through telnet. Telnet is an outdated\nprotocol that transmits all data, including sensitive information like\npasswords, in clear text. This exposes it to interception and\neavesdropping on unsecured networks.\n\nTo mitigate this issue, replace Telnet usage with more secure protocols \nsuch as SSH (Secure Shell), which provides encrypted communication. Use \nthe SSH functionality provided by libraries like JSch or Apache MINA SSHD \nfor secure data transmission.\n\nSecure Code Example:\n```\nimport com.jcraft.jsch.JSch;\nimport com.jcraft.jsch.Session;\n\npublic class SecureConnector {\n public static void main(String[] args) {\n try {\n JSch jsch = new JSch();\n Session session = jsch.getSession(\"username\", \"hostname\", 22);\n session.setPassword(\"password\");\n session.setConfig(\"StrictHostKeyChecking\", \"no\");\n session.connect();\n System.out.println(\"Connected securely.\");\n } catch (Exception e) {\n System.err.println(\"Secure connection failed: \" + e.getMessage());\n }\n }\n}\n```\n" metadata: category: security - cwe: CWE-326 - security-severity: Medium - shortDescription: Inadequate Encryption Strength + confidence: MEDIUM + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://commons.apache.org/proper/commons-net/javadocs/api-3.6/org/apache/commons/net/telnet/TelnetClient.html + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + subcategory: + - vuln technology: - - scala - patterns: - - pattern-either: - - pattern: MessageDigest.getInstance("$ALG", ...) - - pattern: Signature.getInstance("$ALG", ...) - - metavariable-regex: - metavariable: $ALG - regex: (.*(MD5|MD4|MD2|SHA1|SHA-1).*) + - java + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information + pattern: | + (org.apache.commons.net.telnet.TelnetClient $TELNETCLIENT).connect(...); severity: WARNING - - id: scala_crypto_rule-WeakTLSProtocol + - id: java_crypto_rule-UnirestHTTPRequest languages: - - scala - message: | - A HostnameVerifier that accept any host are often use because of certificate - reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middleattacks - attacks since the client will trust any certificate. + - java + message: "This application uses the Unirest library to send\nnetwork requests to URLs starting with 'http://'. Communicating over HTTP\nis considered insecure because it does not encrypt traffic with TLS\n(Transport Layer Security), exposing data to potential interception or\nmanipulation by attackers.\n\nTo mitigate the issue, modify the request URL to begin with 'https://' \ninstead of 'http://'. Using HTTPS ensures that the data is encrypted and \nsecure during transmission. Review all instances where HTTP is used and \nupdate them to use HTTPS to prevent security risks.\n\nSecure Code Example:\n```\nimport kong.unirest.core.Unirest;\n\npublic void safe() {\n Unirest.get(\"https://httpbin.org\")\n .queryString(\"fruit\", \"apple\")\n .queryString(\"droid\", \"R2D2\")\n .asString();\n}\n```\n" metadata: category: security - cwe: CWE-295 - security-severity: Medium - shortDescription: Improper Certificate Validation + confidence: MEDIUM + cwe: CWE-319 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://kong.github.io/unirest-java/#requests + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + subcategory: + - vuln + technology: + - unirest + vulnerability: Insecure Transport + vulnerability_class: + - Mishandled Sensitive Information patterns: - - pattern-either: - - pattern: new org.apache.http.impl.client.DefaultHttpClient() - - pattern: javax.net.ssl.SSLContext.getInstance("SSL") - - patterns: - - pattern-inside: | - import javax.net.ssl._ - ... - - pattern: SSLContext.getInstance("SSL") + - pattern: | + Unirest.$METHOD("=~/[hH][tT][tT][pP]://.*/") severity: WARNING - - id: scala_endpoint_rule-JaxRsEndpoint - languages: - - scala - message: | - This method is part of a REST Web Service (JSR311). The security of this web service should be - analyzed. For example: - - Authentication, if enforced, should be tested. - - Access control, if enforced, should be tested. - - The inputs should be tracked for potential vulnerabilities. - - The communication should ideally be over SSL. - - If the service supports writes (e.g., via POST), its vulnerability to CSRF should be - investigated. - metadata: - category: security - cwe: CWE-348 - security-severity: Medium - shortDescription: Use of less trusted source - technology: - - scala - mode: taint - pattern-sinks: - - pattern: <...$VAR...> - pattern-sources: - - patterns: - - pattern-inside: | - @javax.ws.rs.Path("...") - def $FUNC(..., $VAR: $TYPE, ...) = ... - - pattern: $VAR - severity: INFO - - id: scala_endpoint_rule-JaxWsEndpoint + - id: java_crypto_rule-UseOfRC2 languages: - - scala - message: | - This method is part of a SOAP Web Service (JSR224). The security of this web service should be - analyzed. For example: - - Authentication, if enforced, should be tested. - - Access control, if enforced, should be tested. - - The inputs should be tracked for potential vulnerabilities. - - The communication should ideally be over SSL. + - java + message: "Use of RC2, a deprecated cryptographic algorithm vulnerable to related-key\nattacks, was detected. Modern cryptographic standards recommend the\nadoption of algorithms that integrate message integrity to ensure the\nciphertext remains unaltered.\n\nTo mitigate the issue, use any of the below algorithms instead:\n1. `ChaCha20Poly1305` - Preferred for its simplicity and speed, suitable for \nenvironments where cryptographic acceleration is absent.\n2. `AES-256-GCM` - Highly recommended when hardware support is available, \ndespite being somewhat slower than `ChaCha20Poly1305`. It is crucial to avoid \nnonce reuse with AES-256-GCM to prevent security compromises.\n\nSecure code example using `ChaCha20Poly1305` in Java:\n```\npublic void encryptAndDecrypt() throws Exception {\n SecureRandom random = new SecureRandom();\n byte[] secretKey = new byte[32]; // 256-bit key\n byte[] nonce = new byte[12]; // 96-bit nonce\n random.nextBytes(secretKey);\n random.nextBytes(nonce);\n\n Cipher cipher = Cipher.getInstance(\"ChaCha20-Poly1305/None/NoPadding\");\n SecretKeySpec keySpec = new SecretKeySpec(secretKey, \"ChaCha20\");\n GCMParameterSpec spec = new GCMParameterSpec(128, nonce);\n\n cipher.init(Cipher.ENCRYPT_MODE, keySpec, spec);\n byte[] plaintext = \"Secret text\".getBytes(StandardCharsets.UTF_8);\n byte[] ciphertext = cipher.doFinal(plaintext);\n System.out.println(\"Encrypted: \" + Base64.getEncoder().encodeToString(ciphertext));\n\n cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);\n byte[] decrypted = cipher.doFinal(ciphertext);\n System.out.println(\"Decrypted: \" + new String(decrypted, StandardCharsets.UTF_8));\n}\n```\nFor more on Java Cryptography, refer:\nhttps://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html\n" metadata: category: security - cwe: CWE-348 + confidence: HIGH + cwe: CWE-327 + impact: MEDIUM + likelihood: MEDIUM owasp: - - A7:2017-Cross-Site Scripting (XSS) - - A03:2021-Injection - security-severity: Info - shortDescription: Use of less trusted source + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + security-severity: MEDIUM + shortDescription: Use of a broken or risky cryptographic algorithm + subcategory: + - vuln technology: - - scala - mode: taint - pattern-sinks: - - pattern: <...$VAR...> - pattern-sources: + - java + pattern-either: + - pattern: | + javax.crypto.Cipher.getInstance("RC2") - patterns: - pattern-inside: | - @javax.jws.WebMethod(...) - def $FUNC(..., $VAR: $TYPE, ...) = ... - - pattern: $VAR - severity: INFO - - id: scala_endpoint_rule-UnencryptedSocket + class $CLS{ + ... + String $ALG = "RC2"; + ... + } + - pattern: | + javax.crypto.Cipher.getInstance($ALG); + severity: WARNING + - id: java_crypto_rule-UseOfRC4 languages: - - scala - message: | - Beyond using an SSL socket, you need to make sure your use of SSLSocketFactory - does all the appropriate certificate validation checks to make sure you are not - subject to man-in-the-middle attacks. Please read the OWASP Transport Layer - Protection Cheat Sheet for details on how to do this correctly. + - java + message: "Use of RC4 was detected. RC4 is vulnerable to several types of attacks,\nincluding stream cipher attacks where attackers can recover plaintexts by\nanalyzing a large number of encrypted messages, and bit-flipping attacks\nthat can alter messages without knowing the encryption key.\n\nTo mitigate the issue, use any of the below algorithms instead:\n1. `ChaCha20Poly1305` - Preferred for its simplicity and speed, suitable for \nenvironments where cryptographic acceleration is absent.\n2. `AES-256-GCM` - Highly recommended when hardware support is available, \ndespite being somewhat slower than `ChaCha20Poly1305`. It is crucial to avoid \nnonce reuse with AES-256-GCM to prevent security compromises.\n\nSecure code example using `ChaCha20Poly1305` in Java:\n```\npublic void encryptAndDecrypt() throws Exception {\n SecureRandom random = new SecureRandom();\n byte[] secretKey = new byte[32]; // 256-bit key\n byte[] nonce = new byte[12]; // 96-bit nonce\n random.nextBytes(secretKey);\n random.nextBytes(nonce);\n\n Cipher cipher = Cipher.getInstance(\"ChaCha20-Poly1305/None/NoPadding\");\n SecretKeySpec keySpec = new SecretKeySpec(secretKey, \"ChaCha20\");\n GCMParameterSpec spec = new GCMParameterSpec(128, nonce);\n\n cipher.init(Cipher.ENCRYPT_MODE, keySpec, spec);\n byte[] plaintext = \"Secret text\".getBytes(StandardCharsets.UTF_8);\n byte[] ciphertext = cipher.doFinal(plaintext);\n System.out.println(\"Encrypted: \" + Base64.getEncoder().encodeToString(ciphertext));\n\n cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);\n byte[] decrypted = cipher.doFinal(ciphertext);\n System.out.println(\"Decrypted: \" + new String(decrypted, StandardCharsets.UTF_8));\n}\n```\nFor more information, refer:\nhttps://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions\n" metadata: category: security - cwe: CWE-319 + confidence: HIGH + cwe: CWE-327 + impact: MEDIUM + likelihood: MEDIUM owasp: - A3:2017-Sensitive Data Exposure - A02:2021-Cryptographic Failures - security-severity: Info - shortDescription: Cleartext transmission of sensitive information - patterns: - - pattern: new java.net.Socket(...) + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + - https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html + security-severity: MEDIUM + shortDescription: Use of a broken or risky cryptographic algorithm + subcategory: + - vuln + technology: + - java + pattern-either: + - pattern: | + javax.crypto.Cipher.getInstance("RC4") + - patterns: + - pattern-inside: | + class $CLS{ + ... + String $ALG = "RC4"; + ... + } + - pattern: | + javax.crypto.Cipher.getInstance($ALG); severity: WARNING - - id: scala_endpoint_rule-UnvalidatedRedirect + - id: java_deserialization_rule-InsecureJmsDeserialization languages: - - scala - message: | - Unvalidated redirects occur when an application redirects a user to a - destination URL specified by a user supplied parameter that is not validated. - Such vulnerabilities can be used to facilitate phishing attacks. + - java + message: "Deserialization of untrusted JMS ObjectMessage can lead to arbitrary \ncode execution. This vulnerability occurs when `ObjectMessage.getObject()` \nis called to deserialize the payload of an ObjectMessage, potentially \nallowing remote attackers to execute arbitrary code with the permissions \nof the JMS MessageListener application. \n\nTo mitigate the issue, avoid deserialization of untrusted data and \nconsider alternative message formats or explicit whitelisting of \nallowable classes for deserialization.\n\nTo implement allowlisting, override the ObjectInputStream#resolveClass() \nmethod to limit deserialization to allowed classes only. This prevents \ndeserialization of any class except those explicitly permitted, such as \nin the following example that restricts deserialization to the Bicycle \nclass only:\n\n```\n// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html\npublic class LookAheadObjectInputStream extends ObjectInputStream {\n public LookAheadObjectInputStream(InputStream inputStream) throws IOException {\n super(inputStream);\n }\n /**\n * Only deserialize instances of our expected Bicycle class\n */\n @Override\n protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {\n if (!desc.getName().equals(Bicycle.class.getName())) {\n throw new InvalidClassException(\"Unauthorized deserialization attempt\", desc.getName());\n }\n return super.resolveClass(desc);\n }\n}\n```\n" metadata: category: security - cwe: CWE-601 - security-severity: Info - shortDescription: URL Redirection to Untrusted Site ('Open Redirect') + confidence: MEDIUM + cwe: CWE-502 + cwe2021-top25: "true" + cwe2022-top25: "true" + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A8:2017-Insecure Deserialization + - A08:2021-Software and Data Integrity Failures + references: + - https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities-wp.pdf + security-severity: High + shortDescription: Deserialization of untrusted data + subcategory: + - vuln + technology: + - java + vulnerability_class: + - 'Insecure Deserialization ' patterns: - - pattern-either: - - patterns: - - pattern: '($REQ: HttpServletResponse).sendRedirect(...)' - - pattern-not: '($REQ: HttpServletResponse).sendRedirect("...")' - - patterns: - - pattern: '($REQ: HttpServletResponse).addHeader(...)' - - pattern-not: '($REQ: HttpServletResponse).addHeader("...", "...")' - - patterns: - - pattern: '($REQ: HttpServletResponse).encodeURL(...)' - - pattern-not: '($REQ: HttpServletResponse).encodeURL("...")' - - patterns: - - pattern: '($REQ: HttpServletResponse).encodeRedirectUrl(...)' - - pattern-not: '($REQ: HttpServletResponse).encodeRedirectUrl("...")' + - pattern-inside: | + class $JMS_LISTENER implements MessageListener { + ... + public void onMessage(Message $JMS_MSG) { + ... + } + } + - pattern: $Y.getObject(...); severity: ERROR - - id: scala_endpoint_rule-WeakHostNameVerification + - id: java_endpoint_rule-ManuallyConstructedURLs languages: - - scala + - java message: | - A HostnameVerifier that accept any host are often use because of certificate - reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middle - attacks since the client will trust any certificate. + User data flows into the host portion of this manually-constructed URL. + This could allow an attacker to send data to their own server, potentially + exposing sensitive data such as cookies or authorization information sent + with this request. They could also probe internal servers or other + resources that the server running this code can access. (This is called + server-side request forgery, or SSRF.) Do not allow arbitrary hosts. + Instead, create an allowlist for approved hosts hardcode the correct host, + or ensure that the user data can only affect the path or parameters. + + Example of using allowlist: + ``` + ArrayList allowlist = (ArrayList) + Arrays.asList(new String[] { "https://example.com/api/1", "https://example.com/api/2", "https://example.com/api/3"}); + + if(allowlist.contains(url)){ + ... + } + ``` metadata: category: security - cwe: CWE-295 - security-severity: Info - shortDescription: Improper Certificate Validation - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - class $V extends HostnameVerifier { + confidence: MEDIUM + cwe: CWE-918 + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + interfile: true + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A1:2017-Injection + - A10:2021-Server-Side Request Forgery + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html + security-severity: CRITICAL + shortDescription: Detect manually constructed URLs + subcategory: + - vuln + technology: + - java + - spring + vulnerability_class: + - Server-Side Request Forgery (SSRF) + mode: taint + options: + interfile: true + pattern-sanitizers: + - patterns: + - pattern-either: + - pattern: "if($VALIDATION){\n ...\n new URL($ONEARG);\n ...\n} \n" + - pattern: | + $A = $VALIDATION; + ... + if($A){ + ... + new URL($ONEARG); ... } - - pattern-either: - - pattern: def verify(...) = true + - metavariable-pattern: + metavariable: $VALIDATION + pattern-either: + - pattern: "$AL.contains(...) \n" - pattern: | - def verify(...) = { - return true - } + $AL.indexOf(...) != -1 + pattern-sinks: + - pattern-either: + - pattern: new URL($ONEARG) - patterns: - - pattern-inside: | - class $V extends X509TrustManager { - ... - } - pattern-either: - - pattern: 'def checkClientTrusted(...): Unit = {}' - - pattern: 'def checkServerTrusted(...): Unit = {}' - - pattern: def checkClientTrusted(...) = {} - - pattern: def checkServerTrusted(...) = {} - - pattern: 'def getAcceptedIssuers(): Array[X509Certificate] = null' - - pattern: 'def getAcceptedIssuers(): Array[X509Certificate] = {}' - severity: WARNING - - id: scala_file_rule-FileUploadFileName - languages: - - scala - message: | - The filename provided by the FileUpload API can be tampered with by the client to reference - unauthorized files. The provided filename should be properly validated to ensure it's properly - structured, contains no unauthorized path characters (e.g., / \), and refers to an authorized - file. - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Info - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - technology: - - scala - patterns: - - pattern: | - def $FUNC (..., $REQ: HttpServletRequest, ... ) = { - ... - val $FILES = ($SFU: ServletFileUpload).parseRequest($REQ) - ... - for ($FILE <- $FILES.asScala) { - ... - } - } - - pattern: $ITEM.getName() - severity: WARNING - - id: scala_file_rule-FilenameUtils + - pattern: | + "$URLSTR" + ... + - pattern: | + "$URLSTR".concat(...) + - patterns: + - pattern-inside: | + StringBuilder $SB = new StringBuilder("$URLSTR"); + ... + - pattern: $SB.append(...) + - patterns: + - pattern-inside: | + $VAR = "$URLSTR"; + ... + - pattern: $VAR += ... + - patterns: + - pattern: String.format("$URLSTR", ...) + - pattern-not: String.format("$URLSTR", "...", ...) + - patterns: + - pattern-inside: | + String $VAR = "$URLSTR"; + ... + - pattern: String.format($VAR, ...) + - metavariable-regex: + metavariable: $URLSTR + regex: http(s?)://%(v|s|q).* + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + $METHODNAME(..., @$REQ(...) $TYPE $SOURCE,...) { + ... + } + - pattern-inside: | + $METHODNAME(..., @$REQ $TYPE $SOURCE,...) { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Integer|Long|Float|Double|Char|Boolean|int|long|float|double|char|boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute) + - focus-metavariable: $SOURCE + severity: ERROR + - id: java_file_rule_rule-FilePathTraversalHttpServlet languages: - - scala - message: | - A file is opened to read its content. The filename comes from an input - parameter. If an unfiltered parameter is passed to this file API, files from an - arbitrary filesystem location could be read. + - java + message: "Detected a potential path traversal. A malicious actor could control\nthe location of this file, to include going backwards in the directory\nwith '../'. \n\nTo address this, ensure that user-controlled variables in file\npaths are sanitized. You may also consider using a utility method such as\norg.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file\nname from the path.\n\nExample code using FilenameUtils.getName(...)\n\n```\npublic void ok(HttpServletRequest request, HttpServletResponse response)\n throws ServletException, IOException {\n String image = request.getParameter(\"image\");\n File file = new File(\"static/images/\", FilenameUtils.getName(image));\n\n if (!file.exists()) {\n log.info(image + \" could not be created.\");\n response.sendError();\n }\n\n response.sendRedirect(\"/index.html\");\n}\n```\n" metadata: category: security + confidence: MEDIUM cwe: CWE-22 + cwe2021-top25: true + cwe2022-top25: true + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] owasp: - A5:2017-Broken Access Control - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') + references: + - https://www.owasp.org/index.php/Path_Traversal + security-severity: CRITICAL + shortDescription: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') + source-rule-url: https://find-sec-bugs.github.io/bugs.htm#PATH_TRAVERSAL_IN technology: - - scala - pattern-either: + - java + vulnerability_class: + - Path Traversal + mode: taint + pattern-sanitizers: + - pattern: org.apache.commons.io.FilenameUtils.getName(...) + pattern-sinks: - patterns: - - pattern-inside: | - import org.apache.commons.io.FilenameUtils._ - ... - pattern-either: - - pattern: normalize(...) - - pattern: getExtension(...) - - pattern: isExtensions(...) - - pattern: isExtension(...) - - pattern: getName(...) - - pattern: getBaseName(...) + - pattern: | + (java.io.File $FILE) = ... + - pattern: | + (java.io.FileOutputStream $FOS) = ... + - pattern: | + new java.io.FileInputStream(...) + pattern-sources: - patterns: - pattern-either: - - pattern: org.apache.commons.io.FilenameUtils.normalize(...) - - pattern: org.apache.commons.io.FilenameUtils.getExtension(...) - - pattern: org.apache.commons.io.FilenameUtils.isExtensions(...) - - pattern: org.apache.commons.io.FilenameUtils.isExtension(...) - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - - pattern: org.apache.commons.io.FilenameUtils.getBaseName(...) - severity: WARNING - - id: scala_form_rule-FormValidate - languages: - - scala - message: | - Form inputs should have minimal input validation. Preventive validation helps provide defense - in depth against a variety of risks. - metadata: - category: security - cwe: CWE-1289 - security-severity: Info - shortDescription: Improper validation of unsafe equivalence in input - patterns: - - pattern-inside: | - class $CLASS extends $SC { - ... - } - - metavariable-regex: - metavariable: $SC - regex: (ActionForm|ValidatorForm) - - pattern-not: public void validate() { ... } - severity: WARNING - - id: scala_inject_rule-AWSQueryInjection + - pattern: | + (HttpServletRequest $REQ) + - patterns: + - pattern-inside: | + (javax.servlet.http.Cookie[] $COOKIES) = (HttpServletRequest $REQ).getCookies(...); ... + for (javax.servlet.http.Cookie $COOKIE: $COOKIES) { + ... + } + - pattern: | + $COOKIE.getValue(...) + - patterns: + - pattern-inside: | + $TYPE[] $VALS = (HttpServletRequest $REQ).$GETFUNC(...); + ... + - pattern: | + $PARAM = $VALS[$INDEX]; + severity: ERROR + - id: java_inject_rule-EnvInjection languages: - - scala - message: | - Constructing SimpleDB queries containing user input can allow an attacker to view unauthorized - records. + - java + message: "Detected input from a HTTPServletRequest going into the environment\nvariables of an 'exec' command. The user input is passed directly to\nthe Runtime.exec() function to set an environment variable. This allows \nmalicious input from the user to modify the command that will be executed.\nTo remediate this, do not pass user input directly to Runtime.exec().\nValidate any user input before using it to set environment variables \nor command arguments. Consider using an allow list of allowed values\nrather than a deny list. If dynamic commands must be constructed, use\na map to look up valid values based on user input instead of using \nthe input directly.\nExample of safely executing an OS command:\n```\npublic void doPost(HttpServletRequest request, HttpServletResponse response)\n throws ServletException, IOException {\n response.setContentType(\"text/html;charset=UTF-8\");\n\n String param = \"\";\n if (request.getHeader(\"UserDefined\") != null) {\n param = request.getHeader(\"UserDefined\");\n }\n\n param = java.net.URLDecoder.decode(param, \"UTF-8\");\n String cmd = \"/bin/cmd\";\n\n String[] allowList = {\"FOO=true\",\"FOO=false\",\"BAR=true\", \"BAR=false\"}\n if(Arrays.asList(allowList).contains(param)){\n String[] argsEnv = {param};\n }\n \n Runtime r = Runtime.getRuntime();\n\n try {\n Process p = r.exec(cmd, argsEnv);\n printOSCommandResults(p, response); \n } catch (IOException e) {\n System.out.println(\"Problem executing command\");\n response.getWriter()\n .println(org.owasp.esapi.ESAPI.encoder().encodeForHTML(e.getMessage()));\n return;\n }\n```\n" metadata: category: security - cwe: CWE-943 - security-severity: Info - shortDescription: Improper Neutralization of Special Elements in Data Query Logic + confidence: MEDIUM + cwe: CWE-78 + impact: MEDIUM + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: MEDIUM + owasp: + - A1:2017-Injection + - A03:2021-Injection + references: + - https://owasp.org/Top10/A03_2021-Injection + security-severity: HIGH + shortDescription: Improper neutralization of special elements used in an OS command ('OS Command Injection') + subcategory: + - vuln technology: - - scala + - java + vulnerability_class: + - Other mode: taint - pattern-sinks: - - pattern: new com.amazonaws.services.simpledb.model.SelectRequest($QUERY, ...); + pattern-sanitizers: - patterns: - - pattern-inside: | - $DB.select(($SR: com.amazonaws.services.simpledb.model.SelectRequest).withSelectExpression($QUERY,...)); - - pattern: $QUERY + - pattern-either: + - pattern: | + if($VALIDATION){ + ... + } + - patterns: + - pattern-inside: | + $A = $VALIDATION; + ... + - pattern: | + if($A){ + ... + } - metavariable-pattern: - metavariable: $DB + metavariable: $VALIDATION pattern-either: - - pattern: '($DB: com.amazonaws.services.simpledb.AmazonSimpleDB)' - - pattern: '($DB: com.amazonaws.services.simpledb.AmazonSimpleDBClient)' + - pattern: | + $AL.contains(...) + pattern-sinks: + - pattern-either: + - patterns: + - pattern: (java.lang.Runtime $R).exec($CMD, $ENV_ARGS, ...); + - focus-metavariable: $ENV_ARGS + - patterns: + - pattern: (ProcessBuilder $PB).environment().put($...ARGS); + - focus-metavariable: $...ARGS + - patterns: + - pattern: | + $ENV = (ProcessBuilder $PB).environment(); + ... + $ENV.put($...ARGS); + - focus-metavariable: $...ARGS pattern-sources: - patterns: - - pattern-inside: | - def $FUNC(..., $REQ: HttpServletRequest, ...): $TYPE = { - ... - } - - pattern: $REQ + - pattern-either: + - pattern: | + (HttpServletRequest $REQ) - patterns: - pattern-inside: | - def $FUNC(..., $X: $TYPE, ...): $RET_TYPE = { - ... - $QUERY = <...$X...> - ... + $FUNC(..., $VAR, ...) { + ... } - - pattern: $QUERY + - pattern: $VAR severity: ERROR - - id: scala_inject_rule-BeanPropertyInjection + - id: java_xxe_rule-DisallowDoctypeDeclFalse languages: - - scala - message: | - An attacker can set arbitrary bean properties that can compromise system integrity. An - attacker can leverage this functionality to access special bean properties like - class.classLoader that will allow them to override system properties and potentially execute - arbitrary code. + - java + message: "DOCTYPE declarations are enabled for $DBFACTORY. Without prohibiting\nexternal entity declarations, this is vulnerable to XML external entity\nattacks. In an XXE attack, an attacker can exploit the processing of external \nentity references within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise.\n\nTo mitigate this vulnerability, disable this by setting the feature\n\"http://apache.org/xml/features/disallow-doctype-decl\" to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\nentities declarations. This can be done by setting the features\n\"http://xml.org/sax/features/external-general-entities\" and\n\"http://xml.org/sax/features/external-parameter-entities\" to false.\n\nSecure Code Example: \n``` \npublic void GoodXMLInputFactory() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n} \n```\n" metadata: category: security - cwe: CWE-15 - security-severity: Info - shortDescription: External Control of System or Configuration Setting + confidence: HIGH + cwe: CWE-611 + cwe2021-top25: "true" + cwe2022-top25: "true" + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference technology: - - scala + - java + - xml + vulnerability_class: + - XML Injection patterns: - - pattern-inside: 'def $FUNC(..., $REQ: HttpServletRequest, ...): $TYPE = { ... }' - - pattern-either: - - pattern: | - $MAP.put(..., $REQ.getParameter(...)) - ... - $BEAN_UTIL.populate(..., $MAP) - - pattern: | - while (...) { - ... - $MAP.put(..., $REQ.getParameterValues(...). ...) - } - ... - $BEAN_UTIL.populate(..., $MAP) - - metavariable-pattern: - metavariable: $BEAN_UTIL - pattern-either: - - pattern: (BeanUtilsBean $B) - - pattern: new BeanUtilsBean() - - pattern: org.apache.commons.beanutils.BeanUtils - severity: ERROR - - id: scala_inject_rule-CLRFInjectionLogs + - pattern: | + $DBFACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", + false); + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $DBF.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + ... + } + - pattern-not-inside: | + $RETURNTYPE $METHOD(...){ + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + ... + $DBF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + ... + } + severity: WARNING + - id: java_xxe_rule-DocumentBuilderFactoryDisallowDoctypeDeclMissing languages: - - scala - message: | - When data from an untrusted source is put into a logger and not neutralized correctly, an - attacker could forge log entries or include malicious content. Inserted false entries could be - used to skew statistics, distract the administrator or even to implicate another party in the - commission of a malicious act. If the log file is processed automatically, the attacker can - render the file unusable by corrupting the format of the file or injecting unexpected - characters. An attacker may also inject code or other commands into the log file and take - advantage of a vulnerability in the log processing utility (e.g. command injection or XSS). + - java + message: "DOCTYPE declarations are enabled for this DocumentBuilderFactory. Enabling \nDOCTYPE declarations without proper restrictions can make your application \nvulnerable to XML External Entity (XXE) attacks. \nIn an XXE attack, an attacker can exploit the processing of external entity \nreferences within an XML document to access internal files, conduct \ndenial-of-service attacks, or SSRF (Server Side Request Forgery), potentially \nleading to sensitive information disclosure or system compromise. \n\nTo mitigate this vulnerability, disable this by setting the\nfeature \"http://apache.org/xml/features/disallow-doctype-decl\" to true.\nAlternatively, allow DOCTYPE declarations and only prohibit external\nentities declarations. This can be done by setting the features\n\"http://xml.org/sax/features/external-general-entities\" and\n\"http://xml.org/sax/features/external-parameter-entities\" to false.\n\nSecure Code Example (You can do either of the following):\n```\npublic void GoodDocumentBuilderFactory() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n dbf.newDocumentBuilder();\n}\n\npublic void GoodDocumentBuilderFactory2() throws ParserConfigurationException {\n DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\n dbf.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n dbf.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n dbf.newDocumentBuilder();\n}\n```\n" metadata: category: security - cwe: CWE-93 - security-severity: Info - shortDescription: Improper Neutralization of CRLF Sequences ('CRLF Injection') + confidence: HIGH + cwe: CWE-611 + cwe2021-top25: "true" + cwe2022-top25: "true" + impact: HIGH + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A4:2017-XML External Entities (XXE) + - A05:2021-Security Misconfiguration + references: + - https://semgrep.dev/blog/2022/xml-security-in-java + - https://semgrep.dev/docs/cheat-sheets/java-xxe/ + - https://blog.sonarsource.com/secure-xml-processor + - https://xerces.apache.org/xerces2-j/features.html + security-severity: MEDIUM + shortDescription: Improper restriction of XML external entity reference + subcategory: + - vuln technology: - - scala + - java + - xml + vulnerability_class: + - XML Injection mode: taint pattern-sanitizers: - - patterns: - - pattern-inside: $STR.replaceAll("$REPLACE_CHAR", "$REPLACE"); - - pattern: $STR - - metavariable-regex: - metavariable: $REPLACE_CHAR - regex: (.*\\r\\n.*) - - metavariable-regex: - metavariable: $REPLACE - regex: (?!(\\r\\n)) - - pattern: org.owasp.encoder.Encode.forUriComponent(...) - - pattern: org.owasp.encoder.Encode.forUri(...) - - pattern: java.net.URLEncoder.encode(..., $CHARSET) + - by-side-effect: true + pattern-either: + - patterns: + - pattern-either: + - pattern: | + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); ... $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + - pattern: | + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); ... $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + - focus-metavariable: $FACTORY + - patterns: + - pattern-either: + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", + true); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } + ... + } + - pattern-inside: | + class $C { + ... + $T $M(...) { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false); + ... + } + ... + } + - pattern: $M($X) + - focus-metavariable: $X pattern-sinks: - patterns: - - patterns: - - pattern: $LOGGER.$METHOD(...,<...$TAINTED...>,...) - - focus-metavariable: $TAINTED - - metavariable-regex: - metavariable: $METHOD - regex: (log|logp|logrb|entering|exiting|fine|finer|finest|info|debug|trace|warn|warning|config|error|severe) - - metavariable-pattern: - metavariable: $LOGGER - pattern-either: - - pattern: Logger - - pattern: log - - pattern: logger - - pattern: org.pmw.tinylog.Logger - - pattern: org.apache.log4j.Logger - - pattern: org.apache.logging.log4j.Logger - - pattern: org.slf4j.Logger - - pattern: org.apache.commons.logging.Log - - pattern: java.util.logging.Logger + - pattern: | + $FACTORY.newDocumentBuilder(); pattern-sources: - - patterns: + - by-side-effect: true + patterns: + - pattern: | + $FACTORY - pattern-inside: | - def $FUNC(..., $REQ: HttpServletRequest, ...) : $TYPE = { + $FACTORY = DocumentBuilderFactory.newInstance(); + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + ... + static { + ... + $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + ... + } ... } - - pattern: $REQ.getParameter(...) - severity: ERROR - - id: scala_inject_rule-CommandInjection - languages: - - scala - message: | - The highlighted API is used to execute a system command. If unfiltered input is passed to this - API, it can lead to arbitrary command execution. - metadata: - category: security - cwe: CWE-78 - security-severity: Info - shortDescription: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') - technology: - - scala - pattern-either: - - patterns: - - pattern-inside: | - def $FUNC(..., $PARAM: String, ...): $TYPE = { + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + ... + static { + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + } ... } - - pattern-inside: | - val $RT = Runtime.getRuntime - ... - - pattern-either: - - pattern: $RT.exec($PARAM) - - pattern: | - var $CMDARR = new Array[String]("$SHELL",...,$PARAM,...) + - pattern-not-inside: | + class $C { + ... + $V $FACTORY = DocumentBuilderFactory.newInstance(); + ... + static { ... - $RT.exec($CMDARR,...) - - pattern: $RT.exec(Array[String]("$SHELL",...,$PARAM,...), ...) - - pattern: $RT.exec(java.util.String.format("...", ...,$PARAM,...)) - - pattern: '$RT.exec(($A: String) + ($B: String))' - - metavariable-regex: - metavariable: $SHELL - regex: (/.../)?(sh|bash|ksh|csh|tcsh|zsh)$ - - pattern-not: $RT.exec("...","...","...",...) - - pattern-not: $RT.exec(new Array[String]("...","...","...",...),...) - - patterns: - - pattern-inside: | - def $FUNC(...,$PARAM: String, ...): $TYPE = { + $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false); + ... + $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + ... + } ... } - - pattern-inside: | - val $PB = new ProcessBuilder() - ... - - pattern-either: - - pattern: $PB.command($PARAM,...) - - patterns: - - pattern-either: - - pattern: $PB.command("$SHELL",...,$PARAM,...) - - pattern: | - var $CMDARR = java.util.Arrays.asList("$SHELL",...,$PARAM,...) - ... - $PB.command($CMDARR,...) - - pattern: $PB.command(java.util.Arrays.asList("$SHELL",...,$PARAM,...),...) - - pattern: $PB.command(java.util.String.format("...", ...,$PARAM,...)) - - pattern: '$PB.command(($A: String) + ($B: String))' - - metavariable-regex: - metavariable: $SHELL - regex: (/.../)?(sh|bash|ksh|csh|tcsh|zsh)$ - - pattern-not: $PB.command("...","...","...",...) - - pattern-not: | - $PB.command(java.util.Arrays.asList("...","...","...",...)) severity: WARNING - - id: scala_inject_rule-CustomInjection + - id: properties_spring_rule-SpringActuatorFullyEnabled languages: - - scala - message: | - The method identified is susceptible to injection. The input should be validated and properly - escaped. + - generic + message: "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints\nsuch as /actuator/env, /actuator/logfile, /actuator/heapdump and others.\nIf the application lacks proper security measures (e.g., authentication and \nauthorization), sensitive data could be accessed, compromising the application and \nits infrastructure. This configuration poses a serious risk in production \nenvironments or public-facing deployments.\n\nTo mitigate the risks, take the following measures:\n - Expose only the Actuator endpoints required for your use case\n - For production environments, restrict exposure to non-sensitive endpoints \n like `health` or `info`\n - Ensure Actuator endpoints are protected with authentication and authorization \n (e.g., via Spring Security)\n - Use environment-specific configurations to limit exposure in production\n\nSecure Code Example:\nInstead of include: \"*\", list only the endpoints you need to expose:\n```\nmanagement.endpoints.web.exposure.include=\"health,info,metrics\"\n```\n\nReferences:\n- https://docs.spring.io/spring-boot/reference/actuator/endpoints.html#actuator.endpoints.exposing\n- https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785\n- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators\n" metadata: category: security - cwe: CWE-89 - security-severity: Low - shortDescription: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') + confidence: MEDIUM + cwe: CWE-497 + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2021-Broken Access Control + - A3:2017-Sensitive Data Exposure + security-severity: Medium + shortDescription: Exposure of sensitive system information to an unauthorized control sphere technology: - - scala - patterns: - - pattern-either: - - pattern-inside: | - val $ST = connection.createStatement - ... - - pattern-either: - - pattern: | - val $QUERY = ... + $VAR + ... - ... - $ST.executeQuery($QUERY) - - pattern: | - val $QUERY = ... + $VAR - ... - $ST.executeQuery($QUERY) - - pattern: | - val $QUERY = String.format("...",...,$VAR,...) - ... - $ST.executeQuery($QUERY) - - pattern: '$ST.executeQuery(($SB: StringBuilder).toString())' - - pattern: $ST.executeQuery(... + $VAR + ...) - - pattern: $ST.executeQuery(... + $VAR) - - pattern: $ST.executeQuery(...,String.format("...",...,$VAR,...), ...) + - java + paths: + include: + - '*properties' + pattern: management.endpoints.web.exposure.include=* severity: WARNING - - id: scala_inject_rule-CustomInjectionSQLString + - id: python_crypto_rule-HTTPConnectionPool languages: - - scala - message: | - The method identified is susceptible to injection. The input should be validated and properly - escaped. + - python + message: "The application is using HTTPConnectionPool method. This method transmits\ndata in cleartext, which is vulnerable to MITM (Man in the middle)\nattacks. In MITM attacks, the data transmitted over the unencrypted\nconnection can be intercepted, read and/or modified by unauthorized\nparties which can lead to data integrity and confidentiality loss. \n\nTo mitigate this issue, use HTTPSConnectionPool instead, which encrypts \ncommunications and enhances security.\n\nSecure Code Example:\n```\nimport urllib3\nspool = urllib3.connectionpool.HTTPSConnectionPool(\"example.com\")\n```\n" metadata: category: security - cwe: CWE-89 - security-severity: High - shortDescription: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') + confidence: MEDIUM + cwe: CWE-319 + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://urllib3.readthedocs.io/en/1.2.1/pools.html#urllib3.connectionpool.HTTPSConnectionPool + security-severity: MEDIUM + shortDescription: Cleartext transmission of sensitive information + subcategory: + - audit technology: - - scala - patterns: - - pattern-inside: | - def $FOO(..., $SQLIN: String, ...): $TYPE = { - ... - } - - pattern-either: - - pattern: | - "$SQL_STR" + $SQLIN - - pattern: String.format("$SQL_STR", ... + $SQLIN + ...) - - pattern: | - "$SQL_STR".concat(...) - - pattern: (StringBuilder $BUILDER). ... .append("$SQL_STR") - - patterns: - - pattern-inside: | - StringBuilder $BUILDER = new StringBuilder(... + "$SQL_STR" + ...); - ... - - pattern: $BUILDER.append(...) - - pattern-not: $BUILDER.append("...") - - patterns: - - pattern-inside: | - $QUERY = "$SQL_STR"; - ... - - pattern: $QUERY += ... - - metavariable-regex: - metavariable: $SQL_STR - regex: (?i)(select|insert|create|update|alter|delete|drop)\b + - python + pattern-either: + - pattern: urllib3.HTTPConnectionPool(...) + - pattern: urllib3.connectionpool.HTTPConnectionPool(...) severity: WARNING - - id: scala_inject_rule-ELInjection + - id: python_flask_rule-path-traversal-open languages: - - scala - message: | - An expression is built with a dynamic value. The source of the value(s) should be verified to - avoid that unfiltered values fall into this risky code evaluation. + - python + message: "Found request data in a call to 'open'. An attacker can manipulate this input to access files outside the intended \ndirectory. This can lead to unauthorized access to sensitive files or directories. To prevent path traversal attacks, \navoid using user-controlled input in file paths. If you must use user-controlled input, validate and sanitize the \ninput to ensure it does not contain any path traversal sequences. For example, you can use the `os.path.join` function \nto safely construct file paths or validate that the absolute path starts with the directory which is whitelisted for \naccessing file. The following code snippet demonstrates how to validate a file path from user-controlled input:\n```\nimport os\n\ndef safe_open_file(filename, base_path):\n # Resolve the absolute path of the user-supplied filename\n absolute_path = os.path.abspath(filename)\n\n # Check that the absolute path starts with the base path\n if not absolute_path.startswith(base_path):\n raise ValueError(\"Invalid file path\")\n\n return open(absolute_path, 'r')\n```\nFor more information, see the OWASP Path Traversal page: https://owasp.org/www-community/attacks/Path_Traversal\n" metadata: category: security - cwe: CWE-94 - security-severity: High - shortDescription: Improper Control of Generation of Code ('Code Injection') + confidence: MEDIUM + cwe: CWE-22 + impact: HIGH + likelihood: MEDIUM + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + references: + - https://owasp.org/www-community/attacks/Path_Traversal + security-severity: CRITICAL + shortDescription: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') technology: - - scala - patterns: - - pattern-inside: | - import javax.el._ - ... - - pattern-either: - - pattern-inside: | - def $FUNC(..., $EXPR: String, ...) : $TYPE = { - ... - } - - pattern-inside: | - def $FUNC(..., $EXPR: String, ...) = { - ... - } - - pattern-either: - - pattern: $X.createValueExpression(..., $EXPR, ...) - - pattern: $X.createMethodExpression(..., $EXPR, ...) - severity: WARNING - - id: scala_inject_rule-FileDisclosure - languages: - - scala - message: | - Constructing a server-side redirect path with user input could allow an - attacker to download application binaries (including application classes or - jar files) or view arbitrary files within protected directories. - metadata: - category: security - cwe: CWE-552 - security-severity: Info - shortDescription: Files or Directories Accessible to External Parties - mode: taint - pattern-sinks: - - patterns: - - pattern: new org.springframework.web.servlet.ModelAndView($FST) - - pattern: $FST + - flask + pattern-either: - patterns: - - pattern: new org.springframework.web.servlet.ModelAndView($FST, $SND) - - pattern: $FST + - pattern: open(...) + - pattern-either: + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + open(..., <... $ROUTEVAR ...>, ...) + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + with open(..., <... $ROUTEVAR ...>, ...) as $FD: + ... + - pattern-inside: | + @$APP.route($ROUTE, ...) + def $FUNC(..., $ROUTEVAR, ...): + ... + $INTERIM = <... $ROUTEVAR ...> + ... + open(..., <... $INTERIM ...>, ...) + - pattern: open(..., <... flask.request.$W.get(...) ...>, ...) + - pattern: open(..., <... flask.request.$W[...] ...>, ...) + - pattern: open(..., <... flask.request.$W(...) ...>, ...) + - pattern: open(..., <... flask.request.$W ...>, ...) - patterns: - - pattern: new org.springframework.web.servlet.ModelAndView($FST, $SND, $TRD) - - pattern: $FST + - pattern-inside: | + $INTERIM = <... flask.request.$W.get(...) ...> + ... + open(<... $INTERIM ...>, ...) + - pattern: open(...) - patterns: - - pattern: new org.apache.struts.action.ActionForward($FST) - - pattern: $FST + - pattern-inside: | + $INTERIM = <... flask.request.$W[...] ...> + ... + open(<... $INTERIM ...>, ...) + - pattern: open(...) - patterns: - - pattern: new org.apache.struts.action.ActionForward($FST, $SND) - - pattern: $FST + - pattern-inside: | + $INTERIM = <... flask.request.$W(...) ...> + ... + open(<... $INTERIM ...>, ...) + - pattern: open(...) - patterns: - - pattern: new org.apache.struts.action.ActionForward($FST, $SND, $TRD) - - pattern: $SND + - pattern-inside: | + $INTERIM = <... flask.request.$W ...> + ... + open(<... $INTERIM ...>, ...) + - pattern: open(...) - patterns: - - pattern: new org.apache.struts.action.ActionForward($FST, $SND, $TRD) - - pattern: $TRD + - pattern-inside: | + $INTERIM = <... flask.request.$W.get(...) ...> + ... + with open(<... $INTERIM ...>, ...) as $F: + ... + - pattern: open(...) - patterns: - pattern-inside: | - $ACTION = new org.apache.struts.action.ActionForward() + $INTERIM = <... flask.request.$W[...] ...> ... - - pattern: $ACTION.setPath(...) + with open(<... $INTERIM ...>, ...) as $F: + ... + - pattern: open(...) - patterns: - pattern-inside: | - $MVC = new org.springframework.web.servlet.ModelAndView() + $INTERIM = <... flask.request.$W(...) ...> ... - - pattern: $MVC.setViewName(...); + with open(<... $INTERIM ...>, ...) as $F: + ... + - pattern: open(...) - patterns: - pattern-inside: | - $REQ = $HTTP.getRequestDispatcher(...) + $INTERIM = <... flask.request.$W ...> ... - - pattern-either: - - pattern: $REQ.include($FST, $SND) - - pattern: $REQ.forward($FST, $SND) - pattern-sources: - - pattern: '($VAR: javax.servlet.http.HttpServletRequest).getParameter(...)' + with open(<... $INTERIM ...>, ...) as $F: + ... + - pattern: open(...) severity: ERROR - - id: scala_inject_rule-HttpParameterPollution + - id: python_jwt_rule-jwt-none-alg languages: - - scala + - python message: | - Concatenating unvalidated user input into a URL can allow an attacker to override the value of - a request parameter. Attacker may be able to override existing parameter values, inject a new - parameter or exploit variables out of a direct reach. HTTP Parameter Pollution (HPP) attacks - consist of injecting encoded query string delimiters into other existing parameters. If a web - application does not properly sanitize the user input, a malicious user may compromise the - logic of the application to perform either client-side or server-side attacks. + Detected use of the 'none' algorithm in a JWT token. + The 'none' algorithm assumes the integrity of the token has already + been verified. This would allow a malicious actor to forge a JWT token + that will automatically be verified. Do not explicitly use the 'none' + algorithm. Instead, use an algorithm such as 'HS256'. metadata: category: security - cwe: CWE-88 - security-severity: Info - shortDescription: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') + confidence: MEDIUM + cwe: CWE-327 + impact: MEDIUM + likelihood: MEDIUM + owasp: + - A3:2017-Sensitive Data Exposure + - A02:2021-Cryptographic Failures + references: + - https://owasp.org/Top10/A02_2021-Cryptographic_Failures + security-severity: MEDIUM + shortDescription: Use of a Broken or Risky Cryptographic Algorithm + source-rule-url: https://semgrep.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + subcategory: + - vuln technology: - - scala - mode: taint - pattern-sanitizers: - - pattern: java.net.URLEncoder.encode(...) - - pattern: com.google.common.net.UrlEscapers.urlPathSegmentEscaper().escape(...) - pattern-sinks: - - pattern: new org.apache.http.client.methods.HttpGet(...) - - pattern: new org.apache.commons.httpclient.methods.GetMethod(...) - - pattern: '($GM: org.apache.commons.httpclient.methods.GetMethod).setQueryString(...)' - pattern-sources: - - pattern: '($REQ: HttpServletRequest ).getParameter(...)' + - jwt + pattern-either: + - pattern: jwt.encode(...,algorithm="none",...) + - pattern: jwt.decode(...,algorithms=[...,"none",...],...) severity: ERROR - - id: scala_inject_rule-LDAPInjection + - id: python_pyramid_rule-pyramid-csrf-origin-check languages: - - scala - message: | - Just like SQL, all inputs passed to an LDAP query need to be passed in safely. Unfortunately, - LDAP doesn't have prepared statement interfaces like SQL. Therefore, the primary defense - against LDAP injection is strong input validation of any untrusted data before including it in - an LDAP query. + - python + message: "Automatic check of the referrer for cross-site request forgery tokens\nhas been explicitly disabled globally, which might leave views unprotected\nwhen an unsafe CSRF storage policy is used. By passing `check_origin=False` \nto `set_default_csrf_options()` method, you opt out of checking the origin \nof the domain in the referrer header or the origin header, which can make \nthe application vulnerable to CSRF attacks, specially if CSRF token is not \nproperly implemented.\nCSRF attacks are a type of exploit where an attacker tricks a user into \nexecuting unwanted actions on a web application in which they are authenticated. \nIf a user is logged into a web application, an attacker could create a malicious \nlink or script on another site that causes the user's browser to make a request \nto the web application, carrying out an action without the user's consent.\n\nTo mitigate this vulnerability, use \n'pyramid.config.Configurator.set_default_csrf_options(check_origin=True)'\nto turn the automatic check for all unsafe methods (per RFC2616).\n\nSecure Code Example:\n```\ndef safe(config):\n config.set_csrf_storage_policy(CookieCSRFStoragePolicy())\n config.set_default_csrf_options(check_origin=True)\n```\n" metadata: category: security - cwe: CWE-90 - security-severity: Medium - shortDescription: Improper Neutralization of Special Elements used in an LDAP Query ('LDAP Injection') + confidence: MEDIUM + cwe: CWE-352 + cwe2021-top25: "true" + cwe2022-top25: "true" + impact: LOW + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + likelihood: LOW + owasp: + - A5:2017-Broken Access Control + - A01:2021-Broken Access Control + references: + - https://owasp.org/Top10/A01_2021-Broken_Access_Control + - https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/security.html + security-severity: MEDIUM + shortDescription: Cross-site request forgery (CSRF) + subcategory: + - vuln technology: - - scala + - pyramid + vulnerability_class: + - Cross-Site Request Forgery (CSRF) patterns: - - pattern-either: - - pattern-inside: | - def $FUNC(..., $VAR: String, ...): $TYPE = { - ... - } - - pattern-inside: | - def $FUNC(..., $X: String, ...): $TYPE = { - ... - $VAR = ... + $X; - ... - } - - pattern-either: - - pattern: '($P: java.util.Properties).put($KEY, $VAR)' - - pattern: $CTX.lookup(..., $VAR, ...) - - pattern: $CTX.search(..., $VAR, ...) - - pattern: $CTX.list(..., $VAR, ...) - - metavariable-pattern: - metavariable: $CTX - pattern-either: - - pattern: '($CTX: javax.naming.directory.DirContext)' - - pattern: '($CTX: javax.naming.directory.Context)' - - pattern: '($CTX: javax.naming.Context)' - - pattern: '($CTX: javax.naming.directory.InitialDirContext)' - - pattern: '($CTX: javax.naming.ldap.LdapContext)' - - pattern: '($CTX: com.unboundid.ldap.sdk.LDAPConnection)' - - pattern: '($CTX: javax.naming.event.EventDirContext)' - - pattern: '($CTX: com.sun.jndi.ldap.LdapCtx)' - - pattern: '($CTX: org.springframework.ldap.core.LdapTemplate)' - - pattern: '($CTX: org.springframework.ldap.core.LdapOperations)' + - pattern-inside: | + $CONFIG.set_default_csrf_options(..., check_origin=$CHECK_ORIGIN, ...) + - pattern: | + $CHECK_ORIGIN + - metavariable-comparison: + comparison: $CHECK_ORIGIN == False + metavariable: $CHECK_ORIGIN severity: WARNING - - id: scala_inject_rule-OgnlInjection + - id: yaml_spring_rule-SpringActuatorFullyEnabled languages: - - scala - message: | - "A expression is built with a dynamic value. The source of the value(s) should be verified to - avoid that unfiltered values fall into this risky code evaluation." + - yaml + message: "Spring Boot Actuator is fully enabled. This exposes sensitive endpoints\nsuch as /actuator/env, /actuator/logfile, /actuator/heapdump and others.\nIf the application lacks proper security measures (e.g., authentication and \nauthorization), sensitive data could be accessed, compromising the application and \nits infrastructure. This configuration poses a serious risk in production \nenvironments or public-facing deployments.\n\nTo mitigate the risks, take the following measures:\n - Expose only the Actuator endpoints required for your use case\n - For production environments, restrict exposure to non-sensitive endpoints \n like `health` or `info`\n - Ensure Actuator endpoints are protected with authentication and authorization \n (e.g., via Spring Security)\n - Use environment-specific configurations to limit exposure in production\n\nSecure Code Example:\nInstead of include: \"*\", list only the endpoints you need to expose:\n```\nmanagement:\n endpoints:\n web:\n exposure:\n include: \"health,info,metrics\"\n```\n\nReferences:\n- https://docs.spring.io/spring-boot/reference/actuator/endpoints.html#actuator.endpoints.exposing\n- https://medium.com/walmartglobaltech/perils-of-spring-boot-actuators-misconfiguration-185c43a0f785\n- https://blog.maass.xyz/spring-actuator-security-part-1-stealing-secrets-using-spring-actuators\n" metadata: category: security - cwe: CWE-917 + confidence: MEDIUM + cwe: CWE-497 + impact: HIGH + likelihood: MEDIUM + owasp: + - A01:2021-Broken Access Control + - A3:2017-Sensitive Data Exposure security-severity: Medium - shortDescription: Expression injection (OGNL) + shortDescription: Exposure of sensitive system information to an unauthorized control sphere technology: - - scala + - java patterns: - - pattern-either: - - pattern-inside: | - def $FUNC(..., $VAR: String, ...): $TYPE = { - ... - } - - pattern-inside: | - def $FUNC(..., $VAR: Map[$K,$V], ...): $TYPE = { - ... - } - - pattern-inside: | - def $FUNC(..., $VAR: java.util.HashMap[$K,$V], ...): $TYPE = { + - pattern: | + management: + ... + endpoints: + ... + web: ... - } - - pattern-either: - - pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariables(..., $VAR, ...) - - pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariablesCollection(..., $VAR, ...) - - pattern: com.opensymphony.xwork2.util.TextParseUtil.shallBeIncluded(..., $VAR, ...) - - pattern: com.opensymphony.xwork2.util.TextParseUtil.commaDelimitedStringToSet(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.TextParser).evaluate(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.OgnlTextParser).evaluate(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getGetMethod(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getSetMethod(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getField(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setProperties(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setProperty(...,$VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).getValue(...,$VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlReflectionProvider).setValue(...,$VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getGetMethod(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getSetMethod(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getField(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setProperties(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setProperty(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).getValue(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.util.reflection.ReflectionProvider).setValue(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setProperties(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setProperty(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).getValue(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).setValue(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).callMethod(..., $VAR, ...) - - pattern: ($P:com.opensymphony.xwork2.ognl.OgnlUtil).compile(..., $VAR, ...) - - pattern: ($P:org.apache.struts2.util.VelocityStrutsUtil).evaluate(...) - - pattern: org.apache.struts2.util.StrutsUtil.findString(...) - - pattern: org.apache.struts2.util.StrutsUtil.findValue(..., $VAL) - - pattern: org.apache.struts2.util.StrutsUtil.getText(...) - - pattern: org.apache.struts2.util.StrutsUtil.translateVariables(...) - - pattern: org.apache.struts2.util.StrutsUtil.makeSelectList(..., $VAR, ...) - - pattern: ($T:org.apache.struts2.views.jsp.ui.OgnlTool).findValue(..., $VAR, ...) - - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).findString(...) - - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).findValue(..., $VAR, ...) - - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).setValue(..., $VAR, ...) - - pattern: ($V:com.opensymphony.xwork2.util.ValueStack).setParameter(..., $VAR, ...) + exposure: + ... + include: "*" + ... severity: WARNING - - id: scala_inject_rule-PathTraversalIn + - id: kotlin_perm_rule-DangerousPermissions languages: - - scala + - kotlin message: | - A file is opened to read its content. The filename comes from an input parameter. If an - unfiltered parameter is passed to this file API, files from an arbitrary filesystem location - could be read. This rule identifies potential path traversal vulnerabilities. In many cases, - the constructed file path cannot be controlled by the user. + Do not grant dangerous combinations of permissions. metadata: category: security - cwe: CWE-22 + confidence: HIGH + cwe: CWE-277 owasp: - A5:2017-Broken Access Control - A01:2021-Broken Access Control - security-severity: Medium - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - technology: - - scala + security-severity: MEDIUM + shortDescription: Insecure inherited permissions patterns: - pattern-either: - patterns: - pattern-inside: | - def $FUNC(...,$ARGS: Array[String], ...): $TYPE = { - ... - } - - pattern-inside: | - $VAR = $ARGS($IDX) - ... - - pattern-inside: | - def $FUNC(...,$VAR: String, ...): $TYPE = { - ... - } - - pattern-not-inside: | - ... - org.apache.commons.io.FilenameUtils.getName($VAR) - ... - - pattern-either: - - patterns: - - pattern-inside: | - $U = new java.net.URI($VAR) + $PC = $X.getPermissions(...) ... - - pattern-either: - - pattern: new java.io.File($U) - - pattern: java.nio.file.Paths.get($U) - - pattern: new java.io.RandomAccessFile(..., $VAR,...) - - pattern: new java.io.FileReader(<...$VAR...>, ...) - - pattern: new javax.activation.FileDataSource(..., $VAR, ...) - - pattern: new java.io.FileInputStream(..., $VAR, ...) - - pattern: new java.io.File(<...$VAR...>, ...) - - pattern: java.nio.file.Paths.get(...,$VAR,...) - - pattern: java.io.File.createTempFile(...,$VAR, ...) - - pattern: java.io.File.createTempDirectory(...,$VAR,...) - - pattern: java.nio.file.Files.createTempFile(..., $VAR, ...) - - pattern: java.nio.file.Files.createTempDirectory(..., $VAR, ...) - - pattern: scala.io.Source.from(<...$VAR...>) - - pattern: scala.io.Source.fromFile(<...$VAR...>) - - pattern: scala.io.Source.fromString(<...$VAR...>) - severity: ERROR - - id: scala_inject_rule-PathTraversalOut - languages: - - scala - message: | - A file is opened to write to its contents. The filename comes from an input parameter. If an - unfiltered parameter is passed to this file API, files at an arbitrary filesystem location - could be modified. This rule identifies potential path traversal vulnerabilities. In many - cases, the constructed file path cannot be controlled by the user. - metadata: - category: security - cwe: CWE-22 - owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: High - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - technology: - - scala - mode: taint - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - - patterns: - - pattern-inside: new java.io.FileWriter($PATH, ...) - - pattern: $PATH - - patterns: - - pattern-inside: new java.io.FileOutputStream($PATH, ...) - - pattern: $PATH - pattern-sources: - - patterns: - - pattern-inside: | - def $FUNC(..., $ARGS: Array[String], ...): $TYPE = { - ... - } - - pattern: $ARGS[$IDX] - - patterns: - - pattern-inside: | - def $FUNC(..., $VAR: String, ...): $TYPE = { - ... - } - - pattern: $VAR + - pattern: $PC.add($PERMISSION) + - pattern: | + $REFVAR = $PERMISSION + ...; + ($PC: PermissionCollection).add($REFVAR) + - pattern: '($PC: PermissionCollection).add($PERMISSION)' + - metavariable-pattern: + metavariable: $PERMISSION + pattern-either: + - pattern: ReflectPermission("suppressAccessChecks") + - pattern: RuntimePermission("createClassLoader") severity: WARNING - - id: scala_inject_rule-SpotbugsPathTraversalAbsolute + - id: kotlin_perm_rule-OverlyPermissiveFilePermissionInline languages: - - scala + - kotlin message: | - "The software uses an HTTP request parameter to construct a pathname that should be within a - restricted directory, but it does not properly neutralize absolute path sequences such as - "/abs/path" that can resolve to a location that is outside of that directory. See - http://cwe.mitre.org/data/definitions/36.html for more information." + Overly permissive file permission metadata: category: security - cwe: CWE-22 + confidence: HIGH + cwe: CWE-732 owasp: - A5:2017-Broken Access Control - A01:2021-Broken Access Control - security-severity: Info - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - technology: - - scala - mode: taint - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - - patterns: - - pattern-inside: | - $U = new java.net.URI($VAR) - - pattern-either: - - pattern-inside: new java.io.File($U) - - pattern-inside: java.nio.file.Paths.get($U) - - pattern: $VAR - - patterns: - - pattern-inside: new java.io.RandomAccessFile($INPUT,...) - - pattern: $INPUT - - pattern: new java.io.FileReader(...) - - pattern: new javax.activation.FileDataSource(...) - - pattern: new java.io.FileInputStream(...) - - pattern: new java.io.File(...) - - pattern: java.nio.file.Paths.get(...) - - pattern: java.io.File.createTempFile(...) - - pattern: java.io.File.createTempDirectory(...) - - pattern: java.nio.file.Files.createTempFile(...) - - pattern: java.nio.file.Files.createTempDirectory(...) - - patterns: - - pattern-inside: new java.io.FileWriter($PATH, ...) - - pattern: $PATH - - patterns: - - pattern-inside: new java.io.FileOutputStream($PATH, ...) - - pattern: $PATH - pattern-sources: - - pattern: '($REQ: HttpServletRequest ).getParameter(...)' + security-severity: MEDIUM + shortDescription: Incorrect permission assignment for critical resource + patterns: + - pattern-either: + - pattern: java.nio.file.Files.setPosixFilePermissions(..., java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING")); + - pattern: | + $PERMISSIONS = java.nio.file.attribute.PosixFilePermissions.fromString("$PERM_STRING"); + ... + java.nio.file.Files.setPosixFilePermissions(..., $PERMISSIONS); + - metavariable-regex: + metavariable: $PERM_STRING + regex: '[rwx-]{6}[rwx]{1,}' severity: WARNING - - id: scala_inject_rule-SpotbugsPathTraversalRelative + - id: kotlin_strings_rule-BadHexConversion languages: - - scala + - kotlin message: | - "The software uses an HTTP request parameter to construct a pathname that should be within a - restricted directory, but it does not properly neutralize sequences such as ".." that can - resolve to a location that is outside of that directory. See - http://cwe.mitre.org/data/definitions/23.html for more information." + When converting a byte array containing a hash signature to a human readable string, a + conversion mistake can be made if the array is read byte by byte. metadata: category: security - cwe: CWE-22 + confidence: HIGH + cwe: CWE-704 owasp: - - A5:2017-Broken Access Control - - A01:2021-Broken Access Control - security-severity: Info - shortDescription: Improper limitation of a pathname to a restricted directory ('Path Traversal') - technology: - - scala - mode: taint - pattern-sanitizers: - - pattern: org.apache.commons.io.FilenameUtils.getName(...) - pattern-sinks: - - patterns: - - pattern-inside: | - $U = new java.net.URI($VAR) - - pattern-either: - - pattern-inside: new java.io.File($U) - - pattern-inside: java.nio.file.Paths.get($U) - - pattern: $VAR - - patterns: - - pattern-inside: new java.io.RandomAccessFile($INPUT,...) - - pattern: $INPUT - - pattern: new java.io.FileReader(...) - - pattern: new javax.activation.FileDataSource(...) - - pattern: new java.io.FileInputStream(...) - - pattern: new java.io.File(...) - - pattern: java.nio.file.Paths.get(...) - - pattern: java.io.File.createTempFile(...) - - pattern: java.io.File.createTempDirectory(...) - - pattern: java.nio.file.Files.createTempFile(...) - - pattern: java.nio.file.Files.createTempDirectory(...) - - patterns: - - pattern-inside: new java.io.FileWriter($PATH, ...) - - pattern: $PATH - - patterns: - - pattern-inside: new java.io.FileOutputStream($PATH, ...) - - pattern: $PATH - pattern-sources: - - patterns: - - pattern-inside: | - $P = ($REQ: HttpServletRequest ).getParameter(...); - ... - - pattern-either: - - pattern: $P + ... - - pattern: '... + $P' + - A6:2017-Security Misconfiguration + - A05:2021-Security Misconfiguration + security-severity: MEDIUM + shortDescription: Incorrect type conversion or cast + patterns: + - pattern-inside: | + $B_ARR = ($MD: java.security.MessageDigest).digest(...); + ... + - pattern-either: + - pattern: | + for($B in $B_ARR) { + ... + $B_TOSTR + } + - pattern: | + while(...) { + ... + $B_TOSTR + } + - pattern: | + do { + ... + $B_TOSTR + } while(...) + - metavariable-pattern: + metavariable: $B_TOSTR + patterns: + - pattern-either: + - pattern: java.lang.Integer.toHexString($B_TOINT) + - pattern: Integer.toHexString($B_TOINT) + - pattern: $B_TOINT.toHexString(...) + - metavariable-pattern: + metavariable: $B_TOINT + pattern-either: + - pattern: $B_ARR[...].toInt() + - pattern: $B_ARR[...] + - pattern: $B.toInt() + - pattern: $B severity: WARNING - - id: scala_inject_rule-SqlInjection + - id: kotlin_strings_rule-FormatStringManipulation languages: - - scala + - kotlin message: | - The input values included in SQL queries need to be passed in safely. Bind - variables in prepared statements can be used to easily mitigate the risk of - SQL injection. + Allowing user input to control format parameters could enable an attacker to cause exceptions + to be thrown or leak information.Attackers may be able to modify the format string argument, + such that an exception is thrown. If this exception is left uncaught, it may crash the + application. Alternatively, if sensitive information is used within the unused arguments, + attackers may change the format string to reveal this information. metadata: category: security - cwe: CWE-89 + confidence: HIGH + cwe: CWE-134 owasp: - A1:2017-Injection - A03:2021-Injection - security-severity: Medium - shortDescription: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') + security-severity: CRITICAL + shortDescription: Use of externally-controlled format string patterns: - - pattern-not-inside: | - $ARG = ... - ... - - pattern-not-inside: | - object $CLAZZ { - ... - $ARG = ... - ... - } - - pattern-not-inside: | - class $CLAZZ { - ... - $ARG = ... - ... - } - pattern-either: - patterns: - - pattern: ($PM:javax.jdo.PersistenceManager).newQuery(<...$ARG...>) - - pattern-not: ($PM:javax.jdo.PersistenceManager).newQuery("...") - - patterns: - - pattern: ($PM:javax.jdo.PersistenceManager).newQuery(..., <...$ARG...>) - - pattern-not: ($PM:javax.jdo.PersistenceManager).newQuery(..., "...") - - patterns: - - pattern: '($Q: javax.jdo.Query).setFilter(<...$ARG...>)' - - pattern-not: '($Q: javax.jdo.Query).setFilter("...")' - - patterns: - - pattern: '($Q: javax.jdo.Query).setGrouping(<...$ARG...>)' - - pattern-not: '($Q: javax.jdo.Query).setGrouping("...")' - - patterns: - - pattern: '($Q: javax.jdo.Query).setGrouping(<...$ARG...>)' - - pattern-not: '($Q: javax.jdo.Query).setGrouping("...")' - - patterns: - - pattern: '($H: org.hibernate.criterion.Restrictions).sqlRestriction(<...$ARG...>, ...)' - - pattern-not: '($H: org.hibernate.criterion.Restrictions).sqlRestriction("...", ...)' - - patterns: - - pattern: '($S: org.hibernate.Session).createQuery(<...$ARG...>, ...)' - - pattern-not: '($S: org.hibernate.Session).createQuery("...", ...)' - - patterns: - - pattern: '($S: org.hibernate.Session).createSQLQuery(<...$ARG...>, ...)' - - pattern-not: '($S: org.hibernate.Session).createSQLQuery("...", ...)' - - patterns: - - pattern: '($S: java.sql.Statement).executeQuery(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.Statement).createSQLQuery("...", ...)' - - patterns: - - pattern: '($S: java.sql.Statement).execute(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.Statement).execute("...", ...)' - - patterns: - - pattern: '($S: java.sql.Statement).executeUpdate(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.Statement).executeUpdate("...", ...)' - - patterns: - - pattern: '($S: java.sql.Statement).executeLargeUpdate(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.Statement).executeLargeUpdate("...", ...)' - - patterns: - - pattern: '($S: java.sql.Statement).addBatch(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.Statement).addBatch("...", ...)' - - patterns: - - pattern: '($S: java.sql.PreparedStatement).executeQuery(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.PreparedStatement).executeQuery("...", ...)' - - patterns: - - pattern: '($S: java.sql.PreparedStatement).execute(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.PreparedStatement).execute("...", ...)' - - patterns: - - pattern: '($S: java.sql.PreparedStatement).executeUpdate(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.PreparedStatement).executeUpdate("...", ...)' - - patterns: - - pattern: '($S: java.sql.PreparedStatement).executeLargeUpdate(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.PreparedStatement).executeLargeUpdate("...", ...)' - - patterns: - - pattern: '($S: java.sql.PreparedStatement).addBatch(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.PreparedStatement).addBatch("...", ...)' - - patterns: - - pattern: '($S: java.sql.Connection).prepareCall(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.Connection).prepareCall("...", ...)' - - patterns: - - pattern: '($S: java.sql.Connection).prepareStatement(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.Connection).prepareStatement("...", ...)' - - patterns: - - pattern: '($S: java.sql.Connection).nativeSQL(<...$ARG...>, ...)' - - pattern-not: '($S: java.sql.Connection).nativeSQL("...", ...)' - - patterns: - - pattern: new org.springframework.jdbc.core.PreparedStatementCreatorFactory(<...$ARG...>, ...) - - pattern-not: new org.springframework.jdbc.core.PreparedStatementCreatorFactory("...", ...) - - patterns: - - pattern: (org.springframework.jdbc.core.PreparedStatementCreatorFactory $F).newPreparedStatementCreator(<...$ARG...>, ...) - - pattern-not: (org.springframework.jdbc.core.PreparedStatementCreatorFactory $F).newPreparedStatementCreator("...", ...) - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).batchUpdate(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).batchUpdate("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).execute(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).execute("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).query(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).query("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForList(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForList("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForMap(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForMap("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForObject("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForRowSet(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForRowSet("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForInt(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForInt("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).queryForLong(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).queryForLong("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcOperations).update(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcOperations).update("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).batchUpdate(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).batchUpdate("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).execute(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).execute("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).query(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).query("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForList(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForList("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForMap(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForMap("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForObject(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForObject("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForRowSet(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForRowSet("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForInt(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForInt("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForLong(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).queryForLong("...", ...)' - - patterns: - - pattern: '($O: org.springframework.jdbc.core.JdbcTemplate).update(<...$ARG...>, ...)' - - pattern-not: '($O: org.springframework.jdbc.core.JdbcTemplate).update("...", ...)' - - patterns: - - pattern: '($O: io.vertx.sqlclient.SqlClient).query(<...$ARG...>, ...)' - - pattern-not: '($O: io.vertx.sqlclient.SqlClient).query("...", ...)' - - patterns: - - pattern: '($O: io.vertx.sqlclient.SqlClient).preparedQuery(<...$ARG...>, ...)' - - pattern-not: '($O: io.vertx.sqlclient.SqlClient).preparedQuery("...", ...)' - - patterns: - - pattern: '($O: io.vertx.sqlclient.SqlConnection).prepare(<...$ARG...>, ...)' - - pattern-not: '($O: io.vertx.sqlclient.SqlConnection).prepare("...", ...)' - - patterns: - - pattern: '($O: org.apache.turbine.om.peer.BasePeer).executeQuery(<...$ARG...>, ...)' - - pattern-not: '($O: org.apache.turbine.om.peer.BasePeer).executeQuery("...", ...)' - - patterns: - - pattern: '($O: org.apache.torque.util.BasePeer).executeQuery(<...$ARG...>, ...)' - - pattern-not: '($O: org.apache.torque.util.BasePeer).executeQuery("...", ...)' - - patterns: - - pattern: '($O: javax.persistence.EntityManager).createQuery(<...$ARG...>, ...)' - - pattern-not: '($O: javax.persistence.EntityManager).createQuery("...", ...)' - - patterns: - - pattern: '($O: javax.persistence.EntityManager).createNativeQuery(<...$ARG...>, ...)' - - pattern-not: '($O: javax.persistence.EntityManager).createNativeQuery("...", ...)' + - pattern-inside: | + $INPUT = ($REQ: HttpServletRequest).getParameter(...) + ... + - pattern-inside: | + $FORMAT_STR = ... + $INPUT + ... - patterns: - - pattern: anorm.SQL(<...$ARG...>) - - pattern-not: anorm.SQL("...") + - pattern-inside: | + $INPUT = ($REQ: HttpServletRequest).getParameter(...) + ... + - pattern-inside: | + $FORMAT_STR = ... + $INPUT + ... + ... + - pattern-inside: | + $FORMAT_STR = ... + ($REQ: HttpServletRequest).getParameter(...) + ... + ... + - pattern-inside: | + $FORMAT_STR = ... + ($REQ: HttpServletRequest).getParameter(...) + ... + - pattern-either: + - pattern: String.format($FORMAT_STR, ...) + - pattern: String.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) - patterns: - pattern-inside: | - import anorm._ + $F = java.util.Formatter(...) ... - - pattern: SQL(<...$ARG...>) - - pattern-not: SQL("...") + - pattern-either: + - pattern: $F.format($FORMAT_STR, ...) + - pattern: $F.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) + - pattern: '($F: java.io.PrintStream).printf($FORMAT_STR, ...)' + - pattern: '($F: java.io.PrintStream).printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...)' + - pattern: '($F: java.io.PrintStream).format($FORMAT_STR, ...)' + - pattern: '($F: java.io.PrintStream).format(java.util.Locale.$LOCALE, $FORMAT_STR, ...)' + - pattern: System.out.printf($FORMAT_STR, ...) + - pattern: System.out.printf(java.util.Locale.$LOCALE, $FORMAT_STR, ...) + - pattern: System.out.format($FORMAT_STR, ...) + - pattern: System.out.format(java.util.Locale.$LOCALE, $FORMAT_STR, ...) severity: ERROR - - id: scala_ldap_rule-AnonymousLDAP + - id: kotlin_strings_rule-ModifyAfterValidation languages: - - scala + - kotlin message: | - Without proper access control, executing an LDAP statement that contains a - user-controlled value can allow an attacker to abuse poorly configured LDAP - context + CERT: IDS11-J. Perform any string modifications before validation metadata: category: security - cwe: CWE-358 - security-severity: Info - shortDescription: Improperly implemented security check for standard + confidence: HIGH + cwe: CWE-182 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: Collapse of data into unsafe value patterns: - pattern-inside: | - import javax.naming.Context; + $PATTERN = Pattern.compile(...) + ... + - pattern-inside: | + $PATTERN.matcher($VAR) ... - - pattern: $ENV.put(Context.SECURITY_AUTHENTICATION, "none"); + - pattern-either: + - pattern: | + $VAR + $OTHER + - patterns: + - pattern: | + $VAR.$METHOD(...) + - metavariable-regex: + metavariable: $METHOD + regex: (replace|replaceAll|replaceFirst|concat) severity: WARNING - - id: scala_ldap_rule-EntryPoisoning - languages: - - scala - message: | - Without proper access control, executing an LDAP statement that contains a - user-controlled value can allow an attacker to abuse poorly configured LDAP - context - metadata: - category: security - cwe: CWE-358 - security-severity: High - shortDescription: Improperly implemented security check for standard - patterns: - - pattern: new javax.naming.directory.SearchControls($SCOPE, $CLIMIT, $TLIMIT, $ATTR, true, $DEREF) - severity: ERROR - - id: scala_password_rule-ConstantDBPassword - languages: - - scala - message: | - A potential hard-coded password was identified in a database connection string. - Passwords should not be stored directly in code - but loaded from secure locations such as a Key Management System (KMS). - - The purpose of using a Key Management System is so access can be audited and keys easily - rotated - in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine - when or if, a key is compromised. - - The recommendation on which KMS to use depends on the environment the application is running - in: - - - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - - For on premise or other alternatives to cloud providers, consider [Hashicorp's - Vault](https://www.vaultproject.io/) - - For other cloud providers, please see their documentation - metadata: - category: security - cwe: CWE-259 - security-severity: Critical - shortDescription: Use of Hard-coded Password - technology: - - scala - patterns: - - pattern: java.sql.DriverManager.getConnection($URI, $USR, "..."); - severity: ERROR - - id: scala_password_rule-EmptyDBPassword + - id: kotlin_strings_rule-NormalizeAfterValidation languages: - - scala + - kotlin message: | - The application does not provide authentication when communicating a database - server. It is strongly recommended that the database server be configured with - authentication and restrict what queries users can execute. - - Please see your database server's documentation on how to configure a password. - - Additionally, passwords should not be stored directly in code - but loaded from secure locations such as a Key Management System (KMS). - - The purpose of using a Key Management System is so access can be audited and keys easily - rotated - in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine - when or if, a key is compromised. - - The recommendation on which KMS to use depends on the environment the application is running - in: - - - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - - For on premise or other alternatives to cloud providers, consider [Hashicorp's - Vault](https://www.vaultproject.io/) - - For other cloud providers, please see their documentation + IDS01-J. Normalize strings before validating them metadata: category: security - cwe: CWE-259 - security-severity: Critical - shortDescription: Use of Hard-coded Password - technology: - - scala + confidence: HIGH + cwe: CWE-180 + owasp: + - A1:2017-Injection + - A03:2021-Injection + security-severity: MEDIUM + shortDescription: 'Incorrect behavior order: validate before canonicalize' patterns: - - pattern: java.sql.DriverManager.getConnection($URI, $USR, ""); - severity: ERROR - - id: scala_password_rule-HardcodePassword - languages: - - scala - message: | - A potential hard-coded password was identified in the source code. - Passwords should not be stored directly in code - but loaded from secure locations such as a Key Management System (KMS). - - The purpose of using a Key Management System is so access can be audited and keys easily - rotated - in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine - when or if, a key is compromised. - - The recommendation on which KMS to use depends on the environment the application is running - in: - - - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - - For on premise or other alternatives to cloud providers, consider [Hashicorp's - Vault](https://www.vaultproject.io/) - - For other cloud providers, please see their documentation - metadata: - category: security - cwe: CWE-259 - security-severity: High - shortDescription: Use of Hard-coded Password - technology: - - scala - pattern-either: - - pattern: java.security.KeyStore.PasswordProtection("...".toCharArray()) - - pattern: java.security.KeyStore.getInstance(...).load(..., "...".toCharArray()) - - pattern: '($KS: java.security.KeyStore).load(..., "...".toCharArray())' - - pattern: KeyManagerFactory.getInstance(...).init(..., "...".toCharArray()) - - pattern: '($KMF: KeyManagerFactory).init(..., "...".toCharArray())' - - pattern: PBEKeySpec("...", ...) - - pattern: PasswordAuthentication("...", "...") - - pattern: '($CB: PasswordCallback).setPassword("...")' - - pattern: KerberosKey(...,"...",...) - - pattern: java.sql.DriverManager.getConnection(..., "...") - - pattern: io.vertx.ext.web.handler.CSRFHandler.create(..., "...") - - pattern: $S.setPassword("...") - severity: ERROR + - pattern: | + $Y = java.util.regex.Pattern.compile("[<>]"); + ... + $Y.matcher($VAR); + ... + java.text.Normalizer.normalize($VAR, ...); + severity: WARNING - id: scala_perm_rule-DangerousPermissions languages: - scala @@ -102875,215 +34172,6 @@ rules: metavariable: $P regex: (PosixFilePermission.){0,1}(OTHERS_) severity: WARNING - - id: scala_script_rule-ScriptInjection - languages: - - scala - message: | - The software constructs all or part of a code segment using externally-influenced - input from an upstream component, but it does not neutralize or incorrectly - neutralizes special elements that could modify the syntax or behavior of the - intended code segment. - metadata: - category: security - cwe: CWE-94 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Info - shortDescription: Improper Control of Generation of Code ('Code Injection') - patterns: - - pattern: '($ENGINE: javax.script.ScriptEngine).eval($ARG)' - - pattern-not: '($ENGINE: javax.script.ScriptEngine).eval("...")' - severity: ERROR - - id: scala_script_rule-SpelView - languages: - - scala - message: | - The software constructs all or part of a code segment using externally-influenced - input from an upstream component, but it does not neutralize or incorrectly - neutralizes special elements that could modify the syntax or behavior of the - intended code segment. - metadata: - category: security - cwe: CWE-94 - owasp: - - A1:2017-Injection - - A03:2021-Injection - security-severity: Medium - shortDescription: Improper Control of Generation of Code ('Code Injection') - patterns: - - pattern: '($P: org.springframework.expression.spel.standard.SpelExpressionParser).parseExpression($ARG);' - - pattern-not: '($P: org.springframework.expression.spel.standard.SpelExpressionParser ).parseExpression("...");' - severity: ERROR - - id: scala_smtp_rule-InsecureSmtp - languages: - - scala - message: | - Server identity verification is disabled when making SSL connections. - metadata: - category: security - cwe: CWE-297 - owasp: - - A2:2017-Broken Authentication - - A07:2021-Identification and Authentication Failures - security-severity: High - shortDescription: Improper Validation of Certificate with Host Mismatch - patterns: - - pattern-either: - - pattern-inside: | - $E = new org.apache.commons.mail.SimpleEmail(...); - ... - - pattern-inside: | - $E = new org.apache.commons.mail.Email(...); - ... - - pattern-inside: | - $E = new org.apache.commons.mail.MultiPartEmail(...); - ... - - pattern-inside: | - $E = new org.apache.commons.mail.HtmlEmail(...); - ... - - pattern-inside: | - $E = new org.apache.commons.mail.ImageHtmlEmail(...); - ... - - pattern-not: | - $E.setSSLOnConnect(true); - ... - $E.setSSLCheckServerIdentity(true); - severity: ERROR - - id: scala_smtp_rule-SmtpClient - languages: - - scala - message: | - Simple Mail Transfer Protocol (SMTP) is a the text based protocol used for - email delivery. Like with HTTP, headers are separate by new line separator. If - kuser input is place in a header line, the application should remove or replace - new line characters (CR / LF). You should use a safe wrapper such as Apache - Common Email and Simple Java Mail which filter special characters that can lead - to header injection. - metadata: - category: security - cwe: CWE-77 - security-severity: High - shortDescription: Improper Neutralization of Special Elements used in a Command - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $M = new MimeMessage(...); - ... - - pattern: $M.setSubject($ARG); - - pattern-not: $M.setSubject("...") - - patterns: - - pattern-inside: | - $M = new MimeMessage(...); - ... - - pattern: $M.addHeader($ARG1, $ARG2) - - pattern-not: $M.addHeader("...", "...") - - patterns: - - pattern-inside: | - $M = new MimeMessage(...); - ... - - pattern: $M.setDescription($ARG) - - pattern-not: $M.setDescription("...") - - patterns: - - pattern-inside: | - $M = new MimeMessage(...); - ... - - pattern: $M.setDisposition($ARG) - - pattern-not: $M.setDisposition("...") - severity: ERROR - - id: scala_ssrf_rule-PlaySSRF - languages: - - scala - message: | - Server-Side Request Forgery occur when a web server executes a request to a user supplied - destination parameter that is not validated. Such vulnerabilities could allow an attacker to - access internal services or to launch attacks from your web server. - metadata: - category: security - cwe: CWE-918 - security-severity: Medium - shortDescription: Server-Side Request Forgery (SSRF) - patterns: - - pattern-not-inside: | - object $CLAZZ { - ... - $ARG = ... - ... - } - - pattern-not-inside: | - class $CLAZZ { - ... - $ARG = ... - ... - } - - pattern-either: - - patterns: - - pattern-inside: | - import play.api.libs.ws._ - ... - - pattern-not: ($W:WSClient).url("...") - - pattern-not: ($W:WSClient).url("..." + "...") - - pattern: ($W:WSClient).url(<...$ARG...>) - - patterns: - - pattern: ($W:play.api.libs.ws.WSClient).url(<...$ARG...>) - - pattern-not: ($W:play.api.libs.ws.WSClient).url("...") - - pattern-not: ($W:play.api.libs.ws.WSClient).url("..." + "...") - severity: ERROR - - id: scala_ssrf_rule-SSRF - languages: - - scala - message: | - Server-Side Request Forgery occur when a web server executes a request to a user supplied - destination parameter that is not validated. Such vulnerabilities could allow an attacker to - access internal services or to launch attacks from your web server. - metadata: - category: security - cwe: CWE-918 - security-severity: Low - shortDescription: Server-Side Request Forgery (SSRF) - pattern-either: - - patterns: - - pattern-either: - - pattern-inside: | - import java.net._ - ... - - pattern-inside: | - import java.net.URL - ... - - pattern-inside: | - import java.net.URI - ... - - pattern: new $TYPE(...). ... .$FUNC - - pattern-not: new $TYPE("..."). ... .$FUNC - - metavariable-pattern: - metavariable: $FUNC - pattern-either: - - pattern: connect - - pattern: GetContent - - pattern: openConnection - - pattern: openStream - - pattern: getContent - - metavariable-pattern: - metavariable: $TYPE - pattern-either: - - pattern: URL - - pattern: java.net.URL - - pattern: URI - - pattern: java.net.URI - - patterns: - - pattern-either: - - pattern-inside: | - import java.net.*; - ... - - pattern-inside: | - import java.net.InetSocketAddress; - ... - - pattern: | - new InetSocketAddress(..., $PORT) - - pattern-not: | - new InetSocketAddress("...", $PORT) - severity: ERROR - id: scala_strings_rule-BadHexConversion languages: - scala @@ -103229,514 +34317,6 @@ rules: ... java.text.Normalizer.normalize($VAR, ...); severity: WARNING - - id: scala_templateinjection_rule-TemplateInjection - languages: - - scala - message: | - A malicious user in control of a template can run malicious code on the - server-side. Velocity templates should be seen as scripts. - metadata: - category: security - cwe: CWE-94 - security-severity: Info - shortDescription: Improper Control of Generation of Code ('Code Injection') - pattern-either: - - patterns: - - pattern: org.apache.velocity.app.Velocity.evaluate(..., $VAR) - - pattern-not: org.apache.velocity.app.Velocity.evaluate(..., "...") - - patterns: - - pattern-not-inside: | - $C = ($CFG: freemarker.template.Configuration).getTemplate("..."); - ... - - pattern-inside: | - $C = ($CFG: freemarker.template.Configuration).getTemplate($IN); - ... - - pattern: $C.process(...) - - patterns: - - pattern-inside: | - import com.mitchellbosecke.pebble.PebbleEngine; - ... - - pattern-inside: | - $C = $T.getTemplate($IN); - ... - - pattern-not-inside: | - $C = $T.getTemplate("..."); - ... - - pattern: $C.evaluate(...) - severity: ERROR - - id: scala_unsafe_rule-ExternalConfigControl - languages: - - scala - message: | - Allowing external control of system settings can disrupt service or cause an application to - behave in unexpected, and potentially malicious ways. An attacker could cause an error by - providing a nonexistent catalog name or connect to an unauthorized portion of the database. - metadata: - category: security - cwe: CWE-15 - security-severity: High - shortDescription: External Control of System or Configuration Setting - technology: - - scala - patterns: - - pattern: | - $TAINTED = ($REQ: HttpServletRequest).getParameter(...); - ... - ($CONN: java.sql.Connection).setCatalog($TAINTED); - severity: WARNING - - id: scala_unsafe_rule-InformationExposure - languages: - - scala - message: | - The sensitive information may be valuable information on its own (such as a password), or it - may be useful for launching other, more deadly attacks. If an attack fails, an attacker may use - error information provided by the server to launch another more focused attack. For example, an - attempt to exploit a path traversal weakness (CWE-22) might yield the full pathname of the - installed application. - metadata: - category: security - cwe: CWE-209 - security-severity: Low - shortDescription: Information Exposure Through an Error Message - technology: - - scala - patterns: - - pattern: $E.printStackTrace(...) - severity: WARNING - - id: scala_unsafe_rule-SensitiveDataExposure - languages: - - scala - message: | - Applications can unintentionally leak information about their configuration, internal - workings, or violate privacy through a variety of application problems. Pages that provide - different responses based on the validity of the data can lead to Information Leakage; - specifically when data deemed confidential is being revealed as a result of the web - application's design. - metadata: - category: security - cwe: CWE-497 - security-severity: Info - shortDescription: Exposure of sensitive system information to an unauthorized control sphere - technology: - - scala - - play - patterns: - - pattern-inside: | - def $FUNC(..., $ARG: String, ...) = $TYPE { - ... - } - - pattern-inside: | - $VAL = ($C: play.api.Configuration).underlying.getString($ARG) - ... - - pattern: Ok(<...$VAL...>) - severity: WARNING - - id: scala_xml_rule-ApacheXmlRpc - languages: - - scala - message: | - Enabling extensions in Apache XML RPC server or client can lead to deserialization - vulnerability which would allow an attacker to execute arbitrary code. - metadata: - category: security - cwe: CWE-502 - security-severity: Info - shortDescription: Deserialization of Untrusted Data - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - val $VAR = new XmlRpcServerConfigImpl(); - ... - - pattern: $VAR.setEnabledForExtensions(true); - - patterns: - - pattern-inside: | - val $VAR = new org.apache.xmlrpc.client.XmlRpcClientConfigImpl(); - ... - - pattern: $VAR.setEnabledForExtensions(true); - severity: WARNING - - id: scala_xml_rule-SAMLIgnoreComments - languages: - - scala - message: | - Ignoring XML comments in SAML may lead to authentication bypass - metadata: - category: security - cwe: CWE-1390 - security-severity: Medium - shortDescription: Weak authentication - pattern: '($POOL: BasicParserPool).setIgnoreComments(false);' - severity: WARNING - - id: scala_xml_rule-XmlDecoder - languages: - - scala - message: | - Avoid using XMLDecoder to parse content from an untrusted source. - metadata: - category: security - cwe: CWE-502 - security-severity: High - shortDescription: Deserialization of Untrusted Data - patterns: - - pattern-inside: | - $D = new java.beans.XMLDecoder($IN); - ... - - pattern-not-inside: | - $DX = new java.beans.XMLDecoder("..."); - ... - - pattern: $D.readObject - severity: WARNING - - id: scala_xml_rule-XsltTransform - languages: - - java - message: | - It is possible to attach malicious behavior to those style sheets. Therefore, if an attacker - can control the content or the source of the style sheet, he might be able to trigger remote - code execution. - metadata: - category: security - cwe: CWE-91 - security-severity: Medium - shortDescription: XML injection (aka Blind XPath injection) - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: (javax.xml.transform.TransformerFactory $T).newTransformer($SRC, ...) - - pattern-inside: (javax.xml.transform.Transformer $T).transform($SRC, ...) - - pattern: $SRC - pattern-sources: - - patterns: - - pattern-either: - - patterns: - - pattern-inside: | - $FUNC(...,String $VAR, ...) { - ... - } - - pattern-either: - - pattern: new FileInputStream(<... $VAR ...>); - - pattern: getClass.getResourceAsStream(<... $VAR ...>) - - patterns: - - pattern-inside: | - class $CLZ { - String $X = "..."; - ... - } - - pattern-inside: | - $FUNC(...,String $Y, ...) { - ... - } - - pattern-either: - - pattern: new FileInputStream($X + $Y); - - pattern: getClass.getResourceAsStream($X + $Y) - severity: WARNING - - id: scala_xpathi_rule-XpathInjection - languages: - - scala - message: | - The input values included in SQL queries need to be passed in safely. Bind - variables in prepared statements can be used to easily mitigate the risk of - SQL injection. - metadata: - category: security - cwe: CWE-611 - security-severity: Medium - shortDescription: Improper Restriction of XML External Entity Reference ('XXE') - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - pattern-inside: |- - import javax.xml.xpath._ - ... - - pattern-inside: |- - import javax.xml.xpath.XPath - ... - - pattern-either: - - pattern: $Y.compile(...) - - pattern: $X.evaluate(..., $ARG2) - pattern-sources: - - patterns: - - pattern-inside: | - def $FUNC(..., $ARG: $TYPE,...): $RET = { - ... - } - - pattern: $ARG - severity: ERROR - - id: scala_xss_rule-MVCApi - languages: - - scala - message: | - Disabling HTML escaping put the application at risk for Cross-Site Scripting (XSS). - metadata: - category: security - cwe: CWE-79 - security-severity: Info - shortDescription: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') - mode: taint - pattern-sanitizers: - - pattern: org.owasp.encoder.Encode.forHtml(...) - pattern-sinks: - - pattern: Ok(...) - pattern-sources: - - patterns: - - pattern-inside: | - def $FUNC(..., $ARG: String, ...) = Action { - ... - } - - focus-metavariable: $ARG - severity: WARNING - - id: scala_xss_rule-RequestWrapper - languages: - - scala - message: | - Avoid using custom XSS filtering. Please use standard sanitization functions. - metadata: - category: security - cwe: CWE-79 - security-severity: Medium - shortDescription: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') - patterns: - - pattern-inside: | - class $CLASS(...) extends HttpServletRequestWrapper(...) { - ... - } - - pattern: def stripXSS(...) = { ... } - severity: INFO - - id: scala_xss_rule-WicketXSS - languages: - - scala - message: | - Disabling HTML escaping put the application at risk for Cross-Site Scripting (XSS). - metadata: - category: security - cwe: CWE-79 - security-severity: Medium - shortDescription: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') - patterns: - - pattern: '($X: Label).setEscapeModelStrings(false);' - severity: WARNING - - id: scala_xss_rule-XSSReqParamToServletWriter - languages: - - scala - message: | - Servlet reflected cross site scripting vulnerability - metadata: - category: security - cwe: CWE-79 - security-severity: Medium - shortDescription: Improper Neutralization of Input During Web Page Generation - technology: - - scala - mode: taint - pattern-sanitizers: - - pattern: Encode.forHtml(...) - - pattern: org.owasp.esapi.Encoder.encodeForSQL(...) - pattern-sinks: - - patterns: - - pattern-inside: 'def $FUNC(..., $RES: HttpServletResponse, ...): $TYPE = {...}' - - pattern-inside: | - $WRITER = $RES.getWriter - ... - - pattern: $WRITER.write(...) - - patterns: - - pattern-inside: 'def $FUNC(..., $RES: HttpServletResponse, ...): $TYPE = {...}' - - pattern: $RES.getWriter.write(...) - - patterns: - - pattern-inside: 'def $FUNC(..., $RES: HttpServletResponse, ...): $TYPE = {...}' - - pattern: $RES.getWriter.print(...) - pattern-sources: - - patterns: - - pattern-inside: 'def $FUNC(..., $REQ: HttpServletRequest, ...): $TYPE = {...}' - - pattern-either: - - pattern: $REQ.getParameter(...) - - pattern: $REQ.getQueryString - severity: WARNING - - id: scala_xss_rule-XSSServlet - languages: - - scala - message: | - A potential XSS was found. It could be used to execute unwanted JavaScript in a - client's browser. - metadata: - category: security - cwe: CWE-79 - security-severity: Info - shortDescription: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') - mode: taint - pattern-sanitizers: - - patterns: - - pattern-inside: org.owasp.encoder.Encode.forHtml($TAINTED); - - pattern: $TAINTED - pattern-sinks: - - patterns: - - pattern-inside: 'def $FUNC(..., $RES: HttpServletResponse, ...): $TYPE = {...}' - - pattern-inside: | - $WRITER = $RES.getWriter; - ... - - pattern: $WRITER.write($DATA,...); - - pattern: $DATA - - patterns: - - pattern-inside: 'def $FUNC(..., $RES: HttpServletResponse, ...): $TYPE = {...}' - - pattern: $RES.getWriter.write($DATA,...); - - pattern: $DATA - pattern-sources: - - patterns: - - pattern-inside: 'def $FUNC(..., $REQ: HttpServletRequest, ...): $TYPE = {...}' - - pattern: $REQ.getParameter(...); - severity: WARNING - - id: scala_xxe_rule-Document - languages: - - scala - message: | - XML External Entity (XXE) attacks can occur when an XML parser supports XML - entities while processing XML received from an untrusted source. - metadata: - category: security - cwe: CWE-611 - security-severity: Medium - shortDescription: Improper Restriction of XML External Entity Reference ('XXE') - patterns: - - pattern-inside: | - $DF = DocumentBuilderFactory.newInstance - ... - - pattern-not-inside: | - $DF.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - - pattern-not-inside: | - $DF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) - ... - - pattern: $DB.parse(...) - severity: ERROR - - id: scala_xxe_rule-SaxParserXXE - languages: - - scala - message: | - XML External Entity (XXE) attacks can occur when an XML parser supports XML - entities while processing XML received from an untrusted source. - metadata: - category: security - cwe: CWE-611 - security-severity: Info - shortDescription: Improper Restriction of XML External Entity Reference ('XXE') - patterns: - - pattern-inside: | - val $SF = SAXParserFactory.newInstance - ... - - pattern-not-inside: | - $SF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) - ... - - pattern-not-inside: | - $SF.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - - pattern-inside: | - val $P = $SFP.newSAXParser - ... - - pattern: $P.parse(...); - severity: ERROR - - id: scala_xxe_rule-Trans - languages: - - scala - message: | - XML External Entity (XXE) attacks can occur when an XML parser supports XML - entities while processing XML received from an untrusted source. - metadata: - category: security - cwe: CWE-611 - security-severity: Medium - shortDescription: Improper Restriction of XML External Entity Reference ('XXE') - mode: taint - pattern-sanitizers: - - pattern: $T.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - - pattern: $T.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - - pattern: $T.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - pattern-sinks: - - pattern: $T.transform(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: |- - import javax.xml.transform._ - ... - - pattern-inside: |- - import javax.xml.transform.Transformer - ... - - pattern: $FACT.newTransformer - severity: ERROR - - id: scala_xxe_rule-XMLRdr - languages: - - scala - message: | - XML External Entity (XXE) attacks can occur when an XML parser supports XML - entities while processing XML received from an untrusted source. - metadata: - category: security - cwe: CWE-611 - security-severity: Medium - shortDescription: Improper Restriction of XML External Entity Reference ('XXE') - patterns: - - pattern-inside: | - val $R = XMLReaderFactory.createXMLReader - ... - - pattern-not-inside: | - $R.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) - ... - - pattern: $R.parse(...) - severity: ERROR - - id: scala_xxe_rule-XMLStreamRdr - languages: - - scala - message: | - XML External Entity (XXE) attacks can occur when an XML parser supports XML - entities while processing XML received from an untrusted source. - metadata: - category: security - cwe: CWE-611 - security-severity: Medium - shortDescription: Improper Restriction of XML External Entity Reference ('XXE') - patterns: - - pattern-inside: | - $SF = XMLInputFactory.newFactory - ... - - pattern-not-inside: | - $SF.setProperty(XMLInputFactory.SUPPORT_DTD, false) - ... - - pattern-not-inside: | - $SF.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false) - ... - - pattern: $SF.createXMLStreamReader(...) - severity: ERROR - - id: scala_xxe_rule-XPathXXE - languages: - - scala - message: | - XML External Entity (XXE) attacks can occur when an XML parser supports XML - entities while processing XML received from an untrusted source. - metadata: - category: security - cwe: CWE-611 - security-severity: Medium - shortDescription: Improper Restriction of XML External Entity Reference ('XXE') - patterns: - - pattern-inside: | - val $DF = DocumentBuilderFactory.newInstance - ... - - pattern-not-inside: | - $DF.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "") - ... - - pattern-not-inside: | - $DF.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "") - ... - - pattern-not-inside: | - $DF.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) - ... - - pattern-not-inside: | - $DF.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - ... - - pattern-inside: | - $B = $DF.newDocumentBuilder - ... - - pattern: $XPATH.evaluate(...) - severity: ERROR - id: codacy.java.security.hard-coded-password languages: - java @@ -103806,6 +34386,17 @@ rules: metavariable: $PASSWORD regex: (?i).*(password|motdepasse|heslo|adgangskode|wachtwoord|salasana|passwort|passord|senha|geslo|clave|losenord|clave|parola|secret|pwd).* severity: ERROR + - id: codacy.generic.plsql.empty-strings + languages: + - generic + message: Empty strings can lead to unexpected behavior and should be handled carefully. + metadata: + category: security + confidence: MEDIUM + description: Detects empty strings in the code which might cause issues or bugs. + impact: MEDIUM + pattern: $VAR VARCHAR2($LENGTH) := ''; + severity: WARNING - id: codacy.generic.plsql.find-all-passwords languages: - generic @@ -103820,8 +34411,12 @@ rules: - A3:2017 Sensitive Data Exposure options: generic_ellipsis_max_span: 0 - pattern: | - $PASSWORD VARCHAR2($LENGTH) := $...VALUE; + patterns: + - pattern: | + $PASSWORD VARCHAR2($LENGTH) := $...VALUE; + - metavariable-regex: + metavariable: $PASSWORD + regex: (?i).*(password|motdepasse|heslo|adgangskode|wachtwoord|salasana|passwort|passord|senha|geslo|clave|losenord|clave|parola|secret|pwd).* severity: ERROR - id: codacy.generic.plsql.resource-injection languages: @@ -103861,104 +34456,6 @@ rules: - pattern: | $RESOURCE := WPG_DOCLOAD.DOWNLOAD_FILE($...ARGS); severity: ERROR - - id: codacy.generic.sql.grant-all - languages: - - generic - message: | - GRANT ALL privileges should not be used as it gives excessive permissions that violate the principle of least privilege. Instead, grant only the specific privileges that are required. - metadata: - category: security - confidence: LOW - description: Detects use of GRANT ALL which gives excessive database privileges - impact: HIGH - owasp: - - A5:2017 Broken Access Control - paths: - include: - - '*.sql' - pattern: | - GRANT ALL $X - severity: ERROR - - id: codacy.generic.sql.grant-select-no-role - languages: - - generic - message: | - GRANT SELECT privileges should only be given to role-based accounts (ending in '_role'). Direct grants to users or non-role accounts violate security best practices. - metadata: - category: security - confidence: LOW - description: Detects GRANT SELECT statements that are not targeting role-based accounts - impact: MEDIUM - owasp: - - A5:2017 Broken Access Control - paths: - include: - - '*.sql' - pattern-regex: GRANT\s+(DELETE|INSERT|SELECT|UPDATE)(\s*,\s*(DELETE|INSERT|SELECT|UPDATE))*\s+ON\s+[a-zA-Z0-9_]+(\.[a-zA-Z0-9_*]+)?\s+TO\s+(?![a-zA-Z0-9_]*_role\b)[a-zA-Z0-9_]+ - severity: ERROR - - id: codacy.generic.sql.fnd-profile-in-query - languages: - - generic - message: | - FND_PROFILE functions should not be used directly in SELECT or WHERE clauses. Instead, assign the FND_PROFILE function value to a variable first and then use that variable in the query. This improves performance and maintainability. - metadata: - category: performance - confidence: LOW - description: Detects direct usage of FND_PROFILE functions in SQL queries instead of using variables - impact: MEDIUM - paths: - include: - - '*.sql' - patterns: - - pattern-either: - - pattern-regex: (?i)SELECT\s+.*\bFND_PROFILE\.[a-zA-Z0-9_]+\( - - pattern-regex: (?i)SELECT\s+.*\bFROM\b.*\bWHERE\b.*\bFND_PROFILE\.[a-zA-Z0-9_]+\( - severity: ERROR - - id: codacy.java.security.flexible-search-sql-injection - languages: - - java - message: 'Possible SQL Injection: Avoid concatenating user input in FlexibleSearchQuery.' - metadata: - category: security - confidence: LOW - technology: - - sap-commerce - - hybris - patterns: - - pattern-either: - - pattern: | - new FlexibleSearchQuery("SELECT " + ...) - - pattern: | - new FlexibleSearchQuery("..." + $VAR + "...") - - pattern-not: | - new FlexibleSearchQuery("SELECT ... ?param") - severity: ERROR - - id: codacy.csharp.security.null-dereference - languages: - - csharp - message: | - Potential null dereference detected. The parameter or variable could be null and should be validated before accessing its members. Add a null check before dereferencing the object to prevent NullReferenceException at runtime. - metadata: - category: security - confidence: LOW - technology: - - csharp - - dotnet - patterns: - - pattern-inside: | - $RETURNTYPE $METHOD(...,$TYPE $NULLABLE, ...) { ... } - - pattern-not-inside: | - if ($NULLABLE == null) { ... } - ... - - pattern-either: - - pattern: | - $NULLABLE.$MEMBER - - pattern: | - $FUNCTION_NAME($NULLABLE, ...); - - pattern-not: | - if ($NULLABLE == null) { return ... } - ... - severity: ERROR - id: codacy.generic.security.detect-invisible-unicode languages: - yaml @@ -103979,19 +34476,3 @@ rules: - '*.yml' pattern-regex: "[​‌‍⁠\uFEFF]" severity: WARNING - - id: codacy.generic.csharp-lowercase-variables - languages: - - csharp - message: Variable names should be lowercase - metadata: - category: codestyle - confidence: LOW - description: Variable names should be lowercase - impact: LOW - technology: - - .net - paths: - include: - - '*.cs' - pattern-regex: (?:int|string|long|float|char|double|bool|var)\s([A-Z0-9]) - severity: INFO diff --git a/plugins/tools/semgrep/embedded/rules.yaml b/plugins/tools/semgrep/embedded/rules.yaml index 505a9964..6eaab64e 100644 --- a/plugins/tools/semgrep/embedded/rules.yaml +++ b/plugins/tools/semgrep/embedded/rules.yaml @@ -507,6 +507,7 @@ rules: # unsafe: $* $@ $0 $15 $_ $foo $FOO # unsafe but tolerated: $_foo $_FOO $_42 regex: "[*@0-9]|[A-Za-z].*" + - id: bash.lang.correctness.unquoted-expansion.unquoted-command-substitution-in-command languages: [bash] severity: INFO @@ -64528,7 +64529,7 @@ rules: resource "aws_instance" "..." { ... } - id: aws-provisioner-exec + id: terraform.aws.security.aws-provisioner-exec.aws-provisioner-exec message: Provisioners are a tool of last resort and should be avoided where possible. Provisioner behavior cannot be mapped by Terraform as part of a plan, and execute arbitrary shell commands by design. languages: - terraform @@ -78894,7 +78895,7 @@ rules: - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/ - fix: bash - id: lang-consistency-bash + id: yaml.semgrep.consistency.lang-consistency-bash.lang-consistency-bash languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -78911,7 +78912,7 @@ rules: regex: ^(sh)$ severity: WARNING - fix: cpp - id: lang-consistency-cpp + id: yaml.semgrep.consistency.lang-consistency-cpp.lang-consistency-cpp languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -78928,7 +78929,7 @@ rules: regex: ^(c\+\+)$ severity: WARNING - fix: csharp - id: lang-consistency-csharp + id: yaml.semgrep.consistency.lang-consistency-csharp.lang-consistency-csharp languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -78945,7 +78946,7 @@ rules: regex: ^(c\#)$ severity: WARNING - fix: dockerfile - id: lang-consistency-dockerfile + id: yaml.semgrep.consistency.lang-consistency-dockerfile.lang-consistency-dockerfile languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -78962,7 +78963,7 @@ rules: regex: ^(docker)$ severity: WARNING - fix: elixir - id: lang-consistency-elixir + id: yaml.semgrep.consistency.lang-consistency-elixir.lang-consistency-elixir languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -78979,7 +78980,7 @@ rules: regex: ^(ex)$ severity: WARNING - fix: go - id: lang-consistency-go + id: yaml.semgrep.consistency.lang-consistency-go.lang-consistency-go languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -78996,7 +78997,7 @@ rules: regex: ^(golang)$ severity: WARNING - fix: hcl - id: lang-consistency-hcl + id: yaml.semgrep.consistency.lang-consistency-hcl.lang-consistency-hcl languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -79013,7 +79014,7 @@ rules: regex: ^(tf|terraform)$ severity: WARNING - fix: js - id: lang-consistency-js + id: yaml.semgrep.consistency.lang-consistency-js.lang-consistency-js languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -79030,7 +79031,7 @@ rules: regex: ^(javascript)$ severity: WARNING - fix: kotlin - id: lang-consistency-kotlin + id: yaml.semgrep.consistency.lang-consistency-kotlin.lang-consistency-kotlin languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -79047,7 +79048,7 @@ rules: regex: ^(kt)$ severity: WARNING - fix: python - id: lang-consistency-python + id: yaml.semgrep.consistency.lang-consistency-python.lang-consistency-python languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -79064,7 +79065,7 @@ rules: regex: ^(py)$ severity: WARNING - fix: regex - id: lang-consistency-regex + id: yaml.semgrep.consistency.lang-consistency-regex.lang-consistency-regex languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -79081,7 +79082,7 @@ rules: regex: ^(none)$ severity: WARNING - fix: solidity - id: lang-consistency-solidity + id: yaml.semgrep.consistency.lang-consistency-solidity.lang-consistency-solidity languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -79098,7 +79099,7 @@ rules: regex: ^(sol)$ severity: WARNING - fix: ts - id: lang-consistency-ts + id: yaml.semgrep.consistency.lang-consistency-ts.lang-consistency-ts languages: - yaml message: Found '$X' in language config which diverges from semgrep.dev normalization. @@ -84143,8 +84144,9 @@ rules: - pattern: "os.WriteFile(...,$MASK)" - metavariable-comparison: metavariable: "$MASK" - comparison: "$MASK > 0o640" - base: 8 + comparison: "int($MASK) > 0o640" + # comparison: "$MASK > 0o640" + # base: 8 message: | The application was found setting file permissions to overly permissive values. Consider using the following values if the application user is the only process to access @@ -94913,6 +94915,98 @@ rules: shortDescription: "Missing validation of OpenSSL certificate" security-severity: "MEDIUM" category: "security" +- id: kotlin_pathtraversal_rule-FilePathTraversal + languages: + - kotlin + message: | + The application is found using untrusted user input with file + operations, which can potentially lead to Path Traversal vulnerabilities. + Path traversal (also known as directory traversal) allows attackers to + access files and directories outside of intended boundaries by inserting + special characters or sequences (like ../, ..\\, or URL-encoded variants) + to navigate to arbitrary locations in the filesystem. + The vulnerability can lead to unauthorized access to sensitive files + (configuration files, credentials), code execution (if attackers can write + to or include executable files), information disclosure, or complete system + compromise. + + Where possible, do not send user input to file operation methods. If that + cannot be avoided, follow the below mitigation strategy: + 1. Validate and sanitize all user inputs used in file operations + 2. Use allowlisting approaches to validate file paths where possible + 3. Apply canonicalization before validation to prevent bypass techniques + 4. Restrict operations to a specific designated directory + 5. Use application-specific user accounts with limited privileges + + Secure Code Example: + ``` + fun safeWrite(filename: String, content: String) { + val baseDir = File("/safe-dir/") + val target = File(baseDir, filename).canonicalFile + + // Ensure the target path is within the allowed directory + if (!target.path.startsWith(baseDir.canonicalPath)) { + throw SecurityException("Invalid file path: $filename") + } + + FileWriter(target).use { writer -> + writer.write(content) + } + } + ``` + metadata: + shortDescription: "Improper limitation of a pathname to a restricted directory ('Path Traversal')" + cwe: "CWE-22" + owasp: + - "A5:2017-Broken Access Control" + - "A01:2021-Broken Access Control" + security-severity: "High" + technology: + - "kotlin" + category: "security" + severity: ERROR + mode: taint + pattern-sources: + - patterns: + - patterns: + - pattern-inside: | + import $IMPORT + ... + - metavariable-regex: + metavariable: $IMPORT + regex: .*springframework.* + - focus-metavariable: $VAR + - patterns: + - pattern-either: + - pattern-inside: | + fun $_(..., @$REQ(...) $VAR: $TYPE,...): $_ { + ... + } + - pattern-inside: | + fun $_(..., @$REQ $VAR: $TYPE,...): $_ { + ... + } + - metavariable-regex: + metavariable: $TYPE + regex: ^(?!(Int|Long|Float|Double|Char|Boolean)) + - metavariable-regex: + metavariable: $REQ + regex: (RequestBody|PathVariable|RequestParam|RequestHeader|CookieValue|ModelAttribute|RequestPart) + - pattern: | + ($REQ: javax.servlet.ServletRequest) + - pattern: | + ($REQ: javax.servlet.http.HttpServletRequest) + pattern-sinks: + - pattern: java.io.File(...) + - pattern: java.io.FileInputStream(...) + - pattern: java.io.FileReader(...) + - patterns: + - pattern-either: + - pattern: java.io.FileOutputStream($TAINT, ...) + - pattern: java.io.FileWriter($TAINT, ...) + - pattern: java.io.RandomAccessFile($TAINT, ...) + - focus-metavariable: $TAINT + - pattern: kotlin.io.path.Path(...) - id: python_exec_rule-start-process-partial-path languages: - "python" @@ -100203,7 +100297,7 @@ rules: - "A01:2021-Broken Access Control" cwe: "CWE-22" shortDescription: "Improper limitation of a pathname to a restricted directory - ('Path Traversal')" + ('Path Traversal')" references: - "https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion" - "https://github.com/semgrep/semgrep-rules/blob/develop/ruby/rails/security/brakeman/check-render-local-file-include.yaml" @@ -103349,6 +103443,12 @@ rules: - metavariable-regex: metavariable: "$FUNC" regex: "^(body|params|query|baseUrl|cookies|hostname|subdomains|ip|ips|originalUrl|path)$" + pattern-sanitizers: + - patterns: + - pattern: $OBJ.slice($X, $Y) + - pattern-not: $OBJ.slice($X) + - pattern-not: $OBJ.slice(..., $OBJ.length) + - pattern-not: $OBJ.slice(..., Object.keys($OBJ).length) pattern-sinks: - patterns: - pattern: | @@ -113132,8 +113232,12 @@ rules: severity: ERROR languages: - generic - pattern: | - $PASSWORD VARCHAR2($LENGTH) := $...VALUE; + patterns: + - pattern: | + $PASSWORD VARCHAR2($LENGTH) := $...VALUE; + - metavariable-regex: + metavariable: "$PASSWORD" + regex: "(?i).*(password|motdepasse|heslo|adgangskode|wachtwoord|salasana|passwort|passord|senha|geslo|clave|losenord|clave|parola|secret|pwd).*" options: generic_ellipsis_max_span: 0 message: > @@ -113325,4 +113429,94 @@ rules: - .net impact: LOW confidence: LOW +- id: codacy.generic.sql.hardcoded-language-currency-orgid + severity: ERROR + languages: + - generic + patterns: + - pattern-either: + - pattern-regex: "(?i)\\b\\w*language\\w*\\b\\s*(=|:=)\\s*'?\\b[A-Z]{2}\\b'?" + - pattern-regex: "(?i)\\b\\w*currency\\w*\\b\\s*(=|:=)\\s*'?\\b[A-Z]{3}\\b'?" + - pattern-regex: "(?i)\\b(\\w*\\.)?org_id\\b\\s*(=|:=|IN|!=|<>)\\s*(\\(?\\s*'?\\d+'?(,\\s*'?\\d+'?)*\\s*\\)?)?" + paths: + include: + - "*.sql" + message: > + Hardcoded Language, Currency, or Org_Id values detected in SQL.Avoid hardcoding such values; use parameters or configuration instead. + metadata: + description: > + Detects hardcoded values for fields containing 'language', 'currency', or 'org_id' in SQL queries. These should be parameterized or retrieved from configuration. + category: performance + impact: MEDIUM + confidence: LOW +- id: codacy.generic.sql.lookup-type-without-language-or-apps-fnd + severity: ERROR + languages: + - generic + patterns: + - pattern-either: + - pattern-regex: "(?i)lookup_type(?![^;]{0,200}language\\s*=)" + - pattern-regex: "apps\\.fnd_lookup_values" + paths: + include: + - "*.sql" + message: > + Usage of 'lookup_type' without a language clause or reference to 'apps.fnd_lookup_values' detected.These patterns must be reviewed for localization and security risks. + metadata: + description: > + Flags usage of 'lookup_type' when no 'language = ...' clause is present, and flags any use of 'apps.fnd_lookup_values'. + category: performance + impact: MEDIUM + confidence: LOW +- id: codacy.generic.sql.from-all-without-orgid + severity: ERROR + languages: + - generic + patterns: + - pattern-regex: "(?i)from\\s+[a-z0-9_]*_all[a-z0-9_]*(?![^;]{0,300}\\b[a-z0-9_]*org_id\\b\\s*(=|:=))" + paths: + include: + - "*.sql" + message: > + Detected use of *_ALL* table without an org_id clause.These queries must include an org_id condition to ensure data partitioning. + metadata: + description: > + Flags any SQL query selecting from *_ALL* tables without checking for an org_id condition like org_id = ... or org_id := ... + category: performance + impact: MEDIUM + confidence: LOW +- id: codacy.generic.sql.rac-table-access + severity: ERROR + languages: + - generic + patterns: + - pattern-regex: '(?i)\b(SELECT|INSERT\s+INTO|UPDATE|DELETE\s+FROM)\b(?![^\n;]*\bRAC_\w*\b)[^\n;]*' + paths: + include: + - "*.sql" + message: > + All queries must target RAC_* tables.Query does not reference RAC_* table. + metadata: + description: > + Enforce that all SELECT, INSERT, UPDATE, and DELETE queries must be performed only on RAC_* tables. + category: performance + impact: MEDIUM + confidence: LOW +- id: codacy.generic.sql.rownum + severity: ERROR + languages: + - generic + patterns: + - pattern-regex: (?i)\bROWNUM\b + paths: + include: + - "*.sql" + message: > + The file contains ROWNUM usage which must be reviewed for performance and correctness. + metadata: + description: > + The file contains ROWNUM usage which must be reviewed for performance and correctness. + category: security + impact: MEDIUM + confidence: LOW diff --git a/plugins/tools/trivy/test/expected.sarif b/plugins/tools/trivy/test/expected.sarif index 747aa1d1..70e9384d 100644 --- a/plugins/tools/trivy/test/expected.sarif +++ b/plugins/tools/trivy/test/expected.sarif @@ -10,30 +10,30 @@ }, "results": [ { - "level": "note", + "level": "warning", "locations": [ { "message": { - "text": "package-lock.json: brace-expansion@1.1.11" + "text": "requirements.txt: django@1.11.29" }, "physicalLocation": { "artifactLocation": { - "uri": "package-lock.json", + "uri": "requirements.txt", "uriBaseId": "ROOTPATH" }, "region": { "endColumn": 1, - "endLine": 357, + "endLine": 1, "startColumn": 1, - "startLine": 349 + "startLine": 1 } } } ], "message": { - "text": "Package: brace-expansion\nInstalled Version: 1.1.11\nVulnerability CVE-2025-5889\nSeverity: LOW\nFixed Version: 2.0.2, 1.1.12, 3.0.1, 4.0.1\nLink: [CVE-2025-5889](https://avd.aquasec.com/nvd/cve-2025-5889)" + "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2021-33203\nSeverity: MEDIUM\nFixed Version: 2.2.24, 3.1.12, 3.2.4\nLink: [CVE-2021-33203](https://avd.aquasec.com/nvd/cve-2021-33203)" }, - "ruleId": "CVE-2025-5889", + "ruleId": "CVE-2021-33203", "ruleIndex": 4 }, { @@ -41,54 +41,54 @@ "locations": [ { "message": { - "text": "package-lock.json: cross-spawn@7.0.3" + "text": "requirements.txt: django@1.11.29" }, "physicalLocation": { "artifactLocation": { - "uri": "package-lock.json", + "uri": "requirements.txt", "uriBaseId": "ROOTPATH" }, "region": { "endColumn": 1, - "endLine": 527, + "endLine": 1, "startColumn": 1, - "startLine": 515 + "startLine": 1 } } } ], "message": { - "text": "Package: cross-spawn\nInstalled Version: 7.0.3\nVulnerability CVE-2024-21538\nSeverity: HIGH\nFixed Version: 7.0.5, 6.0.6\nLink: [CVE-2024-21538](https://avd.aquasec.com/nvd/cve-2024-21538)" + "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2022-36359\nSeverity: HIGH\nFixed Version: 3.2.15, 4.0.7\nLink: [CVE-2022-36359](https://avd.aquasec.com/nvd/cve-2022-36359)" }, - "ruleId": "CVE-2024-21538", - "ruleIndex": 1 + "ruleId": "CVE-2022-36359", + "ruleIndex": 2 }, { "level": "error", "locations": [ { "message": { - "text": "requirements.txt: django@1.11.29" + "text": "package-lock.json: cross-spawn@7.0.3" }, "physicalLocation": { "artifactLocation": { - "uri": "requirements.txt", + "uri": "package-lock.json", "uriBaseId": "ROOTPATH" }, "region": { "endColumn": 1, - "endLine": 1, + "endLine": 527, "startColumn": 1, - "startLine": 1 + "startLine": 515 } } } ], "message": { - "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2022-36359\nSeverity: HIGH\nFixed Version: 3.2.15, 4.0.7\nLink: [CVE-2022-36359](https://avd.aquasec.com/nvd/cve-2022-36359)" + "text": "Package: cross-spawn\nInstalled Version: 7.0.3\nVulnerability CVE-2024-21538\nSeverity: HIGH\nFixed Version: 7.0.5, 6.0.6\nLink: [CVE-2024-21538](https://avd.aquasec.com/nvd/cve-2024-21538)" }, - "ruleId": "CVE-2022-36359", - "ruleIndex": 2 + "ruleId": "CVE-2024-21538", + "ruleIndex": 1 }, { "level": "warning", @@ -112,9 +112,9 @@ } ], "message": { - "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2021-33203\nSeverity: MEDIUM\nFixed Version: 2.2.24, 3.1.12, 3.2.4\nLink: [CVE-2021-33203](https://avd.aquasec.com/nvd/cve-2021-33203)" + "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2024-45231\nSeverity: MEDIUM\nFixed Version: 5.1.1, 5.0.9, 4.2.16\nLink: [CVE-2024-45231](https://avd.aquasec.com/nvd/cve-2024-45231)" }, - "ruleId": "CVE-2021-33203", + "ruleId": "CVE-2024-45231", "ruleIndex": 5 }, { @@ -139,9 +139,9 @@ } ], "message": { - "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2024-45231\nSeverity: MEDIUM\nFixed Version: 5.1.1, 5.0.9, 4.2.16\nLink: [CVE-2024-45231](https://avd.aquasec.com/nvd/cve-2024-45231)" + "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2025-48432\nSeverity: MEDIUM\nFixed Version: 5.2.2, 5.1.10, 4.2.22\nLink: [CVE-2025-48432](https://avd.aquasec.com/nvd/cve-2025-48432)" }, - "ruleId": "CVE-2024-45231", + "ruleId": "CVE-2025-48432", "ruleIndex": 6 }, { @@ -172,31 +172,31 @@ "ruleIndex": 3 }, { - "level": "warning", + "level": "note", "locations": [ { "message": { - "text": "requirements.txt: django@1.11.29" + "text": "package-lock.json: brace-expansion@1.1.11" }, "physicalLocation": { "artifactLocation": { - "uri": "requirements.txt", + "uri": "package-lock.json", "uriBaseId": "ROOTPATH" }, "region": { "endColumn": 1, - "endLine": 1, + "endLine": 357, "startColumn": 1, - "startLine": 1 + "startLine": 349 } } } ], "message": { - "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2025-48432\nSeverity: MEDIUM\nFixed Version: 5.2.2, 5.1.10, 4.2.22\nLink: [CVE-2025-48432](https://avd.aquasec.com/nvd/cve-2025-48432)" + "text": "Package: brace-expansion\nInstalled Version: 1.1.11\nVulnerability CVE-2025-5889\nSeverity: LOW\nFixed Version: 2.0.2, 1.1.12, 3.0.1, 4.0.1\nLink: [CVE-2025-5889](https://avd.aquasec.com/nvd/cve-2025-5889)" }, - "ruleId": "CVE-2025-48432", - "ruleIndex": 5 + "ruleId": "CVE-2025-5889", + "ruleIndex": 0 } ], "tool": { diff --git a/plugins/tools/trivy/test/src/.codacy/codacy.yaml b/plugins/tools/trivy/test/src/.codacy/codacy.yaml index fb538d3c..f9dabc55 100644 --- a/plugins/tools/trivy/test/src/.codacy/codacy.yaml +++ b/plugins/tools/trivy/test/src/.codacy/codacy.yaml @@ -1,3 +1,3 @@ runtimes: tools: - - trivy@0.65.0 \ No newline at end of file + - trivy@0.66.0 \ No newline at end of file diff --git a/tools/semgrepConfigCreator.go b/tools/semgrepConfigCreator.go index d51f9df5..55229c06 100644 --- a/tools/semgrepConfigCreator.go +++ b/tools/semgrepConfigCreator.go @@ -4,7 +4,6 @@ import ( "codacy/cli-v2/domain" "codacy/cli-v2/plugins/tools/semgrep/embedded" "fmt" - "os" "strings" "gopkg.in/yaml.v3" @@ -15,10 +14,6 @@ type semgrepRulesFile struct { Rules []map[string]interface{} `yaml:"rules"` } -// getExecutablePath is a variable that holds the function to get the executable path -// This is used for testing purposes -var getExecutablePath = os.Executable - // FilterRulesFromFile extracts enabled rules from a rules.yaml file based on configuration func FilterRulesFromFile(rulesData []byte, config []domain.PatternConfiguration) ([]byte, error) { // Parse the YAML data