Skip to content

Commit e6f4d8c

Browse files
author
sg
committed
close feature 405, modelscan component
1 parent 2f08d25 commit e6f4d8c

File tree

5 files changed

+367
-0
lines changed

5 files changed

+367
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"modelscan_version": "0.5.0",
3+
"timestamp": "2024-01-25T17:56:00.855056",
4+
"input_path": "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
5+
"total_issues": 1,
6+
"summary": {
7+
"total_issues_by_severity": {
8+
"LOW": 0,
9+
"MEDIUM": 0,
10+
"HIGH": 0,
11+
"CRITICAL": 1
12+
}
13+
},
14+
"issues_by_severity": {
15+
"CRITICAL": [
16+
{
17+
"description": "Use of unsafe operator 'system' from module 'posix'",
18+
"operator": "system",
19+
"module": "posix",
20+
"source": "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
21+
"scanner": "modelscan.scanners.PickleUnsafeOpScan"
22+
}
23+
],
24+
"MEDIUM": [
25+
{
26+
"description": "Use of unsafe operator 'system' from module 'posix'",
27+
"operator": "system",
28+
"module": "posix",
29+
"source": "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
30+
"scanner": "modelscan.scanners.PickleUnsafeOpScan"
31+
}
32+
],
33+
"HIGH": [
34+
{
35+
"description": "Use of unsafe operator 'system' from module 'posix'",
36+
"operator": "system",
37+
"module": "posix",
38+
"source": "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
39+
"scanner": "modelscan.scanners.PickleUnsafeOpScan"
40+
}
41+
],
42+
"LOW": [
43+
{
44+
"description": "Use of unsafe operator 'system' from module 'posix'",
45+
"operator": "system",
46+
"module": "posix",
47+
"source": "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
48+
"scanner": "modelscan.scanners.PickleUnsafeOpScan"
49+
}
50+
]
51+
},
52+
"errors": [],
53+
"scanned": {
54+
"total_scanned": 4,
55+
"scanned_files": [
56+
"/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl"
57+
]
58+
}
59+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
 �͙�햞�gosec�
