Skip to content

Commit c5e0520

Browse files
committed
Add reader and tests for SAST Precaution
This change adds Precaution to the list of supported SASTs. Precaution can render its output as SARIF so it extends the SarifReader. Included are a test case and example SARIF output file as a result of scanning BenchmarkTest00073.java in BenchmarkJava. https://github.com/securesauce/precli Signed-off-by: Eric Brown <eric_wade_brown@yahoo.com>
1 parent 4f80e9a commit c5e0520

File tree

4 files changed

+237
-0
lines changed

4 files changed

+237
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* OWASP Benchmark Project
3+
*
4+
* <p>This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For
5+
* details, please see <a
6+
* href="https://owasp.org/www-project-benchmark/">https://owasp.org/www-project-benchmark/</a>.
7+
*
8+
* <p>The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms
9+
* of the GNU General Public License as published by the Free Software Foundation, version 2.
10+
*
11+
* <p>The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY
12+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13+
* PURPOSE. See the GNU General Public License for more details.
14+
*
15+
* @author Eric Brown
16+
* @created 2024
17+
*/
18+
package org.owasp.benchmarkutils.score.parsers;
19+
20+
import static java.lang.Integer.parseInt;
21+
22+
import java.util.HashMap;
23+
import java.util.Map;
24+
import org.json.JSONArray;
25+
import org.json.JSONObject;
26+
27+
public class PrecautionReader extends SarifReader {
28+
private final String CWE_PREFIX = "external/cwe/cwe-";
29+
private final int CWE_PREFIX_LENGTH = CWE_PREFIX.length();
30+
31+
@Override
32+
protected String expectedSarifToolName() {
33+
return "Precaution";
34+
}
35+
36+
@Override
37+
protected boolean isCommercial() {
38+
return false;
39+
}
40+
41+
@Override
42+
protected Map<String, Integer> ruleCweMappings(JSONArray rules) {
43+
Map<String, Integer> mappings = new HashMap<>();
44+
45+
for (int i = 0; i < rules.length(); i++) {
46+
JSONObject rule = rules.getJSONObject(i);
47+
JSONArray tags = rule.getJSONObject("properties").getJSONArray("tags");
48+
49+
for (int j = 0; j < tags.length(); j++) {
50+
String tag = tags.getString(j);
51+
52+
if (tag.startsWith(CWE_PREFIX)) {
53+
int cwe = parseInt(tag.substring(CWE_PREFIX_LENGTH));
54+
mappings.put(rule.getString("id"), cwe);
55+
}
56+
}
57+
}
58+
59+
return mappings;
60+
}
61+
}

