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/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/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/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/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-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/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..3ff8d613 100644 --- a/integration-tests/init-without-token/expected/tools-configs/semgrep.yaml +++ b/integration-tests/init-without-token/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/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/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..70e9384d 100644 --- a/plugins/tools/trivy/test/expected.sarif +++ b/plugins/tools/trivy/test/expected.sarif @@ -10,31 +10,58 @@ }, "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", - "ruleIndex": 0 + "ruleId": "CVE-2021-33203", + "ruleIndex": 4 + }, + { + "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-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-2022-36359", + "ruleIndex": 2 }, { "level": "error", @@ -64,7 +91,7 @@ "ruleIndex": 1 }, { - "level": "error", + "level": "warning", "locations": [ { "message": { @@ -85,10 +112,10 @@ } ], "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: 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-2022-36359", - "ruleIndex": 2 + "ruleId": "CVE-2024-45231", + "ruleIndex": 5 }, { "level": "warning", @@ -112,13 +139,13 @@ } ], "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-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-2021-33203", - "ruleIndex": 3 + "ruleId": "CVE-2025-48432", + "ruleIndex": 6 }, { - "level": "warning", + "level": "error", "locations": [ { "message": { @@ -139,37 +166,37 @@ } ], "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-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-2024-45231", - "ruleIndex": 4 + "ruleId": "CVE-2025-57833", + "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": { @@ -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/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 a4e6d5e4..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 @@ -35,7 +30,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": [