ai-code-audit 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.
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.aiSpecificRules = exports.excessiveComments = exports.typeAnyAbuse = exports.incompleteImpl = exports.aiPlaceholder = void 0;
4
+ function findMatches(content, pattern, rule, severity, message, filename) {
5
+ const findings = [];
6
+ const lines = content.split('\n');
7
+ for (let i = 0; i < lines.length; i++) {
8
+ const line = lines[i];
9
+ let match;
10
+ pattern.lastIndex = 0;
11
+ while ((match = pattern.exec(line)) !== null) {
12
+ findings.push({
13
+ rule,
14
+ severity,
15
+ message,
16
+ file: filename,
17
+ line: i + 1,
18
+ column: match.index + 1,
19
+ snippet: line.trim(),
20
+ });
21
+ if (!pattern.global)
22
+ break;
23
+ }
24
+ }
25
+ return findings;
26
+ }
27
+ exports.aiPlaceholder = {
28
+ name: 'ai-placeholder',
29
+ description: 'Detects placeholder text left by AI',
30
+ severity: 'error',
31
+ languages: ['javascript', 'typescript', 'python', 'ruby', 'go'],
32
+ check: (content, filename) => {
33
+ const patterns = [
34
+ /\/\/\s*(?:Add|TODO:?\s*add|Implement)\s+(?:your|the)\s+/gi,
35
+ /\/\/\s*(?:Replace|Update)\s+(?:this|with)\s+/gi,
36
+ /#\s*(?:Add|TODO:?\s*add|Implement)\s+(?:your|the)\s+/gi,
37
+ /\/\/\s*\.\.\.\s*(?:rest|more|additional|other)/gi,
38
+ /\/\*\s*(?:Add|Implement|Your)\s+.*\s+here\s*\*\//gi,
39
+ /['"](?:your-api-key|YOUR_API_KEY|api-key-here|replace-me|CHANGE_ME)['"]/gi,
40
+ /(?:example|placeholder|dummy)[@.](?:com|org|io)/gi,
41
+ ];
42
+ const findings = [];
43
+ for (const pattern of patterns) {
44
+ findings.push(...findMatches(content, pattern, 'ai-placeholder', 'error', 'AI placeholder text detected - needs implementation', filename));
45
+ }
46
+ return findings;
47
+ },
48
+ };
49
+ exports.incompleteImpl = {
50
+ name: 'incomplete-impl',
51
+ description: 'Detects incomplete implementations',
52
+ severity: 'warning',
53
+ languages: ['javascript', 'typescript', 'python'],
54
+ check: (content, filename) => {
55
+ const patterns = [
56
+ /throw\s+new\s+Error\s*\(\s*['"](?:Not\s+implemented|TODO|FIXME)['"]/gi,
57
+ /raise\s+NotImplementedError/gi,
58
+ /pass\s*#\s*(?:TODO|FIXME)/gi,
59
+ /return\s+(?:null|undefined|None)\s*;?\s*\/\/\s*(?:TODO|FIXME)/gi,
60
+ ];
61
+ const findings = [];
62
+ for (const pattern of patterns) {
63
+ findings.push(...findMatches(content, pattern, 'incomplete-impl', 'warning', 'Incomplete implementation detected', filename));
64
+ }
65
+ return findings;
66
+ },
67
+ };
68
+ exports.typeAnyAbuse = {
69
+ name: 'type-any-abuse',
70
+ description: 'Detects excessive use of any type',
71
+ severity: 'warning',
72
+ languages: ['typescript'],
73
+ check: (content, filename) => {
74
+ if (!filename.endsWith('.ts') && !filename.endsWith('.tsx')) {
75
+ return [];
76
+ }
77
+ const pattern = /:\s*any\b/g;
78
+ const findings = findMatches(content, pattern, 'type-any-abuse', 'warning', 'Unsafe "any" type usage - consider using a specific type', filename);
79
+ // Only report if there are many instances
80
+ if (findings.length > 3) {
81
+ return findings;
82
+ }
83
+ return [];
84
+ },
85
+ };
86
+ exports.excessiveComments = {
87
+ name: 'excessive-comments',
88
+ description: 'Detects over-commented obvious code',
89
+ severity: 'info',
90
+ languages: ['javascript', 'typescript'],
91
+ check: (content, filename) => {
92
+ const findings = [];
93
+ const lines = content.split('\n');
94
+ let commentLines = 0;
95
+ let codeLines = 0;
96
+ for (const line of lines) {
97
+ const trimmed = line.trim();
98
+ if (trimmed.startsWith('//') || trimmed.startsWith('/*') || trimmed.startsWith('*')) {
99
+ commentLines++;
100
+ }
101
+ else if (trimmed.length > 0) {
102
+ codeLines++;
103
+ }
104
+ }
105
+ // If comments exceed 50% of code, flag it
106
+ if (codeLines > 10 && commentLines > codeLines * 0.5) {
107
+ findings.push({
108
+ rule: 'excessive-comments',
109
+ severity: 'info',
110
+ message: `High comment ratio (${commentLines} comments / ${codeLines} code lines) - may be over-documented`,
111
+ file: filename,
112
+ line: 1,
113
+ column: 1,
114
+ });
115
+ }
116
+ return findings;
117
+ },
118
+ };
119
+ exports.aiSpecificRules = [
120
+ exports.aiPlaceholder,
121
+ exports.incompleteImpl,
122
+ exports.typeAnyAbuse,
123
+ exports.excessiveComments,
124
+ ];
125
+ //# sourceMappingURL=ai-specific.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-specific.js","sourceRoot":"","sources":["../../src/rules/ai-specific.ts"],"names":[],"mappings":";;;AAEA,SAAS,WAAW,CAClB,OAAe,EACf,OAAe,EACf,IAAY,EACZ,QAAsC,EACtC,OAAe,EACf,QAAgB;IAEhB,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,KAAK,CAAC;QAEV,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QAEtB,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC7C,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI;gBACJ,QAAQ;gBACR,OAAO;gBACP,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,GAAG,CAAC;gBACX,MAAM,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC;gBACvB,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE;aACrB,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,MAAM;gBAAE,MAAM;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAEY,QAAA,aAAa,GAAS;IACjC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,qCAAqC;IAClD,QAAQ,EAAE,OAAO;IACjB,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG;YACf,2DAA2D;YAC3D,gDAAgD;YAChD,wDAAwD;YACxD,kDAAkD;YAClD,oDAAoD;YACpD,2EAA2E;YAC3E,mDAAmD;SACpD,CAAC;QAEF,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,QAAQ,CAAC,IAAI,CACX,GAAG,WAAW,CACZ,OAAO,EACP,OAAO,EACP,gBAAgB,EAChB,OAAO,EACP,qDAAqD,EACrD,QAAQ,CACT,CACF,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEW,QAAA,cAAc,GAAS;IAClC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,oCAAoC;IACjD,QAAQ,EAAE,SAAS;IACnB,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC;IACjD,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG;YACf,uEAAuE;YACvE,+BAA+B;YAC/B,6BAA6B;YAC7B,iEAAiE;SAClE,CAAC;QAEF,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,QAAQ,CAAC,IAAI,CACX,GAAG,WAAW,CACZ,OAAO,EACP,OAAO,EACP,iBAAiB,EACjB,SAAS,EACT,oCAAoC,EACpC,QAAQ,CACT,CACF,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEW,QAAA,YAAY,GAAS;IAChC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,mCAAmC;IAChD,QAAQ,EAAE,SAAS;IACnB,SAAS,EAAE,CAAC,YAAY,CAAC;IACzB,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC3B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5D,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAG,YAAY,CAAC;QAC7B,MAAM,QAAQ,GAAG,WAAW,CAC1B,OAAO,EACP,OAAO,EACP,gBAAgB,EAChB,SAAS,EACT,0DAA0D,EAC1D,QAAQ,CACT,CAAC;QAEF,0CAA0C;QAC1C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC;AAEW,QAAA,iBAAiB,GAAS;IACrC,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EAAE,qCAAqC;IAClD,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;IACvC,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpF,YAAY,EAAE,CAAC;YACjB,CAAC;iBAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,SAAS,EAAE,CAAC;YACd,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,IAAI,SAAS,GAAG,EAAE,IAAI,YAAY,GAAG,SAAS,GAAG,GAAG,EAAE,CAAC;YACrD,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,oBAAoB;gBAC1B,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,uBAAuB,YAAY,eAAe,SAAS,uCAAuC;gBAC3G,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,CAAC;aACV,CAAC,CAAC;QACL,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEW,QAAA,eAAe,GAAW;IACrC,qBAAa;IACb,sBAAc;IACd,oBAAY;IACZ,yBAAiB;CAClB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { securityRules } from './security.js';
2
+ import { qualityRules } from './quality.js';
3
+ import { aiSpecificRules } from './ai-specific.js';
4
+ import type { Rule } from '../types.js';
5
+ export declare const allRules: Rule[];
6
+ export { securityRules, qualityRules, aiSpecificRules };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.aiSpecificRules = exports.qualityRules = exports.securityRules = exports.allRules = void 0;
4
+ const security_js_1 = require("./security.js");
5
+ Object.defineProperty(exports, "securityRules", { enumerable: true, get: function () { return security_js_1.securityRules; } });
6
+ const quality_js_1 = require("./quality.js");
7
+ Object.defineProperty(exports, "qualityRules", { enumerable: true, get: function () { return quality_js_1.qualityRules; } });
8
+ const ai_specific_js_1 = require("./ai-specific.js");
9
+ Object.defineProperty(exports, "aiSpecificRules", { enumerable: true, get: function () { return ai_specific_js_1.aiSpecificRules; } });
10
+ exports.allRules = [
11
+ ...security_js_1.securityRules,
12
+ ...quality_js_1.qualityRules,
13
+ ...ai_specific_js_1.aiSpecificRules,
14
+ ];
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":";;;AAAA,+CAA8C;AAWrC,8FAXA,2BAAa,OAWA;AAVtB,6CAA4C;AAUpB,6FAVf,yBAAY,OAUe;AATpC,qDAAmD;AASb,gGAT7B,gCAAe,OAS6B;AANxC,QAAA,QAAQ,GAAW;IAC9B,GAAG,2BAAa;IAChB,GAAG,yBAAY;IACf,GAAG,gCAAe;CACnB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Rule } from '../types.js';
2
+ export declare const missingErrorHandling: Rule;
3
+ export declare const emptyCatch: Rule;
4
+ export declare const consoleLog: Rule;
5
+ export declare const todoFixme: Rule;
6
+ export declare const deepNesting: Rule;
7
+ export declare const qualityRules: Rule[];
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.qualityRules = exports.deepNesting = exports.todoFixme = exports.consoleLog = exports.emptyCatch = exports.missingErrorHandling = void 0;
4
+ function findMatches(content, pattern, rule, severity, message, filename) {
5
+ const findings = [];
6
+ const lines = content.split('\n');
7
+ for (let i = 0; i < lines.length; i++) {
8
+ const line = lines[i];
9
+ let match;
10
+ pattern.lastIndex = 0;
11
+ while ((match = pattern.exec(line)) !== null) {
12
+ findings.push({
13
+ rule,
14
+ severity,
15
+ message,
16
+ file: filename,
17
+ line: i + 1,
18
+ column: match.index + 1,
19
+ snippet: line.trim(),
20
+ });
21
+ if (!pattern.global)
22
+ break;
23
+ }
24
+ }
25
+ return findings;
26
+ }
27
+ exports.missingErrorHandling = {
28
+ name: 'missing-error-handling',
29
+ description: 'Detects async operations without try/catch',
30
+ severity: 'warning',
31
+ languages: ['javascript', 'typescript'],
32
+ check: (content, filename) => {
33
+ const findings = [];
34
+ const lines = content.split('\n');
35
+ // Look for await outside of try blocks
36
+ let inTry = 0;
37
+ for (let i = 0; i < lines.length; i++) {
38
+ const line = lines[i];
39
+ if (/\btry\s*\{/.test(line))
40
+ inTry++;
41
+ if (/\}\s*catch/.test(line))
42
+ inTry = Math.max(0, inTry - 1);
43
+ if (inTry === 0 && /\bawait\s+/.test(line)) {
44
+ // Check if it's in an async function without surrounding try
45
+ findings.push({
46
+ rule: 'missing-error-handling',
47
+ severity: 'warning',
48
+ message: 'Async operation without error handling',
49
+ file: filename,
50
+ line: i + 1,
51
+ column: line.indexOf('await') + 1,
52
+ snippet: line.trim(),
53
+ });
54
+ }
55
+ }
56
+ return findings;
57
+ },
58
+ };
59
+ exports.emptyCatch = {
60
+ name: 'empty-catch',
61
+ description: 'Detects empty catch blocks that swallow errors',
62
+ severity: 'warning',
63
+ languages: ['javascript', 'typescript'],
64
+ check: (content, filename) => {
65
+ const pattern = /catch\s*\([^)]*\)\s*\{\s*\}/g;
66
+ return findMatches(content, pattern, 'empty-catch', 'warning', 'Empty catch block swallows errors', filename);
67
+ },
68
+ };
69
+ exports.consoleLog = {
70
+ name: 'console-log',
71
+ description: 'Detects console.log left in code',
72
+ severity: 'info',
73
+ languages: ['javascript', 'typescript'],
74
+ check: (content, filename) => {
75
+ const pattern = /console\.log\s*\(/g;
76
+ return findMatches(content, pattern, 'console-log', 'info', 'console.log statement found', filename);
77
+ },
78
+ };
79
+ exports.todoFixme = {
80
+ name: 'todo-fixme',
81
+ description: 'Detects TODO/FIXME comments',
82
+ severity: 'info',
83
+ languages: ['javascript', 'typescript', 'python', 'ruby', 'go'],
84
+ check: (content, filename) => {
85
+ const pattern = /\/\/\s*(?:TODO|FIXME|HACK|XXX|BUG)[\s:]/gi;
86
+ return findMatches(content, pattern, 'todo-fixme', 'info', 'TODO/FIXME comment found', filename);
87
+ },
88
+ };
89
+ exports.deepNesting = {
90
+ name: 'deep-nesting',
91
+ description: 'Detects deeply nested code (>4 levels)',
92
+ severity: 'warning',
93
+ languages: ['javascript', 'typescript'],
94
+ check: (content, filename) => {
95
+ const findings = [];
96
+ const lines = content.split('\n');
97
+ let depth = 0;
98
+ const MAX_DEPTH = 4;
99
+ for (let i = 0; i < lines.length; i++) {
100
+ const line = lines[i];
101
+ const opens = (line.match(/\{/g) || []).length;
102
+ const closes = (line.match(/\}/g) || []).length;
103
+ depth += opens - closes;
104
+ if (depth > MAX_DEPTH && opens > 0) {
105
+ findings.push({
106
+ rule: 'deep-nesting',
107
+ severity: 'warning',
108
+ message: `Code nested ${depth} levels deep (max: ${MAX_DEPTH})`,
109
+ file: filename,
110
+ line: i + 1,
111
+ column: 1,
112
+ snippet: line.trim(),
113
+ });
114
+ }
115
+ }
116
+ return findings;
117
+ },
118
+ };
119
+ exports.qualityRules = [
120
+ exports.missingErrorHandling,
121
+ exports.emptyCatch,
122
+ exports.consoleLog,
123
+ exports.todoFixme,
124
+ exports.deepNesting,
125
+ ];
126
+ //# sourceMappingURL=quality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.js","sourceRoot":"","sources":["../../src/rules/quality.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Rule } from '../types.js';
2
+ export declare const sqlInjection: Rule;
3
+ export declare const commandInjection: Rule;
4
+ export declare const hardcodedSecret: Rule;
5
+ export declare const unsafeEval: Rule;
6
+ export declare const pathTraversal: Rule;
7
+ export declare const xssRisk: Rule;
8
+ export declare const securityRules: Rule[];
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.securityRules = exports.xssRisk = exports.pathTraversal = exports.unsafeEval = exports.hardcodedSecret = exports.commandInjection = exports.sqlInjection = void 0;
4
+ function findMatches(content, pattern, rule, severity, message, filename) {
5
+ const findings = [];
6
+ const lines = content.split('\n');
7
+ for (let i = 0; i < lines.length; i++) {
8
+ const line = lines[i];
9
+ let match;
10
+ // Reset regex for global patterns
11
+ pattern.lastIndex = 0;
12
+ while ((match = pattern.exec(line)) !== null) {
13
+ findings.push({
14
+ rule,
15
+ severity,
16
+ message,
17
+ file: filename,
18
+ line: i + 1,
19
+ column: match.index + 1,
20
+ snippet: line.trim(),
21
+ });
22
+ // Prevent infinite loop for non-global regex
23
+ if (!pattern.global)
24
+ break;
25
+ }
26
+ }
27
+ return findings;
28
+ }
29
+ exports.sqlInjection = {
30
+ name: 'sql-injection',
31
+ description: 'Detects SQL queries with string interpolation',
32
+ severity: 'error',
33
+ languages: ['javascript', 'typescript', 'python'],
34
+ check: (content, filename) => {
35
+ const patterns = [
36
+ // Template literals in SQL
37
+ /(?:query|execute|sql)\s*\(\s*`[^`]*\$\{/gi,
38
+ // String concatenation in SQL
39
+ /(?:query|execute|sql)\s*\(\s*['"][^'"]*['"]\s*\+/gi,
40
+ // Python f-strings in SQL
41
+ /(?:execute|cursor\.execute)\s*\(\s*f['"][^'"]*\{/gi,
42
+ ];
43
+ const findings = [];
44
+ for (const pattern of patterns) {
45
+ findings.push(...findMatches(content, pattern, 'sql-injection', 'error', 'SQL injection risk: query uses string interpolation', filename));
46
+ }
47
+ return findings;
48
+ },
49
+ };
50
+ exports.commandInjection = {
51
+ name: 'command-injection',
52
+ description: 'Detects shell commands with unsanitized input',
53
+ severity: 'error',
54
+ languages: ['javascript', 'typescript', 'python'],
55
+ check: (content, filename) => {
56
+ const patterns = [
57
+ // exec with template literal
58
+ /(?:exec|execSync|spawn|spawnSync)\s*\(\s*`[^`]*\$\{/gi,
59
+ // exec with concatenation
60
+ /(?:exec|execSync|spawn|spawnSync)\s*\(\s*['"][^'"]*['"]\s*\+/gi,
61
+ // Python subprocess with f-string
62
+ /subprocess\.(?:run|call|Popen)\s*\(\s*f['"][^'"]*\{/gi,
63
+ // shell=True in Python
64
+ /subprocess\.(?:run|call|Popen)\s*\([^)]*shell\s*=\s*True/gi,
65
+ ];
66
+ const findings = [];
67
+ for (const pattern of patterns) {
68
+ findings.push(...findMatches(content, pattern, 'command-injection', 'error', 'Command injection risk: shell command with unsanitized input', filename));
69
+ }
70
+ return findings;
71
+ },
72
+ };
73
+ exports.hardcodedSecret = {
74
+ name: 'hardcoded-secret',
75
+ description: 'Detects hardcoded API keys, passwords, tokens',
76
+ severity: 'error',
77
+ languages: ['javascript', 'typescript', 'python', 'ruby', 'go'],
78
+ check: (content, filename) => {
79
+ const patterns = [
80
+ // API keys
81
+ /(?:api[_-]?key|apikey)\s*[:=]\s*['"][a-zA-Z0-9_\-]{20,}['"]/gi,
82
+ // AWS keys
83
+ /(?:AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16}/g,
84
+ // Generic secrets
85
+ /(?:password|passwd|pwd|secret|token)\s*[:=]\s*['"][^'"]{8,}['"]/gi,
86
+ // Bearer tokens
87
+ /['"]Bearer\s+[a-zA-Z0-9_\-\.]+['"]/g,
88
+ // Private keys
89
+ /-----BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY-----/g,
90
+ // GitHub tokens
91
+ /gh[pousr]_[A-Za-z0-9_]{36,}/g,
92
+ // Slack tokens
93
+ /xox[baprs]-[A-Za-z0-9-]+/g,
94
+ ];
95
+ const findings = [];
96
+ for (const pattern of patterns) {
97
+ findings.push(...findMatches(content, pattern, 'hardcoded-secret', 'error', 'Hardcoded secret detected', filename));
98
+ }
99
+ return findings;
100
+ },
101
+ };
102
+ exports.unsafeEval = {
103
+ name: 'unsafe-eval',
104
+ description: 'Detects use of eval() or Function()',
105
+ severity: 'error',
106
+ languages: ['javascript', 'typescript'],
107
+ check: (content, filename) => {
108
+ const patterns = [
109
+ /\beval\s*\(/g,
110
+ /new\s+Function\s*\(/g,
111
+ /setTimeout\s*\(\s*['"`]/g,
112
+ /setInterval\s*\(\s*['"`]/g,
113
+ ];
114
+ const findings = [];
115
+ for (const pattern of patterns) {
116
+ findings.push(...findMatches(content, pattern, 'unsafe-eval', 'error', 'Unsafe eval() or Function() usage detected', filename));
117
+ }
118
+ return findings;
119
+ },
120
+ };
121
+ exports.pathTraversal = {
122
+ name: 'path-traversal',
123
+ description: 'Detects unsanitized file path operations',
124
+ severity: 'error',
125
+ languages: ['javascript', 'typescript', 'python'],
126
+ check: (content, filename) => {
127
+ const patterns = [
128
+ // Direct path concatenation
129
+ /(?:readFile|writeFile|unlink|rmdir|mkdir)(?:Sync)?\s*\(\s*(?:req\.|request\.|params\.|query\.)/gi,
130
+ // Python path with user input
131
+ /open\s*\(\s*(?:request\.|args\.|kwargs\.)/gi,
132
+ // Path join with user input
133
+ /path\.join\s*\([^)]*(?:req\.|request\.|params\.|query\.)/gi,
134
+ ];
135
+ const findings = [];
136
+ for (const pattern of patterns) {
137
+ findings.push(...findMatches(content, pattern, 'path-traversal', 'error', 'Path traversal risk: file operation with user input', filename));
138
+ }
139
+ return findings;
140
+ },
141
+ };
142
+ exports.xssRisk = {
143
+ name: 'xss-risk',
144
+ description: 'Detects potential XSS in HTML generation',
145
+ severity: 'warning',
146
+ languages: ['javascript', 'typescript'],
147
+ check: (content, filename) => {
148
+ const patterns = [
149
+ // innerHTML with variable
150
+ /\.innerHTML\s*=\s*[^'"]/g,
151
+ // document.write
152
+ /document\.write\s*\(/g,
153
+ // dangerouslySetInnerHTML
154
+ /dangerouslySetInnerHTML\s*=\s*\{\s*\{\s*__html\s*:/g,
155
+ ];
156
+ const findings = [];
157
+ for (const pattern of patterns) {
158
+ findings.push(...findMatches(content, pattern, 'xss-risk', 'warning', 'Potential XSS risk: unsafe HTML manipulation', filename));
159
+ }
160
+ return findings;
161
+ },
162
+ };
163
+ exports.securityRules = [
164
+ exports.sqlInjection,
165
+ exports.commandInjection,
166
+ exports.hardcodedSecret,
167
+ exports.unsafeEval,
168
+ exports.pathTraversal,
169
+ exports.xssRisk,
170
+ ];
171
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/rules/security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type Severity = 'info' | 'warning' | 'error';
2
+ export interface Finding {
3
+ rule: string;
4
+ severity: Severity;
5
+ message: string;
6
+ file: string;
7
+ line: number;
8
+ column: number;
9
+ snippet?: string;
10
+ }
11
+ export interface Rule {
12
+ name: string;
13
+ description: string;
14
+ severity: Severity;
15
+ languages: string[];
16
+ check: (content: string, filename: string) => Finding[];
17
+ }
18
+ export interface Config {
19
+ rules: Record<string, Severity | 'off'>;
20
+ ignore: string[];
21
+ languages: string[];
22
+ }
23
+ export interface AuditResult {
24
+ findings: Finding[];
25
+ filesScanned: number;
26
+ errorCount: number;
27
+ warningCount: number;
28
+ infoCount: number;
29
+ }
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "ai-code-audit",
3
+ "version": "0.1.0",
4
+ "description": "Security and quality linter for AI-generated code",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "ai-code-audit": "dist/cli.js",
8
+ "aca": "dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/cli.js",
14
+ "test": "node --test",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "ai",
19
+ "security",
20
+ "lint",
21
+ "audit",
22
+ "code-review",
23
+ "owasp"
24
+ ],
25
+ "author": "Josh Duffy",
26
+ "license": "MIT",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/joshduffy/ai-code-audit.git"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^20.0.0",
33
+ "typescript": "^5.3.0"
34
+ },
35
+ "engines": {
36
+ "node": ">=18.0.0"
37
+ }
38
+ }