Skip to content

Commit

Permalink
Relax the SarifReader tool name matching logic to use startswith inst…
Browse files Browse the repository at this point in the history
…ead of equals so versions of the same tool will match. For example, Semgrep OSS and Semgrep PRO use the same file format but their names are slightly different. So now the SemgrepSarifReader class names the tool simply 'Semgrep' and SarifReader uses startswith() so both versions of the same tool match with one reader. And added a test case to test this.
  • Loading branch information
davewichers committed Aug 7, 2024
1 parent 4c17896 commit 072a679
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public SarifReader(String expectedToolName, boolean isCommercial, CweSourceType
@Override
public boolean canRead(ResultFile resultFile) {
try {
return resultFile.isJson() && sarifToolName(resultFile).equals(expectedToolName);
return resultFile.isJson() && sarifToolName(resultFile).startsWith(expectedToolName);
} catch (Exception e) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
public class SemgrepSarifReader extends SarifReader {

public SemgrepSarifReader() {
super("Semgrep OSS", false, CweSourceType.TAG);
super("Semgrep", false, CweSourceType.TAG);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,25 @@

class SemgrepSarifReaderTest extends ReaderTestBase {

private ResultFile resultFile;
private ResultFile resultFileOSS, resultFilePRO;

@BeforeEach
void setUp() {
resultFile = TestHelper.resultFileOf("testfiles/Benchmark_semgrep-v1.67.0.sarif");
resultFileOSS = TestHelper.resultFileOf("testfiles/Benchmark_semgrep-oss-v1.67.0.sarif");
resultFilePRO = TestHelper.resultFileOf("testfiles/Benchmark_semgrep-pro-v1.68.1.sarif");
BenchmarkScore.TESTCASENAME = "BenchmarkTest";
}

@Test
public void onlySemgrepSarifReaderReportsCanReadAsTrue() {
assertOnlyMatcherClassIs(this.resultFile, SemgrepSarifReader.class);
assertOnlyMatcherClassIs(this.resultFileOSS, SemgrepSarifReader.class);
assertOnlyMatcherClassIs(this.resultFilePRO, SemgrepSarifReader.class);
}

@Test
void readerHandlesGivenResultFile() throws Exception {
void readerHandlesSemgrepOSSResultFile() throws Exception {
SemgrepSarifReader reader = new SemgrepSarifReader();
TestSuiteResults result = reader.parse(resultFile);
TestSuiteResults result = reader.parse(resultFileOSS);

assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType());
assertFalse(result.isCommercial());
Expand All @@ -59,4 +61,20 @@ void readerHandlesGivenResultFile() throws Exception {
assertEquals(CweNumber.COOKIE_WITHOUT_HTTPONLY, result.get(1).get(0).getCWE());
assertEquals(CweNumber.XSS, result.get(2).get(0).getCWE());
}

@Test
void readerHandlesSemgrepPROResultFile() throws Exception {
SemgrepSarifReader reader = new SemgrepSarifReader();
TestSuiteResults result = reader.parse(resultFilePRO);

assertEquals(TestSuiteResults.ToolType.SAST, result.getToolType());
assertFalse(result.isCommercial());
assertEquals("Semgrep PRO", result.getToolName());
assertEquals("1.68.1", result.getToolVersion());

assertEquals(2, result.getTotalResults());

assertEquals(CweNumber.COOKIE_WITHOUT_HTTPONLY, result.get(1).get(0).getCWE());
assertEquals(CweNumber.XSS, result.get(2).get(0).getCWE());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
{
"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json",
"runs": [
{
"results": [
{
"fingerprints": {
"matchBasedId/v1": "1"
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00001.java",
"uriBaseId": "%SRCROOT%"
},
"region": {
"endColumn": 40,
"endLine": 42,
"snippet": {
"text": " response.addCookie(userCookie);"
},
"startColumn": 9,
"startLine": 42
}
}
}
],
"message": {
"text": "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);'"
},
"properties": {},
"ruleId": "java.lang.security.audit.cookie-missing-httponly.cookie-missing-httponly"
},
{
"fingerprints": {
"matchBasedId/v1": "1"
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00002.java",
"uriBaseId": "%SRCROOT%"
},
"region": {
"endColumn": 77,
"endLine": 73,
"snippet": {
"text": " response.getWriter()\n .println(\n \"Item: '\"\n + org.owasp.benchmark.helpers.Utils.encodeForHTML(param)\n + \"' with value: '10340' saved in session.\");"
},
"startColumn": 9,
"startLine": 69
}
}
}
],
"message": {
"text": "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."
},
"properties": {},
"ruleId": "java.lang.security.audit.xss.no-direct-response-writer.no-direct-response-writer"
}
],
"tool": {
"driver": {
"name": "Semgrep PRO",
"rules": [
{
"defaultConfiguration": {
"level": "warning"
},
"fullDescription": {
"text": "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);'"
},
"help": {
"markdown": "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);'\n\n#### \ud83d\udc8e Enable cross-file analysis and Pro rules for free at <a href='https://sg.run/pro'>sg.run/pro</a>\n\n<b>References:</b>\n - [Semgrep Rule](https://semgrep.dev/r/java.lang.security.audit.cookie-missing-httponly.cookie-missing-httponly)\n - [https://owasp.org/Top10/A05_2021-Security_Misconfiguration](https://owasp.org/Top10/A05_2021-Security_Misconfiguration)\n",
"text": "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);'\n\ud83d\udc8e Enable cross-file analysis and Pro rules for free at sg.run/pro"
},
"helpUri": "https://semgrep.dev/r/java.lang.security.audit.cookie-missing-httponly.cookie-missing-httponly",
"id": "java.lang.security.audit.cookie-missing-httponly.cookie-missing-httponly",
"name": "java.lang.security.audit.cookie-missing-httponly.cookie-missing-httponly",
"properties": {
"precision": "very-high",
"tags": [
"CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag",
"LOW CONFIDENCE",
"OWASP-A05:2021 - Security Misconfiguration",
"security"
]
},
"shortDescription": {
"text": "Semgrep Finding: java.lang.security.audit.cookie-missing-httponly.cookie-missing-httponly"
}
},
{
"defaultConfiguration": {
"level": "warning"
},
"fullDescription": {
"text": "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."
},
"help": {
"markdown": "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.\n\n#### \ud83d\udc8e Enable cross-file analysis and Pro rules for free at <a href='https://sg.run/pro'>sg.run/pro</a>\n\n<b>References:</b>\n - [Semgrep Rule](https://semgrep.dev/r/java.lang.security.audit.xss.no-direct-response-writer.no-direct-response-writer)\n - [https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaServerFaces.html](https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaServerFaces.html)\n",
"text": "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.\n\ud83d\udc8e Enable cross-file analysis and Pro rules for free at sg.run/pro"
},
"helpUri": "https://semgrep.dev/r/java.lang.security.audit.xss.no-direct-response-writer.no-direct-response-writer",
"id": "java.lang.security.audit.xss.no-direct-response-writer.no-direct-response-writer",
"name": "java.lang.security.audit.xss.no-direct-response-writer.no-direct-response-writer",
"properties": {
"precision": "very-high",
"tags": [
"CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')",
"MEDIUM CONFIDENCE",
"OWASP-A03:2021 - Injection",
"OWASP-A07:2017 - Cross-Site Scripting (XSS)",
"security"
]
},
"shortDescription": {
"text": "Semgrep Finding: java.lang.security.audit.xss.no-direct-response-writer.no-direct-response-writer"
}
}
],
"semanticVersion": "1.68.1"
}
}
}
],
"version": "2.1.0"
}

0 comments on commit 072a679

Please sign in to comment.