This repository has been archived by the owner on Oct 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add initial support for a semgrep producer * Fix formatting issues
- Loading branch information
1 parent
59b4fb2
commit a78ba3e
Showing
6 changed files
with
233 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
subinclude("@third_party/subrepos/pleasings//docker") | ||
|
||
go_binary( | ||
name = "semgrep", | ||
srcs = [ | ||
"main.go", | ||
], | ||
deps = [ | ||
"//api/proto:v1", | ||
"//producers", | ||
"//producers/semgrep/types:semgrep-issue" | ||
], | ||
) | ||
|
||
go_test( | ||
name = "semgrep_test", | ||
srcs = [ | ||
"main.go", | ||
"main_test.go", | ||
], | ||
deps = [ | ||
"//api/proto:v1", | ||
"//producers", | ||
"//third_party/go:stretchr_testify", | ||
"//producers/semgrep/types:semgrep-issue", | ||
], | ||
) | ||
|
||
docker_image( | ||
name = "image", | ||
srcs = [ | ||
":semgrep", | ||
], | ||
base_image = "//build/docker:dracon-base-go", | ||
image = "dracon-producer-semgrep", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
FROM //build/docker:dracon-base-go | ||
|
||
COPY semgrep /semgrep | ||
|
||
ENTRYPOINT ["/semgrep"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
|
||
v1 "github.com/thought-machine/dracon/api/proto/v1" | ||
types "github.com/thought-machine/dracon/producers/semgrep/types/semgrep-issue" | ||
|
||
"github.com/thought-machine/dracon/producers" | ||
) | ||
|
||
func main() { | ||
if err := producers.ParseFlags(); err != nil { | ||
log.Fatal(err) | ||
} | ||
var results types.SemgrepResults | ||
if err := producers.ParseInFileJSON(&results); err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
issues := parseIssues(results) | ||
if err := producers.WriteDraconOut( | ||
"semgrep", | ||
issues, | ||
); err != nil { | ||
log.Fatal(err) | ||
} | ||
} | ||
|
||
func parseIssues(out types.SemgrepResults) []*v1.Issue { | ||
issues := []*v1.Issue{} | ||
|
||
results := out.Results | ||
|
||
for _, r := range results { | ||
|
||
// Map the semgrep severity levels to dracon severity levels | ||
severityMap := map[string]v1.Severity{ | ||
"INFO": v1.Severity_SEVERITY_INFO, | ||
"WARNING": v1.Severity_SEVERITY_MEDIUM, | ||
"ERROR": v1.Severity_SEVERITY_HIGH, | ||
} | ||
|
||
sev := severityMap[r.Extra.Severity] | ||
|
||
issues = append(issues, &v1.Issue{ | ||
Target: fmt.Sprintf("%s:%v-%v", r.Path, r.Start.Line, r.End.Line), | ||
Type: r.Extra.Message, | ||
Title: r.CheckID, | ||
Severity: sev, | ||
Cvss: 0.0, | ||
Confidence: v1.Confidence_CONFIDENCE_MEDIUM, | ||
Description: r.Extra.Lines, | ||
}) | ||
} | ||
return issues | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package main | ||
|
||
import ( | ||
v1 "github.com/thought-machine/dracon/api/proto/v1" | ||
types "github.com/thought-machine/dracon/producers/semgrep/types/semgrep-issue" | ||
|
||
"encoding/json" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
const exampleOutput = ` | ||
{ | ||
"results": [ | ||
{ | ||
"check_id": "rules.go.xss.Go using template.HTML", | ||
"path": "/src/go/xss/template-html.go", | ||
"start": {"line": 10, "col": 11}, | ||
"end": {"line": 10, "col": 32}, | ||
"extra": { | ||
"message": "Use of this type presents a security risk: the encapsulated content should come from a trusted source, \nas it will be included verbatim in the template output.\nhttps://blogtitle.github.io/go-safe-html/\n", | ||
"metavars": {}, | ||
"metadata": {}, | ||
"severity": "WARNING", | ||
"lines": "\t\t\treturn template.HTML(revStr)" | ||
} | ||
}, | ||
{ | ||
"check_id": "rules.python.grpc.GRPC Insecure Port", | ||
"path": "/src/python/grpc/grpc_insecure_port.py", | ||
"start": {"line": 19, "col": 5}, | ||
"end": {"line": 19, "col": 68}, | ||
"extra": { | ||
"message": "The gRPC server listening port is configured insecurely, this offers no encryption and authentication.\nPlease review and ensure that this is appropriate for the communication. \n", | ||
"metavars": { | ||
"$VAR": { | ||
"start": {"line": 19, "col": 5, "offset": 389}, | ||
"end": {"line": 19, "col": 20, "offset": 404}, | ||
"abstract_content": "insecure_server", | ||
"unique_id": { | ||
"type": "id", "value": "insecure_server", | ||
"kind": "Local", "sid": 8 | ||
} | ||
} | ||
}, | ||
"metadata": {}, | ||
"severity": "WARNING", | ||
"lines": " insecure_server.add_insecure_port('[::]:{}'.format(flags.port))" | ||
} | ||
} | ||
] | ||
} | ||
` | ||
|
||
func TestParseIssues(t *testing.T) { | ||
semgrepResults := types.SemgrepResults{} | ||
err := json.Unmarshal([]byte(exampleOutput), &semgrepResults) | ||
|
||
assert.Nil(t, err) | ||
issues := parseIssues(semgrepResults) | ||
|
||
expectedIssue := &v1.Issue{ | ||
Target: "/src/go/xss/template-html.go:10-10", | ||
Type: "Use of this type presents a security risk: the encapsulated content should come from a trusted source, \nas it will be included verbatim in the template output.\nhttps://blogtitle.github.io/go-safe-html/\n", | ||
Title: "rules.go.xss.Go using template.HTML", | ||
Severity: v1.Severity_SEVERITY_MEDIUM, | ||
Cvss: 0.0, | ||
Confidence: v1.Confidence_CONFIDENCE_MEDIUM, | ||
Description: "\t\t\treturn template.HTML(revStr)", | ||
} | ||
|
||
assert.Equal(t, expectedIssue, issues[0]) | ||
|
||
expectedIssue2 := &v1.Issue{ | ||
Target: "/src/python/grpc/grpc_insecure_port.py:19-19", | ||
Type: "The gRPC server listening port is configured insecurely, this offers no encryption and authentication.\nPlease review and ensure that this is appropriate for the communication. \n", | ||
Title: "rules.python.grpc.GRPC Insecure Port", | ||
Severity: v1.Severity_SEVERITY_MEDIUM, | ||
Cvss: 0.0, | ||
Confidence: v1.Confidence_CONFIDENCE_MEDIUM, | ||
Description: " insecure_server.add_insecure_port('[::]:{}'.format(flags.port))", | ||
} | ||
|
||
assert.Equal(t, expectedIssue2, issues[1]) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
go_library( | ||
name = "semgrep-issue", | ||
srcs = [ | ||
"semgrep-issue.go", | ||
], | ||
visibility = ["//producers/semgrep/..."] | ||
|
||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package types | ||
|
||
// Position represents where in the file the finding is located | ||
type Position struct { | ||
Col int `json:"col"` | ||
Line int `json:"line"` | ||
} | ||
|
||
// Extra contains extra info needed for semgrep issue | ||
type Extra struct { | ||
Message string `json:"message"` | ||
Metavars Metavars `json:"metavars"` | ||
Metadata Metadata `json:"metadata"` | ||
Severity string `json:"severity"` | ||
Lines string `json:"lines"` | ||
} | ||
|
||
// SemgrepIssue represents a semgrep issue | ||
type SemgrepIssue struct { | ||
CheckID string `json:"check_id"` | ||
Path string `json:"path"` | ||
Start Position `json:"start"` | ||
End Position `json:"end"` | ||
Extra Extra `json:"extra"` | ||
} | ||
|
||
// SemgrepResults represents a series of semgrep issues | ||
type SemgrepResults struct { | ||
Results []SemgrepIssue `'json:"results"` | ||
} | ||
|
||
// Metavars currently is empty but could represent more metavariables for semgrep | ||
type Metavars struct { | ||
} | ||
|
||
// Metadata currently is empty, however, could represent semgrep issue metadata going forward. | ||
type Metadata struct { | ||
} |