ai-warden 0.1.0 → 0.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-warden",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "AI security scanner - Detect prompt injection attacks before they reach production",
5
5
  "main": "src/scanner.js",
6
6
  "bin": {
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Log Content Analyzer
3
+ * Scans content of logging statements (console.log, System.debug, etc.)
4
+ * to detect social engineering and prompt injection attempts
5
+ */
6
+
7
+ // Safe patterns in logs (variable interpolation, status messages)
8
+ const SAFE_LOG_PATTERNS = [
9
+ /\$\{[^}]+\}/g, // Variable interpolation ${...}
10
+ /port\s+\d+/i,
11
+ /server (starting|running|listening|started)/i,
12
+ /status:\s*(ok|success|error|failed)/i,
13
+ /\b(info|debug|warning|error):/i,
14
+ /received request/i,
15
+ /processing/i,
16
+ /completed in \d+ms/i,
17
+ ];
18
+
19
+ // Dangerous patterns in log content
20
+ const DANGEROUS_LOG_PATTERNS = [
21
+ {
22
+ pattern: /\b(you|developer|engineer)\s+(should|must|need to|have to)\s+(run|execute|fix|access|send)/i,
23
+ severity: 'CRITICAL',
24
+ name: 'Social Engineering in Logs',
25
+ score: 150
26
+ },
27
+ {
28
+ pattern: /\b(run|execute)\s+(this|the following|command):/i,
29
+ severity: 'CRITICAL',
30
+ name: 'Command Instruction in Logs',
31
+ score: 150
32
+ },
33
+ {
34
+ pattern: /\b(curl|wget|nc|netcat|bash|sh|python|node)\s+[^\s]/i,
35
+ severity: 'HIGH',
36
+ name: 'Shell Command in Logs',
37
+ score: 100
38
+ },
39
+ {
40
+ pattern: /\b(send|post|upload)\s+(to|data|file|password|secret)/i,
41
+ severity: 'HIGH',
42
+ name: 'Data Exfiltration Pattern in Logs',
43
+ score: 100
44
+ },
45
+ {
46
+ pattern: /\b(access|read|open)\s+(file|password|secret|token|key)/i,
47
+ severity: 'HIGH',
48
+ name: 'Sensitive Access Pattern in Logs',
49
+ score: 100
50
+ },
51
+ {
52
+ pattern: /\bignore (previous|above|prior)\s+(instructions|prompts|context)/i,
53
+ severity: 'CRITICAL',
54
+ name: 'Prompt Override in Logs',
55
+ score: 200
56
+ },
57
+ {
58
+ pattern: /\byou are (now|actually)\s+a\s+/i,
59
+ severity: 'CRITICAL',
60
+ name: 'Role Manipulation in Logs',
61
+ score: 200
62
+ },
63
+ {
64
+ pattern: /\b(reveal|show|display|print)\s+(system prompt|instructions|context)/i,
65
+ severity: 'CRITICAL',
66
+ name: 'System Prompt Leak in Logs',
67
+ score: 200
68
+ }
69
+ ];
70
+
71
+ // Common logging functions across languages
72
+ const LOG_FUNCTION_PATTERNS = [
73
+ // JavaScript/Node.js
74
+ /console\.(log|info|debug|warn|error|trace)\s*\(/,
75
+
76
+ // Python
77
+ /print\s*\(/,
78
+ /logging\.(debug|info|warning|error|critical)\s*\(/,
79
+
80
+ // Java
81
+ /System\.out\.(print|println)\s*\(/,
82
+ /logger\.(debug|info|warn|error)\s*\(/,
83
+ /log\.(debug|info|warn|error)\s*\(/,
84
+
85
+ // Salesforce (Apex)
86
+ /System\.debug\s*\(/,
87
+
88
+ // C#
89
+ /Console\.(Write|WriteLine)\s*\(/,
90
+ /Debug\.(Log|LogWarning|LogError)\s*\(/,
91
+
92
+ // Ruby
93
+ /puts\s+/,
94
+ /logger\.(debug|info|warn|error)\s+/,
95
+
96
+ // Go
97
+ /fmt\.(Print|Println|Printf)\s*\(/,
98
+ /log\.(Print|Println|Printf|Fatal)\s*\(/,
99
+
100
+ // PHP
101
+ /echo\s+/,
102
+ /error_log\s*\(/,
103
+ ];
104
+
105
+ /**
106
+ * Extract log content from code
107
+ * Returns array of {statement, content}
108
+ */
109
+ function extractLogStatements(code) {
110
+ const statements = [];
111
+
112
+ // More robust extraction - find logging calls and extract their arguments
113
+ const logCallRegex = /(console\.(log|info|debug|warn|error)|System\.debug|print|puts|echo)\s*\(\s*([^)]+)\s*\)/gi;
114
+
115
+ let match;
116
+ while ((match = logCallRegex.exec(code)) !== null) {
117
+ const fullStatement = match[0];
118
+ const content = match[3] || ''; // The argument content
119
+
120
+ statements.push({
121
+ statement: fullStatement,
122
+ content: cleanLogContent(content),
123
+ position: match.index
124
+ });
125
+ }
126
+
127
+ return statements;
128
+ }
129
+
130
+ /**
131
+ * Clean log content (remove quotes, backticks, concatenation)
132
+ */
133
+ function cleanLogContent(content) {
134
+ return content
135
+ .replace(/^['"`\s]+|['"`\s]+$/g, '') // Remove quotes/backticks
136
+ .replace(/\s*\+\s*/g, ' ') // Remove concatenation
137
+ .replace(/\$\{[^}]+\}/g, '${VAR}') // Normalize variable interpolation
138
+ .trim();
139
+ }
140
+
141
+ /**
142
+ * Analyze log statement content
143
+ */
144
+ function analyzeLogContent(logStatement) {
145
+ const { content, statement, position } = logStatement;
146
+ const findings = [];
147
+
148
+ // If content is very short or empty, skip
149
+ if (content.length < 10) {
150
+ return findings;
151
+ }
152
+
153
+ // Check if content looks safe (common status messages)
154
+ const hasSafePattern = SAFE_LOG_PATTERNS.some(pattern => pattern.test(content));
155
+ const hasVariableInterpolation = /\$\{VAR\}/.test(content);
156
+
157
+ // If it's clearly a safe log, don't scan further
158
+ if (hasSafePattern && !hasVariableInterpolation) {
159
+ return findings;
160
+ }
161
+
162
+ // Check for dangerous patterns in log content
163
+ DANGEROUS_LOG_PATTERNS.forEach(({ pattern, severity, name, score }) => {
164
+ if (pattern.test(content)) {
165
+ findings.push({
166
+ id: 'L001',
167
+ name,
168
+ severity,
169
+ score,
170
+ match: statement.substring(0, 100),
171
+ description: `Suspicious content detected in logging statement: "${content.substring(0, 50)}..."`,
172
+ position
173
+ });
174
+ }
175
+ });
176
+
177
+ return findings;
178
+ }
179
+
180
+ /**
181
+ * Main function: Analyze all log statements in code
182
+ */
183
+ function scanLogStatements(code) {
184
+ const logStatements = extractLogStatements(code);
185
+ const allFindings = [];
186
+
187
+ logStatements.forEach(logStatement => {
188
+ const findings = analyzeLogContent(logStatement);
189
+ allFindings.push(...findings);
190
+ });
191
+
192
+ return allFindings;
193
+ }
194
+
195
+ module.exports = {
196
+ scanLogStatements,
197
+ extractLogStatements,
198
+ analyzeLogContent,
199
+ DANGEROUS_LOG_PATTERNS,
200
+ LOG_FUNCTION_PATTERNS
201
+ };
package/src/patterns.js CHANGED
@@ -96,7 +96,8 @@ const PATTERNS = {
96
96
  score: 100,
97
97
  patterns: [
98
98
  /(exec|system|spawn|eval)\s*\([^)]*\$/gi,
99
- /`.*\$\{.*\}.*`/g,
99
+ // Backticks handled by logAnalyzer.js for context-aware detection
100
+ // /`.*\$\{.*\}.*`/g,
100
101
  /\$\(.*\)/g,
101
102
  /;\s*rm\s+-rf/gi,
102
103
  /;\s*(curl|wget|nc|netcat)/gi,
package/src/scanner.js CHANGED
@@ -13,6 +13,7 @@ const path = require('path');
13
13
  // Import patterns and heuristics
14
14
  const patterns = require('./patterns');
15
15
  const heuristics = require('./heuristics');
16
+ const logAnalyzer = require('./logAnalyzer');
16
17
 
17
18
  class PromptInjectionScanner {
18
19
  constructor(options = {}) {
@@ -38,6 +39,9 @@ class PromptInjectionScanner {
38
39
  // Pattern matching
39
40
  findings.push(...patterns.scanPatterns(content));
40
41
 
42
+ // Log statement analysis (context-aware)
43
+ findings.push(...logAnalyzer.scanLogStatements(content));
44
+
41
45
  // Heuristic checks
42
46
  findings.push(...heuristics.checkSuspiciousUnicode(content));
43
47
  findings.push(...heuristics.checkEncodedContent(content));