3+
O/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl%modelscan.scanners.PickleUnsafeOpScan3Use of unsafe operator 'system' from module 'posix':3Use of unsafe operator 'system' from module 'posix'Bunknown�
4+
O/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl%modelscan.scanners.PickleUnsafeOpScan3Use of unsafe operator 'system' from module 'posix':3Use of unsafe operator 'system' from module 'posix'Bunknown�
5+
O/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl%modelscan.scanners.PickleUnsafeOpScan3Use of unsafe operator 'system' from module 'posix':3Use of unsafe operator 'system' from module 'posix'Bunknown�
6+
O/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl%modelscan.scanners.PickleUnsafeOpScan3Use of unsafe operator 'system' from module 'posix':3Use of unsafe operator 'system' from module 'posix'Bunknown
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"log"
6+
7+
v1 "github.com/ocurity/dracon/api/proto/v1"
8+
9+
"github.com/ocurity/dracon/components/producers"
10+
)
11+
12+
func main() {
13+
if err := producers.ParseFlags(); err != nil {
14+
log.Fatal(err)
15+
}
16+
17+
inFile, err := producers.ReadInFile()
18+
if err != nil {
19+
log.Fatal(err)
20+
}
21+
22+
var results ModelScanOut
23+
if err := json.Unmarshal(inFile, &results); err != nil {
24+
log.Fatal(err)
25+
}
26+
27+
issues, err := parseIssues(&results)
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
if err := producers.WriteDraconOut(
32+
"modelscan",
33+
issues,
34+
); err != nil {
35+
log.Fatal(err)
36+
}
37+
}
38+
39+
func parseIssues(out *ModelScanOut) ([]*v1.Issue, error) {
40+
issues := []*v1.Issue{}
41+
for _, crit := range out.IssuesBySeverity.Critical {
42+
issues = append(issues,
43+
&v1.Issue{
44+
Target: crit.Source,
45+
Type: crit.Scanner,
46+
Description: crit.Description,
47+
Title: crit.Description,
48+
Severity: v1.Severity_SEVERITY_UNSPECIFIED,
49+
Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED,
50+
})
51+
}
52+
for _, crit := range out.IssuesBySeverity.High {
53+
issues = append(issues,
54+
&v1.Issue{
55+
Target: crit.Source,
56+
Type: crit.Scanner,
57+
Description: crit.Description,
58+
Title: crit.Description,
59+
Severity: v1.Severity_SEVERITY_UNSPECIFIED,
60+
Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED,
61+
})
62+
}
63+
for _, crit := range out.IssuesBySeverity.Medium {
64+
issues = append(issues,
65+
&v1.Issue{
66+
Target: crit.Source,
67+
Type: crit.Scanner,
68+
Description: crit.Description,
69+
Title: crit.Description,
70+
Severity: v1.Severity_SEVERITY_UNSPECIFIED,
71+
Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED,
72+
})
73+
}
74+
for _, crit := range out.IssuesBySeverity.Low {
75+
issues = append(issues,
76+
&v1.Issue{
77+
Target: crit.Source,
78+
Type: crit.Scanner,
79+
Description: crit.Description,
80+
Title: crit.Description,
81+
Severity: v1.Severity_SEVERITY_UNSPECIFIED,
82+
Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED,
83+
})
84+
}
85+
return issues, nil
86+
}
87+
88+
type ModelScanOut struct {
89+
ModelscanVersion string `json:"modelscan_version"`
90+
Timestamp string `json:"timestamp"`
91+
InputPath string `json:"input_path"`
92+
TotalIssues int `json:"total_issues"`
93+
Summary struct {
94+
TotalIssuesBySeverity struct {
95+
Low int `json:"LOW"`
96+
Medium int `json:"MEDIUM"`
97+
High int `json:"HIGH"`
98+
Critical int `json:"CRITICAL"`
99+
} `json:"total_issues_by_severity"`
100+
} `json:"summary"`
101+
IssuesBySeverity struct {
102+
Critical []struct {
103+
Description string `json:"description"`
104+
Operator string `json:"operator"`
105+
Module string `json:"module"`
106+
Source string `json:"source"`
107+
Scanner string `json:"scanner"`
108+
} `json:"CRITICAL"`
109+
High []struct {
110+
Description string `json:"description"`
111+
Operator string `json:"operator"`
112+
Module string `json:"module"`
113+
Source string `json:"source"`
114+
Scanner string `json:"scanner"`
115+
} `json:"HIGH"`
116+
Medium []struct {
117+
Description string `json:"description"`
118+
Operator string `json:"operator"`
119+
Module string `json:"module"`
120+
Source string `json:"source"`
121+
Scanner string `json:"scanner"`
122+
} `json:"MEDIUM"`
123+
Low []struct {
124+
Description string `json:"description"`
125+
Operator string `json:"operator"`
126+
Module string `json:"module"`
127+
Source string `json:"source"`
128+
Scanner string `json:"scanner"`
129+
} `json:"LOW"`
130+
} `json:"issues_by_severity"`
131+
Errors []any `json:"errors"`
132+
Scanned struct {
133+
TotalScanned int `json:"total_scanned"`
134+
ScannedFiles []string `json:"scanned_files"`
135+
} `json:"scanned"`
136+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
v1 "github.com/ocurity/dracon/api/proto/v1"
8+
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestParseIssues(t *testing.T) {
13+
var results ModelScanOut
14+
err := json.Unmarshal([]byte(modelScanOut), &results)
15+
require.NoError(t, err)
16+
17+
issues, err := parseIssues(&results)
18+
require.NoError(t, err)
19+
expectedIssue := []*v1.Issue{
20+
21+
{
22+
Target: "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
23+
Type: "modelscan.scanners.PickleUnsafeOpScan",
24+
Title: "Use of unsafe operator 'system' from module 'posix'",
25+
Description: "Use of unsafe operator 'system' from module 'posix'",
26+
},
27+
{
28+
Target: "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
29+
Type: "modelscan.scanners.PickleUnsafeOpScan",
30+
Title: "Use of unsafe operator 'system' from module 'posix'",
31+
Description: "Use of unsafe operator 'system' from module 'posix'",
32+
},
33+
{
34+
Target: "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
35+
Type: "modelscan.scanners.PickleUnsafeOpScan",
36+
Title: "Use of unsafe operator 'system' from module 'posix'",
37+
Description: "Use of unsafe operator 'system' from module 'posix'",
38+
},
39+
{
40+
Target: "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
41+
Type: "modelscan.scanners.PickleUnsafeOpScan",
42+
Title: "Use of unsafe operator 'system' from module 'posix'",
43+
Description: "Use of unsafe operator 'system' from module 'posix'",
44+
},
45+
}
46+
47+
require.Equal(t, expectedIssue, issues)
48+
}
49+
50+
const modelScanOut = `{
51+
"modelscan_version": "0.5.0",
52+
"timestamp": "2024-01-25T17:56:00.855056",
53+
"input_path": "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
54+
"total_issues": 1,
55+
"summary": {
56+
"total_issues_by_severity": {
57+
"LOW": 0,
58+
"MEDIUM": 0,
59+
"HIGH": 0,
60+
"CRITICAL": 1
61+
}
62+
},
63+
"issues_by_severity": {
64+
"CRITICAL": [
65+
{
66+
"description": "Use of unsafe operator 'system' from module 'posix'",
67+
"operator": "system",
68+
"module": "posix",
69+
"source": "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
70+
"scanner": "modelscan.scanners.PickleUnsafeOpScan"
71+
}
72+
],
73+
"MEDIUM": [
74+
{
75+
"description": "Use of unsafe operator 'system' from module 'posix'",
76+
"operator": "system",
77+
"module": "posix",
78+
"source": "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
79+
"scanner": "modelscan.scanners.PickleUnsafeOpScan"
80+
}
81+
],
82+
"HIGH": [
83+
{
84+
"description": "Use of unsafe operator 'system' from module 'posix'",
85+
"operator": "system",
86+
"module": "posix",
87+
"source": "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
88+
"scanner": "modelscan.scanners.PickleUnsafeOpScan"
89+
}
90+
],
91+
"LOW": [
92+
{
93+
"description": "Use of unsafe operator 'system' from module 'posix'",
94+
"operator": "system",
95+
"module": "posix",
96+
"source": "/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl",
97+
"scanner": "modelscan.scanners.PickleUnsafeOpScan"
98+
}
99+
]
100+
},
101+
"errors": [],
102+
"scanned": {
103+
"total_scanned": 4,
104+
"scanned_files": [
105+
"/Users/mehrinkiani/Documents/modelscan/notebooks/XGBoostModels/unsafe_model.pkl"
106+
]
107+
}
108+
}
109+
`
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
apiVersion: tekton.dev/v1beta1
3+
kind: Task
4+
metadata:
5+
name: producer-modelscan
6+
labels:
7+
v1.dracon.ocurity.com/component: producer
8+
v1.dracon.ocurity.com/test-type: sast
9+
v1.dracon.ocurity.com/language: python
10+
spec:
11+
description: Analyse Go source code to look for security issues.
12+
params:
13+
- name: producer-modelscan-relative-path-to-model
14+
type: string
15+
volumes:
16+
- name: scratch
17+
emptyDir: {}
18+
workspaces:
19+
- name: output
20+
description: The workspace containing the source-code to scan.
21+
steps:
22+
- name: run-modelscan
23+
image: python:alpine
24+
script: |
25+
pip install 'modelscan[ tensorflow, h5py ]'
26+
modelscan \
27+
--path "$(workspaces.output.path)/source-code/$(params.producer-modelscan-relative-path-to-model)" \
28+
--reporting-format json \
29+
--output-file /scratch/out.json
30+
31+
exitCode=$?
32+
if [[ $exitCode -eq 1 ]]; then
33+
echo "ModelScan found vulnerabilities"
34+
exit 0
35+
else if [[ $exitCode -eq 2 ]]; then
36+
echo "ModelScan failed, error while scanning"
37+
exit $exitCode
38+
else if [[ $exitCode -eq 3 ]]; then
39+
echo "ModelScan did not find any supported files while scanning"
40+
exit $exitCode
41+
else if [[ $exitCode -eq 4 ]]; then
42+
echo "ModelScan encountered an error whle parsing CLI variables, the task definition has a bug"
43+
exit $exitCode
44+
fi
45+
volumeMounts:
46+
- mountPath: /scratch
47+
name: scratch
48+
- name: produce-issues
49+
imagePullPolicy: IfNotPresent
50+
image: '{{ default "ghcr.io/ocurity/dracon" .Values.image.registry }}/components/producers/modelscan:{{ .Chart.AppVersion }}'
51+
command: ["/app/components/producers/modelscan/modelscan-parser"]
52+
args:
53+
- "-in=/scratch/out.json"
54+
- "-out=$(workspaces.output.path)/.dracon/producers/modelscan.pb"
55+
volumeMounts:
56+
- mountPath: /scratch
57+
name: scratch

0 commit comments

Comments
 (0)