forked from veracode/veracode-pipeline-scan-results-to-sarif
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconvert-action.js
167 lines (151 loc) · 6.29 KB
/
convert-action.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
const core = require('@actions/core');
//onst github = require('@actions/github');
const fs = require('fs');
const pipelineInputFileName = core.getInput('pipeline-results-json'); // 'results.json'
const sarifOutputFileName = core.getInput('output-results-sarif'); // 'veracode-results.sarif'
// none,note,warning,error
const sevIntToStr = (sevInt => {
const intSev = parseInt(sevInt);
if (intSev===5 || intSev===4){
return 'error';
} else if (intSev===3) {
return 'warning';
} else if (intSev===2||intSev===1 || intSev===0){
return 'note';
} else {
return 'none'
}
})
const addRuleToRules = (issue,rules) => {
if (rules.filter(ruleItem => ruleItem.id===issue.CWEId).length>0) {
return null;
}
/*
{
"id": "no-unused-vars",
"shortDescription": {
"text": "disallow unused variables"
},
"helpUri": "https://eslint.org/docs/rules/no-unused-vars",
"properties": {
"category": "Variables"
}
}
*/
let rule = {
id: issue.CWEId,
shortDescription: {
text: "CWE-"+issue.CWEId+": "+issue.IssueType
},
helpUri: "https://cwe.mitre.org/data/definitions/"+issue.CWEId+".html",
properties: {
category: issue.IssueTypeId
}
}
return rule;
}
/*
{
"Title": "java.sql.Statement.executeQuery",
"IssueId": "1016",
"GOB": "B",
"Severity": "4",
"IssueTypeId": "taint",
"IssueType": "Improper Neutralization of Special Elements used in an SQL Command (\u0027SQL Injection\u0027)",
"CWEId": "89",
"VCId": "89.005",
"DisplayText": "\u003cspan\u003eThis database query contains a SQL injection flaw. The call to java.sql.Statement.executeQuery() constructs a dynamic SQL query using a variable derived from untrusted input. An attacker could exploit this flaw to execute arbitrary SQL queries against the database. The first argument to executeQuery() contains tainted data from the variable sqlQuery. The tainted data originated from an earlier call to AnnotationVirtualController.vc_annotation_entry.\u003c/span\u003e \u003cspan\u003eAvoid dynamically constructing SQL queries. Instead, use parameterized prepared statements to prevent the database from interpreting the contents of bind variables as part of the query. Always validate untrusted input to ensure that it conforms to the expected format, using centralized data validation routines when possible.\u003c/span\u003e \u003cspan\u003eReferences: \u003ca href\u003d\"https://cwe.mitre.org/data/definitions/89.html\"\u003eCWE\u003c/a\u003e \u003ca href\u003d\"https://www.owasp.org/index.php/SQL_injection\"\u003eOWASP\u003c/a\u003e \u003ca href\u003d\"https://webappsec.pbworks.com/SQL-Injection\"\u003eWASC\u003c/a\u003e\u003c/span\u003e",
"Files": {
"SourceFile": {
"File": "com/veracode/verademo/controller/UserController.java",
"Line": "166",
"FunctionName": "processLogin",
"QualifiedFunctionName": "com.veracode.verademo.controller.UserController.processLogin",
"FunctionPrototype": "java.lang.String processLogin(java.lang.String, java.lang.String, java.lang.String, java.lang.String, org.springframework.ui.Model, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)",
"Scope": "com.veracode.verademo.controller.UserController"
}
},
"FlawMatch": {
"ProcedureHash": "844194490",
"PrototypeHash": "839857025",
"FlawHash": "3392777041",
"FlawHashCount": "1",
"FlawHashOrdinal": "1",
"CauseHash": "1176028798",
"CauseHashCount": "1",
"CauseHashOrdinal": "1"
}
},
*/
const convertPipelineResultFileToSarifFile = (inputFileName,outputFileName) => {
var results = {};
let rawdata = fs.readFileSync(inputFileName);
results = JSON.parse(rawdata);
console.log('Pipeline Scan results file found and parsed - validated JSON file');
//"scan_status": "SUCCESS"
if (results.scan_status==='SUCCESS') {
let issues = results.results.TestResults.Issues.Issue;
console.log('Issues count: '+issues.length);
let rules=[];
// convert to SARIF json
let sarifResults = issues.map(issue => {
// append rule to ruleset - if not already there
let rule = addRuleToRules(issue,rules);
if (rule!==null){
rules.push(rule);
}
// construct flaw location
let issueFileLocation = issue.Files.SourceFile;
let location = {
physicalLocation: {
artifactLocation: {
uri: issueFileLocation.File
},
region: {
startLine: parseInt(issueFileLocation.Line)
}
}
}
// get the severity number to name
let serStr = sevIntToStr(issue.Severity);
// construct the issue
let resultItem = {
level: serStr,
message: {
text: issue.DisplayText,
},
locations: [location],
ruleId: issue.CWEId
}
return resultItem;
})
// construct the full SARIF content
let sarifFileJSONContent = {
$schema : "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
version : "2.1.0",
runs : [
{
tool : {
driver : {
name : "Veracode Pipeline Scanner",
rules: rules
}
},
results: sarifResults
}
]
};
// save to file
fs.writeFileSync(outputFileName,JSON.stringify(sarifFileJSONContent));
console.log('SARIF file created: '+outputFileName);
}
}
try {
convertPipelineResultFileToSarifFile(pipelineInputFileName,sarifOutputFileName);
} catch (error) {
core.setFailed(error.message);
}
module.exports = {
sevIntToStr: sevIntToStr,
convertToSarif: convertPipelineResultFileToSarifFile
}