narvy-cli 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. narvy/__init__.py +3 -0
  2. narvy/android/__init__.py +0 -0
  3. narvy/android/source_analyzer.py +268 -0
  4. narvy/android/split_bundle.py +475 -0
  5. narvy/android_rule_context.py +196 -0
  6. narvy/apk_memory_preflight.py +248 -0
  7. narvy/auth.py +40 -0
  8. narvy/ci_templates/bitbucket.yml +25 -0
  9. narvy/ci_templates/github.yml +60 -0
  10. narvy/ci_templates/gitlab.yml +32 -0
  11. narvy/cloud/__init__.py +0 -0
  12. narvy/cloud/aws_scan.py +1188 -0
  13. narvy/comment_filter.py +134 -0
  14. narvy/crypto_taint_lite.py +82 -0
  15. narvy/decompiler.py +337 -0
  16. narvy/doctor.py +244 -0
  17. narvy/host/__init__.py +0 -0
  18. narvy/host/audit.py +157 -0
  19. narvy/host/host_knowledge.py +982 -0
  20. narvy/host/lynis_bootstrap.py +400 -0
  21. narvy/host/lynis_parser.py +358 -0
  22. narvy/host/narvy_checks.py +789 -0
  23. narvy/host/report.py +69 -0
  24. narvy/host/ssh_exec.py +219 -0
  25. narvy/ios/__init__.py +0 -0
  26. narvy/ios/binary_analyzer.py +1201 -0
  27. narvy/ios/plist_checks.py +249 -0
  28. narvy/ios/source_analyzer.py +301 -0
  29. narvy/ios/third_party_filter.py +242 -0
  30. narvy/ios/trust_all_context.py +66 -0
  31. narvy/main.py +1983 -0
  32. narvy/native_hardening.py +503 -0
  33. narvy/reporter.py +151 -0
  34. narvy/rule_engine.py +57 -0
  35. narvy/rules/android/config.yml +77 -0
  36. narvy/rules/android/crypto.yml +34 -0
  37. narvy/rules/android/secrets.yml +161 -0
  38. narvy/rules/android/storage.yml +24 -0
  39. narvy/rules/android/webview.yml +23 -0
  40. narvy/rules/android.yml +219 -0
  41. narvy/rules/ios/objc/crypto.yml +56 -0
  42. narvy/rules/ios/objc/network.yml +67 -0
  43. narvy/rules/ios/objc/secrets.yml +79 -0
  44. narvy/rules/ios/objc/storage.yml +45 -0
  45. narvy/rules/ios/objc/webview.yml +45 -0
  46. narvy/rules/ios_swift.yml +327 -0
  47. narvy/rules/web/go.yml +2837 -0
  48. narvy/rules/web/java.yml +1576 -0
  49. narvy/rules/web/javascript.yml +3683 -0
  50. narvy/rules/web/kotlin.yml +413 -0
  51. narvy/rules/web/local/csharp_narvy/config.yml +61 -0
  52. narvy/rules/web/local/csharp_narvy/crypto.yml +64 -0
  53. narvy/rules/web/local/csharp_narvy/deserialization.yml +59 -0
  54. narvy/rules/web/local/csharp_narvy/injection.yml +122 -0
  55. narvy/rules/web/local/csharp_narvy/xxe.yml +48 -0
  56. narvy/rules/web/local/java_narvy/auth_jwt.yml +134 -0
  57. narvy/rules/web/local/java_narvy/deserialization.yml +108 -0
  58. narvy/rules/web/local/java_narvy/mybatis.yml +39 -0
  59. narvy/rules/web/local/java_narvy/snakeyaml.yml +34 -0
  60. narvy/rules/web/local/java_narvy/spring_authz.yml +32 -0
  61. narvy/rules/web/local/java_narvy/spring_config.yml +67 -0
  62. narvy/rules/web/local/java_narvy/spring_hardening.yml +291 -0
  63. narvy/rules/web/local/java_narvy/sqli.yml +235 -0
  64. narvy/rules/web/local/java_narvy/xxe.yml +212 -0
  65. narvy/rules/web/php.yml +1644 -0
  66. narvy/rules/web/python.yml +3967 -0
  67. narvy/rules/web/ruby.yml +703 -0
  68. narvy/rules/web/rust.yml +258 -0
  69. narvy/rules/web/secrets.yml +1420 -0
  70. narvy/rules/web/secrets_supplement.yml +383 -0
  71. narvy/sca/__init__.py +1 -0
  72. narvy/sca/android_deps.py +349 -0
  73. narvy/sca/ios_deps.py +578 -0
  74. narvy/sca/osv_client.py +617 -0
  75. narvy/sca/web_deps.py +955 -0
  76. narvy/scope_config.py +195 -0
  77. narvy/semgrep_engine.py +219 -0
  78. narvy/stack_protector_evidence.py +96 -0
  79. narvy/third_party_filter.py +211 -0
  80. narvy/uploader.py +92 -0
  81. narvy/weak_prng_context.py +270 -0
  82. narvy/web/__init__.py +0 -0
  83. narvy/web/nuclei_binary.py +105 -0
  84. narvy/web/scan_blocklist.py +96 -0
  85. narvy/web/scanner.py +842 -0
  86. narvy/web/source_analyzer.py +714 -0
  87. narvy/web/ssrf_guard.py +374 -0
  88. narvy_cli-1.0.0.dist-info/METADATA +165 -0
  89. narvy_cli-1.0.0.dist-info/RECORD +93 -0
  90. narvy_cli-1.0.0.dist-info/WHEEL +5 -0
  91. narvy_cli-1.0.0.dist-info/entry_points.txt +2 -0
  92. narvy_cli-1.0.0.dist-info/licenses/LICENSE +202 -0
  93. narvy_cli-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,122 @@