plugin/src/main/java/org/owasp/benchmarkutils/score/parsers/Reader.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public static List<Reader> allReaders() {
8282
new NJSScanReader(),
8383
new NoisyCricketReader(),
8484
new ParasoftReader(),
85+
new PrecautionReader(),
8586
new PMDReader(),
8687
new QualysWASReader(),
8788
new Rapid7Reader(),
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* OWASP Benchmark Project
3+
*
4+
* <p>This file is part of the Open Web Application Security Project (OWASP) Benchmark Project For
5+
* details, please see <a
6+
* href="https://owasp.org/www-project-benchmark/">https://owasp.org/www-project-benchmark/</a>.
7+
*
8+
* <p>The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms
9+
* of the GNU General Public License as published by the Free Software Foundation, version 2.
10+
*
11+
* <p>The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY
12+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13+
* PURPOSE. See the GNU General Public License for more details.
14+
*
15+
* @author Eric Brown
16+
* @created 2024
17+
*/
18+
package org.owasp.benchmarkutils.score.parsers;
19+
20+
import static org.junit.jupiter.api.Assertions.assertEquals;
21+
import static org.junit.jupiter.api.Assertions.assertFalse;
22+
23+
import org.junit.jupiter.api.BeforeEach;
24+
import org.junit.jupiter.api.Test;
25+
import org.owasp.benchmarkutils.score.BenchmarkScore;
26+
import org.owasp.benchmarkutils.score.CweNumber;
27+
import org.owasp.benchmarkutils.score.ResultFile;
28+
import org.owasp.benchmarkutils.score.TestHelper;
29+
import org.owasp.benchmarkutils.score.TestSuiteResults;
30+
31+
class PrecautionReaderTest extends ReaderTestBase {
32+
33+
private ResultFile resultFile;
34+
35+
@BeforeEach
36+
void setUp() {
37+
resultFile = TestHelper.resultFileOf("testfiles/Benchmark_Precaution.sarif");
38+
BenchmarkScore.TESTCASENAME = "BenchmarkTest";
39+
}
40+
41+
@Test
42+
public void onlyPrecautionReportsCanReadAsTrue() {
43+
assertOnlyMatcherClassIs(this.resultFile, PrecautionReader.class);
44+
}
45+
46+
@Test
47+
void readerHandlesGivenResultFile() throws Exception {
48+
PrecautionReader reader = new PrecautionReader();
49+
TestSuiteResults result = reader.parse(resultFile);
50+
51+
assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType());
52+
assertFalse(result.isCommercial());
53+
assertEquals("Precaution", result.getToolName());
54+
assertEquals("0.5.0", result.getToolVersion());
55+
assertEquals(1, result.getTotalResults());
56+
assertEquals(CweNumber.WEAK_HASH_ALGO, result.get(73).get(0).getCWE());
57+
}
58+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
{
2+
"runs": [
3+
{
4+
"tool": {
5+
"driver": {
6+
"name": "Precaution",
7+
"organization": "Secure Sauce",
8+
"rules": [
9+
{
10+
"id": "JAV002",
11+
"help": {
12+
"text": "The Java `MessageDigest` class provides a number of options for algorithms\nto hash data. However, some of the hash algorithms are insecure and should\nnot be used. These insecure hash algorithms include `MD5` and `SHA-1`.\n\nThe MD5 hash algorithm is a cryptographic hash function that was designed in\nthe early 1990s. MD5 is no longer considered secure, and passwords hashed\nwith MD5 can be easily cracked by attackers.\n\nThe SHA-1 hash algorithm is also a cryptographic hash function that was\ndesigned in the early 1990s. SHA-1 is no longer considered secure, and\npasswords hashed with SHA-1 can be easily cracked by attackers.\n\n## Example\n\n```java\nimport java.security.*;\n\npublic class MessageDigestMD5 {\n public static void main(String[] args) {\n try {\n MessageDigest md = MessageDigest.getInstance(\"MD5\");\n } catch (NoSuchAlgorithmException e) {\n System.err.println(\"MD5 hashing algorithm not available.\");\n }\n }\n}\n```\n\n## Remediation\n\nThe recommendation is to swap the insecure hashing method to one of the more\nsecure alternatives, `SHA-256` or `SHA-512`.\n\n```java\nimport java.security.*;\n\npublic class MessageDigestSHA256 {\n public static void main(String[] args) {\n try {\n MessageDigest md = MessageDigest.getInstance(\"SHA-256\");\n } catch (NoSuchAlgorithmException e) {\n System.err.println(\"SHA-256 hashing algorithm not available.\");\n }\n }\n}\n```\n\n## See also\n\n- [MessageDigest (Java SE & JDK)](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/security/MessageDigest.html#getInstance(java.lang.String))\n- [CWE-328: Use of Weak Hash](https://cwe.mitre.org/data/definitions/328.html)\n- [NIST Policy on Hash Functions](https://csrc.nist.gov/projects/hash-functions)\n\n_New in version 0.5.0_\n\n",
13+
"markdown": "The Java `MessageDigest` class provides a number of options for algorithms\nto hash data. However, some of the hash algorithms are insecure and should\nnot be used. These insecure hash algorithms include `MD5` and `SHA-1`.\n\nThe MD5 hash algorithm is a cryptographic hash function that was designed in\nthe early 1990s. MD5 is no longer considered secure, and passwords hashed\nwith MD5 can be easily cracked by attackers.\n\nThe SHA-1 hash algorithm is also a cryptographic hash function that was\ndesigned in the early 1990s. SHA-1 is no longer considered secure, and\npasswords hashed with SHA-1 can be easily cracked by attackers.\n\n## Example\n\n```java\nimport java.security.*;\n\npublic class MessageDigestMD5 {\n public static void main(String[] args) {\n try {\n MessageDigest md = MessageDigest.getInstance(\"MD5\");\n } catch (NoSuchAlgorithmException e) {\n System.err.println(\"MD5 hashing algorithm not available.\");\n }\n }\n}\n```\n\n## Remediation\n\nThe recommendation is to swap the insecure hashing method to one of the more\nsecure alternatives, `SHA-256` or `SHA-512`.\n\n```java\nimport java.security.*;\n\npublic class MessageDigestSHA256 {\n public static void main(String[] args) {\n try {\n MessageDigest md = MessageDigest.getInstance(\"SHA-256\");\n } catch (NoSuchAlgorithmException e) {\n System.err.println(\"SHA-256 hashing algorithm not available.\");\n }\n }\n}\n```\n\n## See also\n\n- [MessageDigest (Java SE & JDK)](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/security/MessageDigest.html#getInstance(java.lang.String))\n- [CWE-328: Use of Weak Hash](https://cwe.mitre.org/data/definitions/328.html)\n- [NIST Policy on Hash Functions](https://csrc.nist.gov/projects/hash-functions)\n\n_New in version 0.5.0_\n\n"
14+
},
15+
"name": "MessageDigestWeakHash",
16+
"properties": {
17+
"tags": [
18+
"security",
19+
"external/cwe/cwe-328"
20+
],
21+
"security-severity": "8.0"
22+
},
23+
"helpUri": "https://docs.securesauce.dev/rules/JAV002",
24+
"messageStrings": {
25+
"default": {
26+
"text": "The hash function '{0}' is vulnerable to collision and pre-image attacks."
27+
}
28+
},
29+
"shortDescription": {
30+
"text": "Reversible One Way Hash in java.security Package"
31+
}
32+
}
33+
],
34+
"downloadUri": "https://pypi.org/project/precli/#files",
35+
"fullDescription": {
36+
"text": "Static analysis security tool command line"
37+
},
38+
"informationUri": "https://github.com/securesauce/precli",
39+
"semanticVersion": "0.5.0",
40+
"shortDescription": {
41+
"text": "Static analysis security tool command line"
42+
}
43+
}
44+
},
45+
"invocations": [
46+
{
47+
"executionSuccessful": true,
48+
"endTimeUtc": "2024-04-16T22:00:01Z"
49+
}
50+
],
51+
"results": [
52+
{
53+
"message": {
54+
"text": "The hash function 'MD5' is vulnerable to collision and pre-image attacks."
55+
},
56+
"fixes": [
57+
{
58+
"description": {
59+
"text": "For cryptographic purposes, use a hash length of at least 256-bits with hashes such as SHA-256."
60+
},
61+
"artifactChanges": [
62+
{
63+
"replacements": [
64+
{
65+
"deletedRegion": {
66+
"endColumn": 91,
67+
"endLine": 87,
68+
"startColumn": 86,
69+
"startLine": 87
70+
},
71+
"insertedContent": {
72+
"text": "\"SHA-256\""
73+
}
74+
}
75+
],
76+
"artifactLocation": {
77+
"uri": "BenchmarkJava/src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00073.java"
78+
}
79+
}
80+
]
81+
}
82+
],
83+
"level": "error",
84+
"locations": [
85+
{
86+
"physicalLocation": {
87+
"region": {
88+
"snippet": {
89+
"text": " java.security.MessageDigest md = java.security.MessageDigest.getInstance(\"MD5\");\n"
90+
},
91+
"endColumn": 91,
92+
"endLine": 87,
93+
"startColumn": 86,
94+
"startLine": 87
95+
},
96+
"artifactLocation": {
97+
"uri": "BenchmarkJava/src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00073.java"
98+
},
99+
"contextRegion": {
100+
"snippet": {
101+
"text": " try {\n java.security.MessageDigest md = java.security.MessageDigest.getInstance(\"MD5\");\n byte[] input = {(byte) '?'};\n"
102+
},
103+
"endLine": 88,
104+
"startLine": 86
105+
}
106+
}
107+
}
108+
],
109+
"ruleId": "JAV002",
110+
"ruleIndex": 0
111+
}
112+
]
113+
}
114+
],
115+
"version": "2.1.0",
116+
"$schema": "https://json.schemastore.org/sarif-2.1.0.json"
117+
}

0 commit comments

Comments
 (0)