Skip to content

Commit 027361f

Browse files
authored
[PLUTO-1411] add Semgrep test (#109)
1 parent 9e54953 commit 027361f

File tree

5 files changed

+175
-19
lines changed

5 files changed

+175
-19
lines changed

.github/workflows/it-test.yml

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
name: Pylint plugin test
1+
name: plugin it-test
22

33
permissions:
44
contents: write
55

66
on:
77
push:
8-
paths:
9-
- 'plugins/tools/pylint/**'
10-
118

129
jobs:
1310
test:
@@ -27,19 +24,32 @@ jobs:
2724
go build -o cli-v2 ./cli-v2.go
2825
chmod +x cli-v2
2926
30-
- name: Run Pylint plugin tests
27+
- name: Run plugin tests
3128
run: |
32-
# Store the path to the CLI
33-
CLI_PATH="$(pwd)/cli-v2"
34-
# Change to test directory
35-
cd plugins/tools/pylint/test/src
36-
# Install the plugin
37-
"$CLI_PATH" install
38-
# Run analysis
39-
"$CLI_PATH" analyze --tool pylint --format sarif --output actual.sarif
40-
# Convert absolute paths to relative paths in the output
41-
sed -i 's|file:///home/runner/work/codacy-cli-v2/codacy-cli-v2/|file:///|g' actual.sarif
42-
# Compare with expected output
43-
jq --sort-keys . expected.sarif > expected.sorted.json
44-
jq --sort-keys . actual.sarif > actual.sorted.json
45-
diff expected.sorted.json actual.sorted.json
29+
run_test() {
30+
local tool=$1
31+
local jq_filter=$2
32+
echo "Running $tool tests..."
33+
# Store the path to the CLI
34+
CLI_PATH="$(pwd)/cli-v2"
35+
# Change to test directory
36+
cd plugins/tools/$tool/test/src
37+
# Install the plugin
38+
"$CLI_PATH" install
39+
# Run analysis
40+
"$CLI_PATH" analyze --tool $tool --format sarif --output actual.sarif
41+
# Convert absolute paths to relative paths in the output
42+
sed -i 's|file:///home/runner/work/codacy-cli-v2/codacy-cli-v2/|file:///|g' actual.sarif
43+
# Compare with expected output
44+
jq --sort-keys "$jq_filter" expected.sarif > expected.sorted.json
45+
jq --sort-keys "$jq_filter" actual.sarif > actual.sorted.json
46+
diff expected.sorted.json actual.sorted.json
47+
# Go back to root directory
48+
cd ../../../../..
49+
}
50+
51+
# Run Pylint tests with simple sorting
52+
run_test "pylint" "."
53+
54+
# Run Semgrep tests with rules sorting
55+
run_test "semgrep" ".runs[0].tool.driver.rules |= if . then sort_by(.id) else . end"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
runtimes:
2+
3+
tools:
4+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
rules:
2+
- id: python.requests.security.no-http-url
3+
pattern: requests.get("http://...")
4+
message: "Insecure HTTP URL in requests.get()"
5+
severity: WARNING
6+
languages: [python]
7+
8+
- id: python.cryptography.bad-cryptography
9+
pattern: |
10+
from cryptography.fernet import Fernet
11+
key = Fernet.generate_key()
12+
f = Fernet(key)
13+
message: "Using Fernet for encryption without proper key management"
14+
severity: WARNING
15+
languages: [python]
16+
17+
- id: python.security.audit.avoid-assert
18+
pattern: assert $X
19+
message: "Use of assert statement in production code"
20+
severity: WARNING
21+
languages: [python]
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
{
2+
"version": "2.1.0",
3+
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
4+
"runs": [
5+
{
6+
"invocations": [
7+
{
8+
"executionSuccessful": true,
9+
"toolExecutionNotifications": []
10+
}
11+
],
12+
"results": [],
13+
"tool": {
14+
"driver": {
15+
"name": "Semgrep OSS",
16+
"rules": [
17+
{
18+
"defaultConfiguration": {
19+
"level": "warning"
20+
},
21+
"fullDescription": {
22+
"text": "Insecure HTTP URL in requests.get()"
23+
},
24+
"help": {
25+
"markdown": "Insecure HTTP URL in requests.get()",
26+
"text": "Insecure HTTP URL in requests.get()"
27+
},
28+
"id": "codacy.tools-configs.python.requests.security.no-http-url",
29+
"name": "codacy.tools-configs.python.requests.security.no-http-url",
30+
"properties": {
31+
"precision": "very-high",
32+
"tags": []
33+
},
34+
"shortDescription": {
35+
"text": "Semgrep Finding: codacy.tools-configs.python.requests.security.no-http-url"
36+
}
37+
},
38+
{
39+
"defaultConfiguration": {
40+
"level": "warning"
41+
},
42+
"fullDescription": {
43+
"text": "Use of assert statement in production code"
44+
},
45+
"help": {
46+
"markdown": "Use of assert statement in production code",
47+
"text": "Use of assert statement in production code"
48+
},
49+
"id": "codacy.tools-configs.python.security.audit.avoid-assert",
50+
"name": "codacy.tools-configs.python.security.audit.avoid-assert",
51+
"properties": {
52+
"precision": "very-high",
53+
"tags": []
54+
},
55+
"shortDescription": {
56+
"text": "Semgrep Finding: codacy.tools-configs.python.security.audit.avoid-assert"
57+
}
58+
},
59+
{
60+
"defaultConfiguration": {
61+
"level": "warning"
62+
},
63+
"fullDescription": {
64+
"text": "Using Fernet for encryption without proper key management"
65+
},
66+
"help": {
67+
"markdown": "Using Fernet for encryption without proper key management",
68+
"text": "Using Fernet for encryption without proper key management"
69+
},
70+
"id": "codacy.tools-configs.python.cryptography.bad-cryptography",
71+
"name": "codacy.tools-configs.python.cryptography.bad-cryptography",
72+
"properties": {
73+
"precision": "very-high",
74+
"tags": []
75+
},
76+
"shortDescription": {
77+
"text": "Semgrep Finding: codacy.tools-configs.python.cryptography.bad-cryptography"
78+
}
79+
}
80+
],
81+
"semanticVersion": "1.78.0"
82+
}
83+
}
84+
}
85+
]
86+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
Test file for semgrep analysis
6+
"""
7+
8+
import os
9+
import sys
10+
import subprocess
11+
12+
def unsafe_command_execution():
13+
"""Function with unsafe command execution"""
14+
user_input = "ls -la"
15+
os.system(user_input) # semgrep: python.lang.security.audit.subprocess-shell-true.subprocess-shell-true
16+
subprocess.run(user_input, shell=True) # semgrep: python.lang.security.audit.subprocess-shell-true.subprocess-shell-true
17+
18+
def hardcoded_password():
19+
"""Function with hardcoded password"""
20+
password = "mysecretpassword123" # semgrep: python.lang.security.audit.hardcoded-password.hardcoded-password
21+
return password
22+
23+
def unsafe_deserialization():
24+
"""Function with unsafe deserialization"""
25+
import pickle
26+
data = b"cos\nsystem\n(S'ls -la'\ntR."
27+
pickle.loads(data) # semgrep: python.lang.security.audit.pickle.avoid-pickle
28+
29+
def main():
30+
unsafe_command_execution()
31+
hardcoded_password()
32+
unsafe_deserialization()
33+
34+
if __name__ == "__main__":
35+
main()

0 commit comments

Comments
 (0)