1
+ rules:
2
+
3
+ # C#/.NET injection: ADO.NET SQL concatenation, request input into filesystem APIs (path traversal) and process launch (command injection).
4
+
5
+ - id: narvy.csharp.sqli.command-text-concat.command-text-concat
6
+ message: >-
7
+ A SQL command text is built with `+` string concatenation and handed to
8
+ ADO.NET (`new SqlCommand(...)`, `SqlCommand.CommandText`, or the
9
+ equivalent `Npgsql`/`MySql`/`OleDb`/`Odbc`/`SQLite` command). Any tainted
10
+ value spliced into the SQL grammar this way is a SQL injection (CWE-89).
11
+ Keep the command text a fixed literal and pass values as parameters
12
+ (`cmd.Parameters.AddWithValue("@id", id)` with a `@id` placeholder).
13
+ severity: ERROR
14
+ languages: [csharp]
15
+ metadata:
16
+ category: security
17
+ cwe:
18
+ - "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')"
19
+ owasp:
20
+ - "A03:2021 - Injection"
21
+ subcategory: [vuln]
22
+ likelihood: HIGH
23
+ impact: HIGH
24
+ confidence: MEDIUM
25
+ technology: [csharp, dotnet, ado.net]
26
+ patterns:
27
+ - pattern-either:
28
+ - pattern: new $CMDTYPE($SQL, ...)
29
+ - pattern: new $CMDTYPE($SQL)
30
+ - pattern: $CMD.CommandText = $SQL;
31
+ - metavariable-regex:
32
+ metavariable: $CMDTYPE
33
+ regex: ^(SqlCommand|NpgsqlCommand|MySqlCommand|OleDbCommand|OdbcCommand|SQLiteCommand|SqliteCommand)$
34
+ - metavariable-pattern:
35
+ metavariable: $SQL
36
+ patterns:
37
+ # concatenation, but not a chain of only string literals joined by `+`
38
+ - pattern-regex: '\+'
39
+ - pattern-not-regex: '^\s*@?\$?"(?:[^"\\]|\\.)*"(\s*\+\s*@?\$?"(?:[^"\\]|\\.)*")*\s*$'
40
+
41
+ - id: narvy.csharp.pathtraversal.request-input-into-file-api.request-input-into-file-api
42
+ message: >-
43
+ A value read from the HTTP request (`Request.Query`/`Form`/`Headers`/
44
+ `Cookies`/`RouteValues`) reaches a `System.IO` file API without being
45
+ reduced to a bare file name first. An attacker can supply `../` segments
46
+ (or an absolute path) to read or write files outside the intended
47
+ directory (CWE-22). Strip the path with `Path.GetFileName(...)` and
48
+ resolve it against a fixed base directory, rejecting anything that
49
+ escapes it.
50
+ severity: ERROR
51
+ languages: [csharp]
52
+ mode: taint
53
+ metadata:
54
+ category: security
55
+ cwe:
56
+ - "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')"
57
+ owasp:
58
+ - "A01:2021 - Broken Access Control"
59
+ subcategory: [vuln]
60
+ likelihood: MEDIUM
61
+ impact: HIGH
62
+ confidence: MEDIUM
63
+ technology: [csharp, dotnet, asp.net]
64
+ pattern-sources:
65
+ - patterns:
66
+ - pattern-either:
67
+ - pattern: $REQ.Query[...]
68
+ - pattern: $REQ.Form[...]
69
+ - pattern: $REQ.Headers[...]
70
+ - pattern: $REQ.Cookies[...]
71
+ - pattern: $REQ.RouteValues[...]
72
+ pattern-sanitizers:
73
+ - pattern: Path.GetFileName(...)
74
+ pattern-sinks:
75
+ - patterns:
76
+ - pattern-either:
77
+ - pattern: File.ReadAllText(...)
78
+ - pattern: File.ReadAllBytes(...)
79
+ - pattern: File.ReadAllLines(...)
80
+ - pattern: File.OpenRead(...)
81
+ - pattern: File.OpenText(...)
82
+ - pattern: File.WriteAllText(...)
83
+ - pattern: File.WriteAllBytes(...)
84
+ - pattern: new StreamReader(...)
85
+ - pattern: new FileStream(...)
86
+
87
+ - id: narvy.csharp.cmdi.process-start-untrusted.process-start-untrusted
88
+ message: >-
89
+ A value read from the HTTP request is passed to `Process.Start(...)`
90
+ (as the file name or the arguments). Request-controlled process
91
+ arguments let an attacker inject extra arguments, and a
92
+ request-controlled file name lets them choose the program to run - both
93
+ are command injection (CWE-78). Never build a process invocation from
94
+ request input; if an external tool must run, hardcode the executable and
95
+ pass a strictly validated, allow-listed argument.
96
+ severity: ERROR
97
+ languages: [csharp]
98
+ metadata:
99
+ category: security
100
+ cwe:
101
+ - "CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')"
102
+ owasp:
103
+ - "A03:2021 - Injection"
104
+ subcategory: [vuln]
105
+ likelihood: HIGH
106
+ impact: HIGH
107
+ confidence: MEDIUM
108
+ technology: [csharp, dotnet]
109
+ patterns:
110
+ - pattern-either:
111
+ - pattern: System.Diagnostics.Process.Start(..., $REQ.Query[...], ...)
112
+ - pattern: System.Diagnostics.Process.Start(..., $REQ.Form[...], ...)
113
+ - pattern: System.Diagnostics.Process.Start(..., $REQ.Headers[...], ...)
114
+ - pattern: System.Diagnostics.Process.Start(..., $REQ.RouteValues[...], ...)
115
+ - pattern: System.Diagnostics.Process.Start($REQ.Query[...], ...)
116
+ - pattern: System.Diagnostics.Process.Start($REQ.Form[...], ...)
117
+ - pattern: Process.Start(..., $REQ.Query[...], ...)
118
+ - pattern: Process.Start(..., $REQ.Form[...], ...)
119
+ - pattern: Process.Start(..., $REQ.Headers[...], ...)
120
+ - pattern: Process.Start(..., $REQ.RouteValues[...], ...)
121
+ - pattern: Process.Start($REQ.Query[...], ...)
122
+ - pattern: Process.Start($REQ.Form[...], ...)
@@ -0,0 +1,48 @@
1
+ rules:
2
+
3
+ # C#/.NET XXE: an XmlDocument left with its default resolver still resolves external entities/DTDs.
4
+
5
+ - id: narvy.csharp.xxe.xmldocument-default-resolver.xmldocument-default-resolver
6
+ message: >-
7
+ An `XmlDocument` parses input while keeping its default `XmlResolver`.
8
+ On older target frameworks that resolver follows external entities and
9
+ DTDs, so parsing attacker-controlled XML lets it read local files or
10
+ reach internal network resources (XXE / SSRF, CWE-611). Set
11
+ `doc.XmlResolver = null;` before loading, or parse with
12
+ `XmlReader` configured with `DtdProcessing.Prohibit`.
13
+ severity: ERROR
14
+ languages: [csharp]
15
+ metadata:
16
+ category: security
17
+ cwe:
18
+ - "CWE-611: Improper Restriction of XML External Entity Reference"
19
+ owasp:
20
+ - "A05:2021 - Security Misconfiguration"
21
+ subcategory: [vuln]
22
+ likelihood: MEDIUM
23
+ impact: HIGH
24
+ confidence: MEDIUM
25
+ technology: [csharp, dotnet]
26
+ patterns:
27
+ - pattern-either:
28
+ - patterns:
29
+ - pattern-inside: |
30
+ var $DOC = new XmlDocument();
31
+ ...
32
+ - pattern-not-inside: |
33
+ var $DOC = new XmlDocument();
34
+ ...
35
+ $DOC.XmlResolver = null;
36
+ ...
37
+ - patterns:
38
+ - pattern-inside: |
39
+ $TY $DOC = new XmlDocument();
40
+ ...
41
+ - pattern-not-inside: |
42
+ $TY $DOC = new XmlDocument();
43
+ ...
44
+ $DOC.XmlResolver = null;
45
+ ...
46
+ - pattern-either:
47
+ - pattern: $DOC.LoadXml(...)
48
+ - pattern: $DOC.Load(...)
@@ -0,0 +1,134 @@
1
+ rules:
2
+
3
+ # Java JWT auth weaknesses: hardcoded signing key, decode without verification, none-algorithm.
4
+
5
+ - id: narvy.java.jwt.hardcoded-signing-key.hardcoded-signing-key
6
+ message: >-
7
+ A JWT signing/verification key is a hardcoded string literal (`jjwt`'s
8
+ `Keys.hmacShaKeyFor(...)`, `java-jwt`'s `Algorithm.HMAC256(...)`, or a
9
+ plain `.getBytes()` call on a literal). Anyone with source or
10
+ decompiled-binary access can forge arbitrarily privileged tokens
11
+ (CWE-321, CWE-798). Load the signing key from an environment variable or
12
+ secrets manager, generated with at least 256 bits of entropy for HMAC.
13
+ severity: ERROR
14
+ languages: [java]
15
+ metadata:
16
+ category: security
17
+ cwe:
18
+ - "CWE-321: Use of Hard-coded Cryptographic Key"
19
+ - "CWE-798: Use of Hard-coded Credentials"
20
+ owasp:
21
+ - "A07:2021 - Identification and Authentication Failures"
22
+ subcategory: [vuln]
23
+ likelihood: LOW
24
+ impact: HIGH
25
+ confidence: MEDIUM
26
+ technology: [java]
27
+ patterns:
28
+ - pattern-either:
29
+ - pattern: Keys.hmacShaKeyFor("...".getBytes(...))
30
+ - pattern: io.jsonwebtoken.security.Keys.hmacShaKeyFor("...".getBytes(...))
31
+ - pattern: Algorithm.HMAC256("...")
32
+ - pattern: Algorithm.HMAC384("...")
33
+ - pattern: Algorithm.HMAC512("...")
34
+ - pattern: com.auth0.jwt.algorithms.Algorithm.HMAC256("...")
35
+
36
+ - id: narvy.java.jwt.decode-without-verification.decode-without-verification
37
+ message: >-
38
+ `JWT.decode(...)` (auth0 java-jwt) reads and parses a token's claims
39
+ without verifying its signature - unlike `JWTVerifier.verify(...)`,
40
+ `decode` accepts a token signed with any key, or none at all. Branching
41
+ on claims read this way (role, user id, `exp`) is an authentication
42
+ bypass (CWE-347). Use a `JWTVerifier` built with the expected algorithm
43
+ and key, and call `verify(token)` instead of `decode(token)`.
44
+ severity: ERROR
45
+ languages: [java]
46
+ metadata:
47
+ category: security
48
+ cwe:
49
+ - "CWE-347: Improper Verification of Cryptographic Signature"
50
+ owasp:
51
+ - "A07:2021 - Identification and Authentication Failures"
52
+ subcategory: [vuln]
53
+ likelihood: MEDIUM
54
+ impact: HIGH
55
+ confidence: HIGH
56
+ technology: [java]
57
+ patterns:
58
+ - pattern-either:
59
+ - pattern: JWT.decode($TOKEN)
60
+ - pattern: com.auth0.jwt.JWT.decode($TOKEN)
61
+
62
+ - id: narvy.java.jwt.parser-no-signing-key.parser-no-signing-key
63
+ message: >-
64
+ A `jjwt` `Jwts.parserBuilder()` (or the deprecated `Jwts.parser()`)
65
+ chain calls `.build().parse(...)`/`.parseClaimsJws(...)` with no
66
+ `.setSigningKey(...)`/`.verifyWith(...)` configured on the builder. Some
67
+ jjwt versions accept an unsigned or `alg: none` token in this
68
+ configuration, which is a full authentication bypass (CWE-347). Always
69
+ set the expected signing key (and, ideally, pin the accepted algorithm)
70
+ on the parser builder before parsing an incoming token.
71
+ severity: WARNING
72
+ languages: [java]
73
+ metadata:
74
+ category: security
75
+ cwe:
76
+ - "CWE-347: Improper Verification of Cryptographic Signature"
77
+ owasp:
78
+ - "A07:2021 - Identification and Authentication Failures"
79
+ subcategory: [audit]
80
+ likelihood: LOW
81
+ impact: HIGH
82
+ confidence: LOW
83
+ technology: [java]
84
+ patterns:
85
+ - pattern: |
86
+ $P = Jwts.parserBuilder();
87
+ ...
88
+ $P.build().parseClaimsJws($TOKEN);
89
+ - pattern-not: |
90
+ $P = Jwts.parserBuilder();
91
+ ...
92
+ $P.setSigningKey(...);
93
+ ...
94
+ $P.build().parseClaimsJws($TOKEN);
95
+ - pattern-not: |
96
+ $P = Jwts.parserBuilder();
97
+ ...
98
+ $P.verifyWith(...);
99
+ ...
100
+ $P.build().parseClaimsJws($TOKEN);
101
+
102
+ - id: narvy.java.jwt.hardcoded-fallback-secret.hardcoded-fallback-secret
103
+ message: >-
104
+ A JWT/session-signing secret is read from configuration with a
105
+ hardcoded string as the fallback default (`System.getProperty("...",
106
+ "literal")`, `env.getProperty("...", "literal")`). If the real
107
+ environment variable or property is ever unset - a common deployment
108
+ mistake - every instance silently falls back to the same publicly
109
+ visible secret, which lets anyone forge valid tokens (CWE-798,
110
+ CWE-321). Fail closed instead: throw if the property is missing rather
111
+ than substituting a literal.
112
+ severity: ERROR
113
+ languages: [java]
114
+ metadata:
115
+ category: security
116
+ cwe:
117
+ - "CWE-798: Use of Hard-coded Credentials"
118
+ - "CWE-321: Use of Hard-coded Cryptographic Key"
119
+ owasp:
120
+ - "A07:2021 - Identification and Authentication Failures"
121
+ subcategory: [vuln]
122
+ likelihood: LOW
123
+ impact: HIGH
124
+ confidence: LOW
125
+ technology: [java]
126
+ patterns:
127
+ - pattern-either:
128
+ - pattern: System.getProperty($KEY, "...")
129
+ - pattern: System.getenv($KEY, "...")
130
+ - pattern: $ENV.getProperty($KEY, "...")
131
+ - pattern: $ENV.getProperty($KEY, "...", ...)
132
+ - metavariable-regex:
133
+ metavariable: $KEY
134
+ regex: (?i)"[^"]*(secret|jwt|token|signing.?key|api.?key|password|passwd|credential)[^"]*"
@@ -0,0 +1,108 @@
1
+ rules:
2
+
3
+ # Java unsafe deserialization: ObjectInputStream, Jackson polymorphic typing, JMS ObjectMessage.
4
+
5
+ - id: narvy.java.deserialization.objectinputstream-readobject.objectinputstream-readobject
6
+ message: >-
7
+ `ObjectInputStream.readObject()` deserialises whatever class stream the
8
+ caller supplies. If the underlying stream can come from the network, a
9
+ file upload, or any other untrusted source, an attacker can smuggle a
10
+ gadget-chain payload that executes arbitrary code the moment it is
11
+ deserialised, before any application logic runs (CWE-502). Avoid native
12
+ Java serialization for untrusted input; use a data format with no code
13
+ execution surface (JSON/Protobuf), or wrap the stream in a
14
+ `ObjectInputFilter` allow-list of expected classes.
15
+ severity: ERROR
16
+ languages: [java]
17
+ metadata:
18
+ category: security
19
+ cwe:
20
+ - "CWE-502: Deserialization of Untrusted Data"
21
+ owasp:
22
+ - "A08:2021 - Software and Data Integrity Failures"
23
+ subcategory: [vuln]
24
+ likelihood: LOW
25
+ impact: HIGH
26
+ confidence: LOW
27
+ technology: [java]
28
+ patterns:
29
+ - pattern-either:
30
+ - pattern: new ObjectInputStream($SOCK.getInputStream()).readObject()
31
+ - pattern: |
32
+ $OIS = new ObjectInputStream($SOCK.getInputStream());
33
+ ...
34
+ $OIS.readObject();
35
+ - pattern: |
36
+ $OIS = new ObjectInputStream($ANY);
37
+ ...
38
+ $OIS.readObject();
39
+ - pattern-not: |
40
+ $OIS = new ObjectInputStream($ANY);
41
+ $OIS.setObjectInputFilter(...);
42
+ ...
43
+ $OIS.readObject();
44
+
45
+ - id: narvy.java.deserialization.jackson-enable-default-typing.jackson-enable-default-typing
46
+ message: >-
47
+ Jackson's `ObjectMapper` has polymorphic default typing enabled
48
+ (`enableDefaultTyping`/`activateDefaultTyping`) with no restricted
49
+ `PolymorphicTypeValidator`. This embeds a `@class` field in the JSON that
50
+ tells Jackson which concrete class to instantiate, and an attacker who
51
+ controls the JSON can point it at a gadget class already on the
52
+ classpath to achieve remote code execution (CWE-502). Remove default
53
+ typing, or pass a `BasicPolymorphicTypeValidator` restricted to an
54
+ explicit allow-list of expected base types.
55
+ severity: ERROR
56
+ languages: [java]
57
+ metadata:
58
+ category: security
59
+ cwe:
60
+ - "CWE-502: Deserialization of Untrusted Data"
61
+ owasp:
62
+ - "A08:2021 - Software and Data Integrity Failures"
63
+ subcategory: [vuln]
64
+ likelihood: LOW
65
+ impact: HIGH
66
+ confidence: MEDIUM
67
+ technology: [java]
68
+ patterns:
69
+ - pattern-either:
70
+ # Bare/legacy calls carry no validator at all - always permissive.
71
+ - pattern: $MAPPER.enableDefaultTyping()
72
+ - pattern: $MAPPER.enableDefaultTyping($X)
73
+ # Only the laissez-faire validator (accepts every class) is flagged; a scoped validator is left alone.
74
+ - pattern: $MAPPER.activateDefaultTyping(LaissezFaireSubTypeValidator.instance)
75
+ - pattern: $MAPPER.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ...)
76
+ # Exclude Spring Security's SecurityJackson2Modules.enableDefaultTyping: it installs typing behind an allow-list (mitigated form).
77
+ - pattern-not: SecurityJackson2Modules.enableDefaultTyping(...)
78
+ - pattern-not: $P.SecurityJackson2Modules.enableDefaultTyping(...)
79
+
80
+ - id: narvy.java.deserialization.jms-objectmessage-getobject.jms-objectmessage-getobject
81
+ message: >-
82
+ `ObjectMessage.getObject()` deserialises the message payload with native
83
+ Java serialization. A JMS broker that accepts messages from outside the
84
+ trust boundary (or a compromised producer) can deliver a gadget-chain
85
+ payload that executes on `getObject()` (CWE-502). Prefer `TextMessage`
86
+ with an explicit JSON/Protobuf parser, or configure the JMS provider's
87
+ class allow-list (e.g. ActiveMQ's `trustedPackages`) if
88
+ `ObjectMessage` must be kept.
89
+ severity: WARNING
90
+ languages: [java]
91
+ metadata:
92
+ category: security
93
+ cwe:
94
+ - "CWE-502: Deserialization of Untrusted Data"
95
+ owasp:
96
+ - "A08:2021 - Software and Data Integrity Failures"
97
+ subcategory: [vuln]
98
+ likelihood: LOW
99
+ impact: HIGH
100
+ confidence: LOW
101
+ technology: [java]
102
+ patterns:
103
+ - pattern-either:
104
+ - pattern: (($T) $MSG).getObject()
105
+ - pattern: $MSG.getObject()
106
+ - pattern-inside: |
107
+ $MSG = ($T) $CONSUMER.receive(...);
108
+ ...
@@ -0,0 +1,39 @@
1
+ rules:
2
+
3
+ # MyBatis mapper XML: `${...}` splices into SQL text (unlike `#{...}` which binds `?`), so tainted `${...}` is SQLi. Generic mode over mapper *.xml.
4
+
5
+ - id: narvy.java.mybatis.handwritten-dollar-substitution.handwritten-dollar-substitution
6
+ message: >-
7
+ A MyBatis mapper uses `${...}` substitution in a SQL statement. MyBatis
8
+ inlines `${...}` into the query text verbatim (only `#{...}` becomes a
9
+ bound `?` placeholder), so any tainted value that reaches it is a SQL
10
+ injection (CWE-89). Use `#{param}` for values; a `${...}` is only
11
+ acceptable for a column/table identifier you have validated against a
12
+ fixed allow-list.
13
+ severity: ERROR
14
+ languages: [generic]
15
+ paths:
16
+ include:
17
+ - "*.xml"
18
+ metadata:
19
+ category: security
20
+ cwe:
21
+ - "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')"
22
+ owasp:
23
+ - "A03:2021 - Injection"
24
+ subcategory: [vuln]
25
+ likelihood: HIGH
26
+ impact: HIGH
27
+ confidence: MEDIUM
28
+ technology: [java, mybatis]
29
+ patterns:
30
+ - pattern-regex: '\$\{[^}]+\}'
31
+ # Exclude MyBatis Generator boilerplate tokens (framework-emitted, not hand-written interpolation).
32
+ - pattern-not-regex: '\$\{(criterion\.condition|criterion\.value|orderByClause|listItem|item\.[A-Za-z0-9_.]+)\}'
33
+ # Scope to MyBatis SQL statement elements, else `${...}` hits log4j2/Spring placeholders (large FP class).
34
+ - pattern-either:
35
+ - pattern-inside: "<select ...>...</select>"
36
+ - pattern-inside: "<insert ...>...</insert>"
37
+ - pattern-inside: "<update ...>...</update>"
38
+ - pattern-inside: "<delete ...>...</delete>"
39
+ - pattern-inside: "<sql ...>...</sql>"
@@ -0,0 +1,34 @@
1
+ rules:
2
+
3
+ # SnakeYAML: default `new Yaml()` uses the unrestricted `Constructor`, an RCE gadget on attacker-controlled YAML.
4
+
5
+ - id: narvy.java.deserialization.snakeyaml-unsafe-constructor.snakeyaml-unsafe-constructor
6
+ message: >-
7
+ A SnakeYAML `Yaml` built with the default constructor parses input with
8
+ the unrestricted `Constructor`, which will instantiate any Java type the
9
+ document names through a `!!package.Class` tag. On attacker-controlled
10
+ YAML this is a deserialization gadget that leads to remote code execution
11
+ (CWE-502). Construct the parser with `new Yaml(new SafeConstructor(new
12
+ LoaderOptions()))` (or a `Constructor` restricted to an explicit
13
+ allow-list of expected types) before calling `load`.
14
+ severity: ERROR
15
+ languages: [java]
16
+ metadata:
17
+ category: security
18
+ cwe:
19
+ - "CWE-502: Deserialization of Untrusted Data"
20
+ owasp:
21
+ - "A08:2021 - Software and Data Integrity Failures"
22
+ subcategory: [vuln]
23
+ likelihood: MEDIUM
24
+ impact: HIGH
25
+ confidence: MEDIUM
26
+ technology: [java, snakeyaml]
27
+ patterns:
28
+ - pattern-inside: |
29
+ Yaml $Y = new Yaml();
30
+ ...
31
+ - pattern-either:
32
+ - pattern: $Y.load($SRC)
33
+ - pattern: $Y.loadAll($SRC)
34
+ - pattern: $Y.loadAs($SRC, ...)
@@ -0,0 +1,32 @@
1
+ rules:
2
+
3
+ # Spring Security authorization: a filter chain that permits every request.
4
+
5
+ - id: narvy.java.spring.permit-all-requests.permit-all-requests
6
+ message: >-
7
+ This Spring Security filter chain authorizes EVERY request
8
+ (`anyRequest().permitAll()`), so no endpoint behind it requires
9
+ authentication. If any protected resource is served by this chain, it is
10
+ now publicly reachable (CWE-862, Missing Authorization). Scope
11
+ `permitAll()` to the handful of genuinely public paths with
12
+ `requestMatchers(...)` and finish the chain with
13
+ `anyRequest().authenticated()` so anything you did not explicitly open
14
+ stays protected.
15
+ severity: ERROR
16
+ languages: [java]
17
+ metadata:
18
+ category: security
19
+ cwe:
20
+ - "CWE-862: Missing Authorization"
21
+ owasp:
22
+ - "A01:2021 - Broken Access Control"
23
+ subcategory: [vuln]
24
+ likelihood: MEDIUM
25
+ impact: HIGH
26
+ confidence: MEDIUM
27
+ technology: [java, spring]
28
+ patterns:
29
+ - pattern-either:
30
+ - pattern: $A.anyRequest().permitAll()
31
+ - pattern: $A.antMatchers("/**").permitAll()
32
+ - pattern: $A.requestMatchers("/**").permitAll()
@@ -0,0 +1,67 @@
1
+ rules:
2
+
3
+ # Spring Boot config hardening (application.properties/.yml): actuator endpoints exposed, H2 web console on.
4
+ # Generic mode over *.properties/*.yml.
5
+
6
+ - id: narvy.java.spring.actuator-exposed-all.actuator-exposed-all
7
+ message: >-
8
+ `management.endpoints.web.exposure.include` is set to `*`, which exposes
9
+ EVERY actuator endpoint over HTTP - including `/actuator/env`,
10
+ `/actuator/heapdump`, `/actuator/threaddump` and, when Spring Boot Admin
11
+ or the loggers endpoint is present, remote configuration changes. These
12
+ leak environment variables, secrets and internal state, and several are
13
+ write-capable (CWE-200, CWE-16). Expose only the endpoints you actually
14
+ need (typically `health,info`) and secure the management port/context
15
+ behind authentication.
16
+ severity: WARNING
17
+ languages: [generic]
18
+ paths:
19
+ include:
20
+ - "*.properties"
21
+ - "*.yml"
22
+ - "*.yaml"
23
+ - "*.conf"
24
+ metadata:
25
+ category: security
26
+ cwe:
27
+ - "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor"
28
+ owasp:
29
+ - "A05:2021 - Security Misconfiguration"
30
+ subcategory: [audit]
31
+ likelihood: MEDIUM
32
+ impact: MEDIUM
33
+ confidence: HIGH
34
+ technology: [java, spring, spring-boot]
35
+ patterns:
36
+ - pattern-regex: 'management\.endpoints\.web\.exposure\.include\s*[:=]\s*["'']?\*'
37
+
38
+ - id: narvy.java.spring.h2-console-enabled.h2-console-enabled
39
+ message: >-
40
+ The H2 database web console is enabled (`spring.h2.console.enabled=true`).
41
+ The console is an unauthenticated servlet by default that runs arbitrary
42
+ SQL - and, through H2's `CREATE ALIAS ... AS` / `RUNSCRIPT` features, can
43
+ reach arbitrary Java code, making an exposed console a remote-code-
44
+ execution path (CWE-489, CWE-16). Never enable it outside local
45
+ development; if it must be on in a shared environment, restrict its
46
+ path to localhost and put it behind authentication.
47
+ severity: WARNING
48
+ languages: [generic]
49
+ paths:
50
+ include:
51
+ - "*.properties"
52
+ - "*.yml"
53
+ - "*.yaml"
54
+ - "*.conf"
55
+ metadata:
56
+ category: security
57
+ cwe:
58
+ - "CWE-489: Active Debug Code"
59
+ owasp:
60
+ - "A05:2021 - Security Misconfiguration"
61
+ subcategory: [audit]
62
+ likelihood: MEDIUM
63
+ impact: HIGH
64
+ confidence: HIGH
65
+ technology: [java, spring, spring-boot, h2]
66
+ patterns:
67
+ - pattern-regex: 'spring\.h2\.console\.enabled\s*[:=]\s*true'