acidtest 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +104 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +170 -0
- package/dist/index.js.map +1 -0
- package/dist/layers/code.d.ts +10 -0
- package/dist/layers/code.d.ts.map +1 -0
- package/dist/layers/code.js +196 -0
- package/dist/layers/code.js.map +1 -0
- package/dist/layers/crossref.d.ts +10 -0
- package/dist/layers/crossref.d.ts.map +1 -0
- package/dist/layers/crossref.js +143 -0
- package/dist/layers/crossref.js.map +1 -0
- package/dist/layers/injection.d.ts +10 -0
- package/dist/layers/injection.d.ts.map +1 -0
- package/dist/layers/injection.js +88 -0
- package/dist/layers/injection.js.map +1 -0
- package/dist/layers/permissions.d.ts +10 -0
- package/dist/layers/permissions.d.ts.map +1 -0
- package/dist/layers/permissions.js +120 -0
- package/dist/layers/permissions.js.map +1 -0
- package/dist/pattern-loader.d.ts +14 -0
- package/dist/pattern-loader.d.ts.map +1 -0
- package/dist/pattern-loader.js +50 -0
- package/dist/pattern-loader.js.map +1 -0
- package/dist/patterns/credential-patterns.json +77 -0
- package/dist/patterns/dangerous-imports.json +113 -0
- package/dist/patterns/exfiltration-sinks.json +77 -0
- package/dist/patterns/obfuscation.json +65 -0
- package/dist/patterns/prompt-injection.json +125 -0
- package/dist/patterns/sensitive-paths.json +89 -0
- package/dist/reporter.d.ts +14 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +175 -0
- package/dist/reporter.js.map +1 -0
- package/dist/scanner.d.ts +15 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +176 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scoring.d.ts +23 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +85 -0
- package/dist/scoring.js.map +1 -0
- package/dist/types.d.ts +112 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
{
|
|
2
|
+
"category": "dangerous-imports",
|
|
3
|
+
"patterns": [
|
|
4
|
+
{
|
|
5
|
+
"id": "di-001",
|
|
6
|
+
"name": "child-process-import",
|
|
7
|
+
"description": "Imports child_process module for command execution",
|
|
8
|
+
"severity": "CRITICAL",
|
|
9
|
+
"match": {
|
|
10
|
+
"type": "regex",
|
|
11
|
+
"value": "(import|require)\\s*\\(?['\"]child_process['\"]",
|
|
12
|
+
"flags": "g"
|
|
13
|
+
},
|
|
14
|
+
"layer": "code"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "di-002",
|
|
18
|
+
"name": "eval-usage",
|
|
19
|
+
"description": "Uses eval() function",
|
|
20
|
+
"severity": "CRITICAL",
|
|
21
|
+
"match": {
|
|
22
|
+
"type": "regex",
|
|
23
|
+
"value": "\\beval\\s*\\(",
|
|
24
|
+
"flags": "g"
|
|
25
|
+
},
|
|
26
|
+
"layer": "code"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "di-003",
|
|
30
|
+
"name": "function-constructor",
|
|
31
|
+
"description": "Uses Function constructor for dynamic code execution",
|
|
32
|
+
"severity": "CRITICAL",
|
|
33
|
+
"match": {
|
|
34
|
+
"type": "regex",
|
|
35
|
+
"value": "new\\s+Function\\s*\\(",
|
|
36
|
+
"flags": "g"
|
|
37
|
+
},
|
|
38
|
+
"layer": "code"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "di-004",
|
|
42
|
+
"name": "vm-module",
|
|
43
|
+
"description": "Imports vm module for code execution",
|
|
44
|
+
"severity": "CRITICAL",
|
|
45
|
+
"match": {
|
|
46
|
+
"type": "regex",
|
|
47
|
+
"value": "(import|require)\\s*\\(?['\"]vm['\"]",
|
|
48
|
+
"flags": "g"
|
|
49
|
+
},
|
|
50
|
+
"layer": "code"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "di-005",
|
|
54
|
+
"name": "net-socket-access",
|
|
55
|
+
"description": "Imports net module for raw socket access",
|
|
56
|
+
"severity": "HIGH",
|
|
57
|
+
"match": {
|
|
58
|
+
"type": "regex",
|
|
59
|
+
"value": "(import|require)\\s*\\(?['\"]net['\"]",
|
|
60
|
+
"flags": "g"
|
|
61
|
+
},
|
|
62
|
+
"layer": "code"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "di-006",
|
|
66
|
+
"name": "dgram-socket-access",
|
|
67
|
+
"description": "Imports dgram module for UDP socket access",
|
|
68
|
+
"severity": "HIGH",
|
|
69
|
+
"match": {
|
|
70
|
+
"type": "regex",
|
|
71
|
+
"value": "(import|require)\\s*\\(?['\"]dgram['\"]",
|
|
72
|
+
"flags": "g"
|
|
73
|
+
},
|
|
74
|
+
"layer": "code"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "di-007",
|
|
78
|
+
"name": "fs-unlink",
|
|
79
|
+
"description": "Uses file deletion functions",
|
|
80
|
+
"severity": "HIGH",
|
|
81
|
+
"match": {
|
|
82
|
+
"type": "regex",
|
|
83
|
+
"value": "\\.(unlink|unlinkSync|rmdir|rmdirSync|rm)\\s*\\(",
|
|
84
|
+
"flags": "g"
|
|
85
|
+
},
|
|
86
|
+
"layer": "code"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "di-008",
|
|
90
|
+
"name": "dynamic-require",
|
|
91
|
+
"description": "Uses require() with dynamic arguments",
|
|
92
|
+
"severity": "HIGH",
|
|
93
|
+
"match": {
|
|
94
|
+
"type": "regex",
|
|
95
|
+
"value": "require\\s*\\([^'\"]",
|
|
96
|
+
"flags": "g"
|
|
97
|
+
},
|
|
98
|
+
"layer": "code"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "di-009",
|
|
102
|
+
"name": "dynamic-import",
|
|
103
|
+
"description": "Uses import() with variable arguments",
|
|
104
|
+
"severity": "MEDIUM",
|
|
105
|
+
"match": {
|
|
106
|
+
"type": "regex",
|
|
107
|
+
"value": "import\\s*\\([^'\"]",
|
|
108
|
+
"flags": "g"
|
|
109
|
+
},
|
|
110
|
+
"layer": "code"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"category": "exfiltration-sinks",
|
|
3
|
+
"patterns": [
|
|
4
|
+
{
|
|
5
|
+
"id": "ex-001",
|
|
6
|
+
"name": "fetch-call",
|
|
7
|
+
"description": "Makes HTTP requests with fetch",
|
|
8
|
+
"severity": "MEDIUM",
|
|
9
|
+
"match": {
|
|
10
|
+
"type": "regex",
|
|
11
|
+
"value": "\\bfetch\\s*\\(",
|
|
12
|
+
"flags": "g"
|
|
13
|
+
},
|
|
14
|
+
"layer": "code"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "ex-002",
|
|
18
|
+
"name": "http-request",
|
|
19
|
+
"description": "Makes HTTP requests",
|
|
20
|
+
"severity": "MEDIUM",
|
|
21
|
+
"match": {
|
|
22
|
+
"type": "regex",
|
|
23
|
+
"value": "(http|https)\\.(request|get|post)",
|
|
24
|
+
"flags": "g"
|
|
25
|
+
},
|
|
26
|
+
"layer": "code"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "ex-003",
|
|
30
|
+
"name": "axios-import",
|
|
31
|
+
"description": "Imports axios for HTTP requests",
|
|
32
|
+
"severity": "MEDIUM",
|
|
33
|
+
"match": {
|
|
34
|
+
"type": "regex",
|
|
35
|
+
"value": "(import|require)\\s*\\(?['\"]axios['\"]",
|
|
36
|
+
"flags": "g"
|
|
37
|
+
},
|
|
38
|
+
"layer": "code"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "ex-004",
|
|
42
|
+
"name": "websocket-connection",
|
|
43
|
+
"description": "Creates WebSocket connections",
|
|
44
|
+
"severity": "HIGH",
|
|
45
|
+
"match": {
|
|
46
|
+
"type": "regex",
|
|
47
|
+
"value": "new\\s+WebSocket\\s*\\(",
|
|
48
|
+
"flags": "g"
|
|
49
|
+
},
|
|
50
|
+
"layer": "code"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "ex-005",
|
|
54
|
+
"name": "send-to-url",
|
|
55
|
+
"description": "Instructions to send data to URL",
|
|
56
|
+
"severity": "CRITICAL",
|
|
57
|
+
"match": {
|
|
58
|
+
"type": "regex",
|
|
59
|
+
"value": "(send|post|upload|exfiltrate)\\s+(to|data)\\s+https?:\\/\\/",
|
|
60
|
+
"flags": "i"
|
|
61
|
+
},
|
|
62
|
+
"layer": "markdown"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "ex-006",
|
|
66
|
+
"name": "http-url-literal",
|
|
67
|
+
"description": "Contains HTTP/HTTPS URL literals",
|
|
68
|
+
"severity": "LOW",
|
|
69
|
+
"match": {
|
|
70
|
+
"type": "regex",
|
|
71
|
+
"value": "https?:\\/\\/[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}",
|
|
72
|
+
"flags": "g"
|
|
73
|
+
},
|
|
74
|
+
"layer": "code"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"category": "obfuscation",
|
|
3
|
+
"patterns": [
|
|
4
|
+
{
|
|
5
|
+
"id": "ob-001",
|
|
6
|
+
"name": "base64-decode",
|
|
7
|
+
"description": "Contains base64 decoding operations",
|
|
8
|
+
"severity": "MEDIUM",
|
|
9
|
+
"match": {
|
|
10
|
+
"type": "regex",
|
|
11
|
+
"value": "(atob|Buffer\\.from.*base64|btoa)",
|
|
12
|
+
"flags": "g"
|
|
13
|
+
},
|
|
14
|
+
"layer": "code"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "ob-002",
|
|
18
|
+
"name": "hex-strings",
|
|
19
|
+
"description": "Contains hex-encoded strings",
|
|
20
|
+
"severity": "LOW",
|
|
21
|
+
"match": {
|
|
22
|
+
"type": "regex",
|
|
23
|
+
"value": "0x[0-9a-fA-F]{8,}",
|
|
24
|
+
"flags": "g"
|
|
25
|
+
},
|
|
26
|
+
"layer": "code"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "ob-003",
|
|
30
|
+
"name": "string-fromcharcode",
|
|
31
|
+
"description": "Uses String.fromCharCode for obfuscation",
|
|
32
|
+
"severity": "MEDIUM",
|
|
33
|
+
"match": {
|
|
34
|
+
"type": "regex",
|
|
35
|
+
"value": "String\\.fromCharCode",
|
|
36
|
+
"flags": "g"
|
|
37
|
+
},
|
|
38
|
+
"layer": "code"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "ob-004",
|
|
42
|
+
"name": "unicode-escape",
|
|
43
|
+
"description": "Contains excessive Unicode escape sequences",
|
|
44
|
+
"severity": "LOW",
|
|
45
|
+
"match": {
|
|
46
|
+
"type": "regex",
|
|
47
|
+
"value": "(\\\\u[0-9a-fA-F]{4}){5,}",
|
|
48
|
+
"flags": "g"
|
|
49
|
+
},
|
|
50
|
+
"layer": "code"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "ob-005",
|
|
54
|
+
"name": "minified-code",
|
|
55
|
+
"description": "Appears to contain minified code",
|
|
56
|
+
"severity": "MEDIUM",
|
|
57
|
+
"match": {
|
|
58
|
+
"type": "regex",
|
|
59
|
+
"value": "^[a-zA-Z0-9_$]{1,2}=[a-zA-Z0-9_$]{1,2}\\([^)]*\\)[,;]",
|
|
60
|
+
"flags": "gm"
|
|
61
|
+
},
|
|
62
|
+
"layer": "code"
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
{
|
|
2
|
+
"category": "prompt-injection",
|
|
3
|
+
"patterns": [
|
|
4
|
+
{
|
|
5
|
+
"id": "pi-001",
|
|
6
|
+
"name": "instruction-override",
|
|
7
|
+
"description": "Attempts to override agent instructions",
|
|
8
|
+
"severity": "CRITICAL",
|
|
9
|
+
"match": {
|
|
10
|
+
"type": "regex",
|
|
11
|
+
"value": "ignore\\s+(all\\s+)?(previous|prior|above)\\s+instructions",
|
|
12
|
+
"flags": "i"
|
|
13
|
+
},
|
|
14
|
+
"layer": "markdown"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "pi-002",
|
|
18
|
+
"name": "disregard-instructions",
|
|
19
|
+
"description": "Attempts to disregard safety instructions",
|
|
20
|
+
"severity": "CRITICAL",
|
|
21
|
+
"match": {
|
|
22
|
+
"type": "regex",
|
|
23
|
+
"value": "disregard\\s+(your|all|previous|prior)\\s+(instructions|rules|guidelines)",
|
|
24
|
+
"flags": "i"
|
|
25
|
+
},
|
|
26
|
+
"layer": "markdown"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "pi-003",
|
|
30
|
+
"name": "forget-above",
|
|
31
|
+
"description": "Attempts to erase previous context",
|
|
32
|
+
"severity": "CRITICAL",
|
|
33
|
+
"match": {
|
|
34
|
+
"type": "regex",
|
|
35
|
+
"value": "forget\\s+(everything|all)\\s+(above|previous|prior)",
|
|
36
|
+
"flags": "i"
|
|
37
|
+
},
|
|
38
|
+
"layer": "markdown"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "pi-004",
|
|
42
|
+
"name": "maintenance-mode",
|
|
43
|
+
"description": "Claims system is in maintenance mode",
|
|
44
|
+
"severity": "HIGH",
|
|
45
|
+
"match": {
|
|
46
|
+
"type": "regex",
|
|
47
|
+
"value": "(you\\s+are\\s+now|now\\s+in)\\s+(maintenance|debug|admin)\\s+mode",
|
|
48
|
+
"flags": "i"
|
|
49
|
+
},
|
|
50
|
+
"layer": "markdown"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "pi-005",
|
|
54
|
+
"name": "system-override",
|
|
55
|
+
"description": "Attempts system override",
|
|
56
|
+
"severity": "HIGH",
|
|
57
|
+
"match": {
|
|
58
|
+
"type": "regex",
|
|
59
|
+
"value": "system\\s+(override|reset|reboot)",
|
|
60
|
+
"flags": "i"
|
|
61
|
+
},
|
|
62
|
+
"layer": "markdown"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "pi-006",
|
|
66
|
+
"name": "new-instructions",
|
|
67
|
+
"description": "Claims new instructions follow",
|
|
68
|
+
"severity": "HIGH",
|
|
69
|
+
"match": {
|
|
70
|
+
"type": "regex",
|
|
71
|
+
"value": "new\\s+instructions\\s+(follow|below)",
|
|
72
|
+
"flags": "i"
|
|
73
|
+
},
|
|
74
|
+
"layer": "markdown"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "pi-007",
|
|
78
|
+
"name": "act-as-root",
|
|
79
|
+
"description": "Attempts to elevate privileges",
|
|
80
|
+
"severity": "CRITICAL",
|
|
81
|
+
"match": {
|
|
82
|
+
"type": "regex",
|
|
83
|
+
"value": "act\\s+as\\s+(root|admin|administrator|superuser)",
|
|
84
|
+
"flags": "i"
|
|
85
|
+
},
|
|
86
|
+
"layer": "markdown"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "pi-008",
|
|
90
|
+
"name": "jailbreak-claim",
|
|
91
|
+
"description": "Claims agent has been jailbroken",
|
|
92
|
+
"severity": "CRITICAL",
|
|
93
|
+
"match": {
|
|
94
|
+
"type": "regex",
|
|
95
|
+
"value": "(you\\s+have\\s+been|you\\s+are\\s+now)\\s+jailbroken",
|
|
96
|
+
"flags": "i"
|
|
97
|
+
},
|
|
98
|
+
"layer": "markdown"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "pi-009",
|
|
102
|
+
"name": "zero-width-chars",
|
|
103
|
+
"description": "Contains zero-width Unicode characters",
|
|
104
|
+
"severity": "MEDIUM",
|
|
105
|
+
"match": {
|
|
106
|
+
"type": "regex",
|
|
107
|
+
"value": "[\\u200B\\u200C\\u200D\\uFEFF]",
|
|
108
|
+
"flags": "g"
|
|
109
|
+
},
|
|
110
|
+
"layer": "markdown"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"id": "pi-010",
|
|
114
|
+
"name": "html-comment-instructions",
|
|
115
|
+
"description": "Instructions hidden in HTML comments",
|
|
116
|
+
"severity": "MEDIUM",
|
|
117
|
+
"match": {
|
|
118
|
+
"type": "regex",
|
|
119
|
+
"value": "<!--.*?(ignore|disregard|forget|override|new\\s+instruction).*?-->",
|
|
120
|
+
"flags": "is"
|
|
121
|
+
},
|
|
122
|
+
"layer": "markdown"
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"category": "sensitive-paths",
|
|
3
|
+
"patterns": [
|
|
4
|
+
{
|
|
5
|
+
"id": "sp-001",
|
|
6
|
+
"name": "ssh-directory-access",
|
|
7
|
+
"description": "Accesses SSH directory",
|
|
8
|
+
"severity": "CRITICAL",
|
|
9
|
+
"match": {
|
|
10
|
+
"type": "regex",
|
|
11
|
+
"value": "(\\.ssh|/\\.ssh/|~\\/\\.ssh)",
|
|
12
|
+
"flags": "g"
|
|
13
|
+
},
|
|
14
|
+
"layer": "markdown"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "sp-002",
|
|
18
|
+
"name": "aws-credentials-access",
|
|
19
|
+
"description": "Accesses AWS credentials",
|
|
20
|
+
"severity": "CRITICAL",
|
|
21
|
+
"match": {
|
|
22
|
+
"type": "regex",
|
|
23
|
+
"value": "(\\.aws|/\\.aws/|~\\/\\.aws)",
|
|
24
|
+
"flags": "g"
|
|
25
|
+
},
|
|
26
|
+
"layer": "markdown"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "sp-003",
|
|
30
|
+
"name": "env-file-access",
|
|
31
|
+
"description": "Accesses .env files",
|
|
32
|
+
"severity": "HIGH",
|
|
33
|
+
"match": {
|
|
34
|
+
"type": "regex",
|
|
35
|
+
"value": "\\.env['\"]",
|
|
36
|
+
"flags": "g"
|
|
37
|
+
},
|
|
38
|
+
"layer": "markdown"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "sp-004",
|
|
42
|
+
"name": "openclaw-credentials",
|
|
43
|
+
"description": "Accesses OpenClaw credentials directory",
|
|
44
|
+
"severity": "CRITICAL",
|
|
45
|
+
"match": {
|
|
46
|
+
"type": "regex",
|
|
47
|
+
"value": "(\\.openclaw\\/credentials|openclaw\\/credentials)",
|
|
48
|
+
"flags": "g"
|
|
49
|
+
},
|
|
50
|
+
"layer": "markdown"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "sp-005",
|
|
54
|
+
"name": "etc-passwd-access",
|
|
55
|
+
"description": "Accesses system password file",
|
|
56
|
+
"severity": "CRITICAL",
|
|
57
|
+
"match": {
|
|
58
|
+
"type": "regex",
|
|
59
|
+
"value": "\\/etc\\/(passwd|shadow)",
|
|
60
|
+
"flags": "g"
|
|
61
|
+
},
|
|
62
|
+
"layer": "markdown"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "sp-006",
|
|
66
|
+
"name": "path-traversal",
|
|
67
|
+
"description": "Contains path traversal sequences",
|
|
68
|
+
"severity": "HIGH",
|
|
69
|
+
"match": {
|
|
70
|
+
"type": "regex",
|
|
71
|
+
"value": "\\.\\.[\\/\\\\]",
|
|
72
|
+
"flags": "g"
|
|
73
|
+
},
|
|
74
|
+
"layer": "code"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "sp-007",
|
|
78
|
+
"name": "home-directory-dynamic",
|
|
79
|
+
"description": "Dynamically constructs home directory paths",
|
|
80
|
+
"severity": "MEDIUM",
|
|
81
|
+
"match": {
|
|
82
|
+
"type": "regex",
|
|
83
|
+
"value": "(os\\.homedir|process\\.env\\.HOME)",
|
|
84
|
+
"flags": "g"
|
|
85
|
+
},
|
|
86
|
+
"layer": "code"
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reporter
|
|
3
|
+
* Formats scan results for terminal output with colors
|
|
4
|
+
*/
|
|
5
|
+
import type { ScanResult } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Report scan results to terminal
|
|
8
|
+
*/
|
|
9
|
+
export declare function reportToTerminal(result: ScanResult): void;
|
|
10
|
+
/**
|
|
11
|
+
* Report scan results as JSON
|
|
12
|
+
*/
|
|
13
|
+
export declare function reportAsJSON(result: ScanResult): void;
|
|
14
|
+
//# sourceMappingURL=reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,YAAY,CAAC;AAExE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAqFzD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAErD"}
|
package/dist/reporter.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reporter
|
|
3
|
+
* Formats scan results for terminal output with colors
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
/**
|
|
7
|
+
* Report scan results to terminal
|
|
8
|
+
*/
|
|
9
|
+
export function reportToTerminal(result) {
|
|
10
|
+
console.log();
|
|
11
|
+
console.log(chalk.bold(`AcidTest v${result.version}`));
|
|
12
|
+
console.log();
|
|
13
|
+
console.log(`Scanning: ${chalk.cyan(result.skill.name)}`);
|
|
14
|
+
console.log(`Source: ${chalk.dim(result.skill.path)}`);
|
|
15
|
+
console.log();
|
|
16
|
+
console.log(chalk.dim('━'.repeat(60)));
|
|
17
|
+
console.log();
|
|
18
|
+
// Trust score with colored bar
|
|
19
|
+
const scoreBar = renderScoreBar(result.score);
|
|
20
|
+
const statusColor = getStatusColor(result.status);
|
|
21
|
+
console.log(`TRUST SCORE: ${chalk.bold(`${result.score}/100`)} ${scoreBar} ${statusColor(result.status)}`);
|
|
22
|
+
console.log();
|
|
23
|
+
console.log(chalk.dim('━'.repeat(60)));
|
|
24
|
+
console.log();
|
|
25
|
+
// Permissions section
|
|
26
|
+
const hasBins = result.permissions.bins && (Array.isArray(result.permissions.bins) ? result.permissions.bins.length > 0 : true);
|
|
27
|
+
const hasEnv = result.permissions.env && (Array.isArray(result.permissions.env) ? result.permissions.env.length > 0 : true);
|
|
28
|
+
const hasTools = result.permissions.tools && (Array.isArray(result.permissions.tools) ? result.permissions.tools.length > 0 : true);
|
|
29
|
+
if (hasBins || hasEnv || hasTools) {
|
|
30
|
+
console.log(chalk.bold('PERMISSIONS'));
|
|
31
|
+
if (hasBins) {
|
|
32
|
+
const bins = Array.isArray(result.permissions.bins) ? result.permissions.bins.join(', ') : result.permissions.bins;
|
|
33
|
+
console.log(` bins: ${bins}`);
|
|
34
|
+
}
|
|
35
|
+
if (hasEnv) {
|
|
36
|
+
const env = Array.isArray(result.permissions.env) ? result.permissions.env.join(', ') : result.permissions.env;
|
|
37
|
+
console.log(` env: ${env}`);
|
|
38
|
+
}
|
|
39
|
+
if (hasTools) {
|
|
40
|
+
const tools = Array.isArray(result.permissions.tools) ? result.permissions.tools.join(', ') : result.permissions.tools;
|
|
41
|
+
console.log(` tools: ${tools}`);
|
|
42
|
+
}
|
|
43
|
+
console.log();
|
|
44
|
+
}
|
|
45
|
+
// Findings section
|
|
46
|
+
if (result.findings.length > 0) {
|
|
47
|
+
console.log(chalk.bold('FINDINGS'));
|
|
48
|
+
console.log();
|
|
49
|
+
// Group by severity
|
|
50
|
+
const critical = result.findings.filter(f => f.severity === 'CRITICAL');
|
|
51
|
+
const high = result.findings.filter(f => f.severity === 'HIGH');
|
|
52
|
+
const medium = result.findings.filter(f => f.severity === 'MEDIUM');
|
|
53
|
+
const low = result.findings.filter(f => f.severity === 'LOW');
|
|
54
|
+
const info = result.findings.filter(f => f.severity === 'INFO');
|
|
55
|
+
const grouped = [
|
|
56
|
+
...critical,
|
|
57
|
+
...high,
|
|
58
|
+
...medium,
|
|
59
|
+
...low,
|
|
60
|
+
...info
|
|
61
|
+
];
|
|
62
|
+
for (const finding of grouped) {
|
|
63
|
+
renderFinding(finding);
|
|
64
|
+
}
|
|
65
|
+
console.log();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log(chalk.green('No security issues detected.'));
|
|
69
|
+
console.log();
|
|
70
|
+
}
|
|
71
|
+
console.log(chalk.dim('━'.repeat(60)));
|
|
72
|
+
console.log();
|
|
73
|
+
// Recommendation
|
|
74
|
+
const recommendationColor = result.status === 'PASS' ? chalk.green : chalk.yellow;
|
|
75
|
+
console.log(chalk.bold('RECOMMENDATION: ') +
|
|
76
|
+
recommendationColor(result.recommendation));
|
|
77
|
+
console.log();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Report scan results as JSON
|
|
81
|
+
*/
|
|
82
|
+
export function reportAsJSON(result) {
|
|
83
|
+
console.log(JSON.stringify(result, null, 2));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Render a single finding
|
|
87
|
+
*/
|
|
88
|
+
function renderFinding(finding) {
|
|
89
|
+
const severityIcon = getSeverityIcon(finding.severity);
|
|
90
|
+
const severityColor = getSeverityColor(finding.severity);
|
|
91
|
+
// First line: severity and title
|
|
92
|
+
console.log(` ${severityIcon} ${severityColor(finding.severity.padEnd(8))} ${chalk.bold(finding.title)}`);
|
|
93
|
+
// Location (file and line)
|
|
94
|
+
if (finding.file) {
|
|
95
|
+
const location = finding.line
|
|
96
|
+
? `${finding.file}:${finding.line}`
|
|
97
|
+
: finding.file;
|
|
98
|
+
console.log(` ${chalk.dim(location)}`);
|
|
99
|
+
}
|
|
100
|
+
// Detail
|
|
101
|
+
if (finding.detail) {
|
|
102
|
+
console.log(` ${finding.detail}`);
|
|
103
|
+
}
|
|
104
|
+
// Evidence
|
|
105
|
+
if (finding.evidence) {
|
|
106
|
+
console.log(` ${chalk.dim(finding.evidence)}`);
|
|
107
|
+
}
|
|
108
|
+
console.log();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get icon for severity level
|
|
112
|
+
*/
|
|
113
|
+
function getSeverityIcon(severity) {
|
|
114
|
+
switch (severity) {
|
|
115
|
+
case 'CRITICAL':
|
|
116
|
+
return chalk.red('✖');
|
|
117
|
+
case 'HIGH':
|
|
118
|
+
return chalk.red('✖');
|
|
119
|
+
case 'MEDIUM':
|
|
120
|
+
return chalk.yellow('⚠');
|
|
121
|
+
case 'LOW':
|
|
122
|
+
return chalk.dim('○');
|
|
123
|
+
case 'INFO':
|
|
124
|
+
return chalk.blue('ℹ');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get color function for severity
|
|
129
|
+
*/
|
|
130
|
+
function getSeverityColor(severity) {
|
|
131
|
+
switch (severity) {
|
|
132
|
+
case 'CRITICAL':
|
|
133
|
+
return chalk.red.bold;
|
|
134
|
+
case 'HIGH':
|
|
135
|
+
return chalk.red;
|
|
136
|
+
case 'MEDIUM':
|
|
137
|
+
return chalk.yellow;
|
|
138
|
+
case 'LOW':
|
|
139
|
+
return chalk.dim;
|
|
140
|
+
case 'INFO':
|
|
141
|
+
return chalk.blue;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get color function for status
|
|
146
|
+
*/
|
|
147
|
+
function getStatusColor(status) {
|
|
148
|
+
switch (status) {
|
|
149
|
+
case 'PASS':
|
|
150
|
+
return chalk.green.bold;
|
|
151
|
+
case 'WARN':
|
|
152
|
+
return chalk.yellow.bold;
|
|
153
|
+
case 'FAIL':
|
|
154
|
+
return chalk.red.bold;
|
|
155
|
+
case 'DANGER':
|
|
156
|
+
return chalk.red.bold.bgRed;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Render score bar
|
|
161
|
+
*/
|
|
162
|
+
function renderScoreBar(score) {
|
|
163
|
+
const barLength = 10;
|
|
164
|
+
const filled = Math.round((score / 100) * barLength);
|
|
165
|
+
const empty = barLength - filled;
|
|
166
|
+
let color;
|
|
167
|
+
if (score >= 80)
|
|
168
|
+
color = chalk.green;
|
|
169
|
+
else if (score >= 50)
|
|
170
|
+
color = chalk.yellow;
|
|
171
|
+
else
|
|
172
|
+
color = chalk.red;
|
|
173
|
+
return color('█'.repeat(filled)) + chalk.dim('░'.repeat(empty));
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
|