@kevinrabun/judges 1.3.0 → 1.4.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.
Files changed (47) hide show
  1. package/dist/evaluators/authentication.d.ts.map +1 -1
  2. package/dist/evaluators/authentication.js +67 -0
  3. package/dist/evaluators/authentication.js.map +1 -1
  4. package/dist/evaluators/backwards-compatibility.d.ts.map +1 -1
  5. package/dist/evaluators/backwards-compatibility.js +70 -0
  6. package/dist/evaluators/backwards-compatibility.js.map +1 -1
  7. package/dist/evaluators/caching.d.ts.map +1 -1
  8. package/dist/evaluators/caching.js +68 -0
  9. package/dist/evaluators/caching.js.map +1 -1
  10. package/dist/evaluators/ci-cd.d.ts.map +1 -1
  11. package/dist/evaluators/ci-cd.js +66 -0
  12. package/dist/evaluators/ci-cd.js.map +1 -1
  13. package/dist/evaluators/configuration-management.d.ts.map +1 -1
  14. package/dist/evaluators/configuration-management.js +70 -0
  15. package/dist/evaluators/configuration-management.js.map +1 -1
  16. package/dist/evaluators/database.d.ts.map +1 -1
  17. package/dist/evaluators/database.js +54 -0
  18. package/dist/evaluators/database.js.map +1 -1
  19. package/dist/evaluators/error-handling.d.ts.map +1 -1
  20. package/dist/evaluators/error-handling.js +57 -0
  21. package/dist/evaluators/error-handling.js.map +1 -1
  22. package/dist/evaluators/logging-privacy.d.ts.map +1 -1
  23. package/dist/evaluators/logging-privacy.js +42 -0
  24. package/dist/evaluators/logging-privacy.js.map +1 -1
  25. package/dist/evaluators/maintainability.d.ts.map +1 -1
  26. package/dist/evaluators/maintainability.js +102 -0
  27. package/dist/evaluators/maintainability.js.map +1 -1
  28. package/dist/evaluators/portability.d.ts.map +1 -1
  29. package/dist/evaluators/portability.js +72 -0
  30. package/dist/evaluators/portability.js.map +1 -1
  31. package/dist/evaluators/rate-limiting.d.ts.map +1 -1
  32. package/dist/evaluators/rate-limiting.js +73 -0
  33. package/dist/evaluators/rate-limiting.js.map +1 -1
  34. package/dist/evaluators/scalability.d.ts.map +1 -1
  35. package/dist/evaluators/scalability.js +8 -3
  36. package/dist/evaluators/scalability.js.map +1 -1
  37. package/dist/evaluators/software-practices.d.ts.map +1 -1
  38. package/dist/evaluators/software-practices.js +14 -3
  39. package/dist/evaluators/software-practices.js.map +1 -1
  40. package/dist/evaluators/testing.d.ts.map +1 -1
  41. package/dist/evaluators/testing.js +6 -2
  42. package/dist/evaluators/testing.js.map +1 -1
  43. package/dist/evaluators/ux.d.ts.map +1 -1
  44. package/dist/evaluators/ux.js +69 -0
  45. package/dist/evaluators/ux.js.map +1 -1
  46. package/package.json +1 -1
  47. package/server.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.d.ts","sourceRoot":"","sources":["../../src/evaluators/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA4G/E"}
1
+ {"version":3,"file":"authentication.d.ts","sourceRoot":"","sources":["../../src/evaluators/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CAoL/E"}
@@ -98,6 +98,73 @@ export function analyzeAuthentication(code, language) {
98
98
  reference: "CWE-295: Improper Certificate Validation",
99
99
  });
100
100
  }
101
+ // No session expiration / no token expiry
102
+ const hasSession = /session|express-session|cookie-session|SessionMiddleware/gi.test(code);
103
+ const hasExpiry = /maxAge|expires|expiresIn|exp:|ttl|timeout.*session|cookie.*max/gi.test(code);
104
+ if (hasSession && !hasExpiry) {
105
+ findings.push({
106
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
107
+ severity: "high",
108
+ title: "Sessions without expiration configured",
109
+ description: "Session middleware is used without visible expiration settings. Sessions that never expire allow stolen session tokens to be used indefinitely.",
110
+ recommendation: "Set session maxAge (e.g., 30 minutes for sensitive apps). Implement idle timeout. Invalidate sessions on password change or logout.",
111
+ reference: "OWASP Session Management Cheat Sheet",
112
+ });
113
+ }
114
+ // Weak password policy — no complexity enforcement
115
+ const hasUserRegistration = /register|signup|sign.?up|createUser|create.*user|new.*user/gi.test(code);
116
+ const hasPasswordPolicy = /minLength|minimum.*length|password.*length|complexity|strongPassword|zxcvbn|password.*policy|password.*require/gi.test(code);
117
+ if (hasUserRegistration && !hasPasswordPolicy) {
118
+ findings.push({
119
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
120
+ severity: "medium",
121
+ title: "No password complexity enforcement",
122
+ description: "User registration logic without visible password policy. Users can set weak passwords like '123456' or 'password', which are trivially guessable.",
123
+ recommendation: "Enforce minimum password length (12+ chars), check against known breached passwords (HaveIBeenPwned API), and use a strength estimator like zxcvbn.",
124
+ reference: "NIST 800-63b / OWASP Password Guidelines",
125
+ });
126
+ }
127
+ // No account lockout after failed attempts
128
+ const hasLogin = /login|signin|sign.?in|authenticate|verifyPassword|checkPassword/gi.test(code);
129
+ const hasLockout = /lockout|lock.*out|attempt|maxAttempt|failedAttempt|rateLimitLogin|brute.?force|account.*lock/gi.test(code);
130
+ if (hasLogin && !hasLockout) {
131
+ findings.push({
132
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
133
+ severity: "medium",
134
+ title: "No account lockout after failed login attempts",
135
+ description: "Login logic without account lockout or rate limiting. Attackers can brute-force passwords by trying unlimited login attempts.",
136
+ recommendation: "Implement progressive delays or temporary lockout after 5-10 failed attempts. Use rate limiting on login endpoints. Consider CAPTCHA for repeated failures.",
137
+ reference: "OWASP Brute Force Prevention / CWE-307",
138
+ });
139
+ }
140
+ // Cookie without Secure and HttpOnly flags
141
+ const cookiePattern = /(?:cookie|Cookie|set-cookie|setCookie|res\.cookie)\s*\(/gi;
142
+ const cookieLines = getLineNumbers(code, cookiePattern);
143
+ const hasSecureFlags = /secure\s*:\s*true|httpOnly\s*:\s*true|HttpOnly|Secure/g.test(code);
144
+ if (cookieLines.length > 0 && !hasSecureFlags) {
145
+ findings.push({
146
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
147
+ severity: "high",
148
+ title: "Cookies set without Secure/HttpOnly flags",
149
+ description: "Cookies are set without Secure (HTTPS-only) or HttpOnly (no JS access) flags. This exposes cookies to interception and XSS-based theft.",
150
+ lineNumbers: cookieLines,
151
+ recommendation: "Set cookies with { secure: true, httpOnly: true, sameSite: 'strict' }. Use Secure for all auth cookies. HttpOnly prevents JavaScript access.",
152
+ reference: "OWASP Secure Cookie Best Practices / CWE-614",
153
+ });
154
+ }
155
+ // No CSRF protection
156
+ const hasFormPost = /app\.post\s*\(|method\s*=\s*["']POST/gi.test(code);
157
+ const hasCsrf = /csrf|csurf|xsrf|_token|csrfToken|antiForgery|X-CSRF|X-XSRF/gi.test(code);
158
+ if (hasFormPost && !hasCsrf && hasSession) {
159
+ findings.push({
160
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
161
+ severity: "high",
162
+ title: "No CSRF protection on form submissions",
163
+ description: "POST endpoints with session-based auth but no CSRF tokens. Attackers can craft pages that submit forms on behalf of authenticated users.",
164
+ recommendation: "Use CSRF tokens (csurf middleware, Django CSRF, Rails authenticity_token). Set SameSite=Strict on cookies. Use custom headers for API calls.",
165
+ reference: "OWASP CSRF Prevention Cheat Sheet / CWE-352",
166
+ });
167
+ }
101
168
  return findings;
102
169
  }
103
170
  //# sourceMappingURL=authentication.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../src/evaluators/authentication.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../src/evaluators/authentication.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"backwards-compatibility.d.ts","sourceRoot":"","sources":["../../src/evaluators/backwards-compatibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA+EvF"}
1
+ {"version":3,"file":"backwards-compatibility.d.ts","sourceRoot":"","sources":["../../src/evaluators/backwards-compatibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA0JvF"}
@@ -71,6 +71,76 @@ export function analyzeBackwardsCompatibility(code, language) {
71
71
  reference: "Semantic Versioning (semver.org)",
72
72
  });
73
73
  }
74
+ // Renamed or removed exports
75
+ const commentedExportPattern = /\/\/\s*export\s+(?:function|class|const|let|type|interface)\s+\w+/g;
76
+ const commentedExportLines = getLineNumbers(code, commentedExportPattern);
77
+ if (commentedExportLines.length > 0) {
78
+ findings.push({
79
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
80
+ severity: "medium",
81
+ title: "Commented-out exports may indicate removed API surface",
82
+ description: `Found ${commentedExportLines.length} commented-out export(s). If these were previously published, removing them is a breaking change for consumers.`,
83
+ lineNumbers: commentedExportLines,
84
+ recommendation: "Re-export removed symbols as deprecated wrappers. Mark them @deprecated with a migration guide. Remove only in the next major version.",
85
+ reference: "Semantic Versioning / API Deprecation Lifecycle",
86
+ });
87
+ }
88
+ // Changed function signatures — optional to required parameter
89
+ const requiredAfterOptionalPattern = /\w+\?:\s*\w+[^)]*,\s*\w+\s*:\s*\w+/g;
90
+ const sigChangeLines = getLineNumbers(code, requiredAfterOptionalPattern);
91
+ if (sigChangeLines.length > 0) {
92
+ findings.push({
93
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
94
+ severity: "low",
95
+ title: "Function signature with required params after optional — potential breaking change",
96
+ description: "Required parameters placed after optional parameters can break callers who relied on positional arguments.",
97
+ lineNumbers: sigChangeLines,
98
+ recommendation: "Keep required parameters before optional ones. Use options objects for functions with many parameters to allow adding fields without breaking callers.",
99
+ reference: "API Design: Function Signature Evolution",
100
+ });
101
+ }
102
+ // Enum/union type removals
103
+ const enumPattern = /enum\s+\w+\s*\{[^}]*\}/g;
104
+ const enumMatches = code.match(enumPattern) || [];
105
+ const hasDeprecatedEnumComment = /\/\/.*deprecated.*enum|\/\/.*removed.*value/gi.test(code);
106
+ if (enumMatches.length > 0 && hasDeprecatedEnumComment) {
107
+ findings.push({
108
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
109
+ severity: "medium",
110
+ title: "Enum value changes may break consumers",
111
+ description: "Enums with deprecated or removed values detected. Removing enum values is a breaking change for anything serializing or deserializing these values.",
112
+ recommendation: "Never remove enum values in minor releases. Mark values as deprecated. If numeric, keep the slot allocated. Provide migration mapping for removed values.",
113
+ reference: "Breaking Changes in Enums / Protocol Buffers Reserved Fields",
114
+ });
115
+ }
116
+ // Changing HTTP methods on endpoints (POST mapping doing DELETE work, etc.)
117
+ const deleteViaPostPattern = /app\.post\s*\([^)]*(?:delete|remove|destroy)/gi;
118
+ const deleteViaPostLines = getLineNumbers(code, deleteViaPostPattern);
119
+ if (deleteViaPostLines.length > 0) {
120
+ findings.push({
121
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
122
+ severity: "low",
123
+ title: "HTTP method mismatch — destructive action via POST",
124
+ description: "Destructive operations (delete, remove) are exposed via POST instead of DELETE. If these were originally DELETE endpoints, the method change breaks REST clients.",
125
+ lineNumbers: deleteViaPostLines,
126
+ recommendation: "Use appropriate HTTP methods: DELETE for removal, PUT/PATCH for updates. If migrating methods, keep the old method working during a deprecation period.",
127
+ reference: "RESTful API Design / HTTP Method Semantics",
128
+ });
129
+ }
130
+ // Breaking serialization changes (renaming JSON fields)
131
+ const fieldRenamePattern = /\/\/\s*(?:renamed|was|previously|old name|formerly)\s*[:=]?\s*\w+/gi;
132
+ const fieldRenameLines = getLineNumbers(code, fieldRenamePattern);
133
+ if (fieldRenameLines.length > 0) {
134
+ findings.push({
135
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
136
+ severity: "medium",
137
+ title: "Possible field rename — breaking serialization change",
138
+ description: `Found ${fieldRenameLines.length} comment(s) suggesting renamed fields. Renaming JSON response fields breaks API clients that depend on the old names.`,
139
+ lineNumbers: fieldRenameLines,
140
+ recommendation: "Include both old and new field names during a transition period. Mark the old field as deprecated. Remove only in the next major version.",
141
+ reference: "API Versioning / Backwards-Compatible JSON Evolution",
142
+ });
143
+ }
74
144
  return findings;
75
145
  }
76
146
  //# sourceMappingURL=backwards-compatibility.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"backwards-compatibility.js","sourceRoot":"","sources":["../../src/evaluators/backwards-compatibility.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"backwards-compatibility.js","sourceRoot":"","sources":["../../src/evaluators/backwards-compatibility.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"caching.d.ts","sourceRoot":"","sources":["../../src/evaluators/caching.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CAiFxE"}
1
+ {"version":3,"file":"caching.d.ts","sourceRoot":"","sources":["../../src/evaluators/caching.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA0JxE"}
@@ -73,6 +73,74 @@ export function analyzeCaching(code, language) {
73
73
  reference: "In-Memory Caching Best Practices",
74
74
  });
75
75
  }
76
+ // Cache key collision risk — simple string concatenation keys
77
+ const cacheKeyPattern = /cache\.(?:set|get|has)\s*\(\s*(?:["'`][^"'`]{1,10}["'`]|`\$\{)/gi;
78
+ const cacheKeyLines = getLineNumbers(code, cacheKeyPattern);
79
+ if (cacheKeyLines.length > 0) {
80
+ findings.push({
81
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
82
+ severity: "low",
83
+ title: "Simple cache keys risk collisions",
84
+ description: `Found ${cacheKeyLines.length} cache operation(s) with short or interpolated keys. Without namespace prefixes or hashing, keys from different features can collide.`,
85
+ lineNumbers: cacheKeyLines,
86
+ recommendation: "Use namespaced, structured cache keys: 'users:byId:${id}'. Include version or tenant info for multi-tenant apps. Consider hashing complex keys.",
87
+ reference: "Cache Key Design Best Practices",
88
+ });
89
+ }
90
+ // Thundering herd / cache stampede — multiple concurrent fetches on miss
91
+ const cacheGetPattern = /cache\.get\s*\(/gi;
92
+ const cacheGetLines = getLineNumbers(code, cacheGetPattern);
93
+ const hasStampedeProtection = /lock|mutex|singleflight|coalesce|dedupe|p-memoize/gi.test(code);
94
+ if (cacheGetLines.length > 0 && !hasStampedeProtection) {
95
+ findings.push({
96
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
97
+ severity: "low",
98
+ title: "No thundering herd protection on cache misses",
99
+ description: "Cache reads without stampede protection. When a popular cache entry expires, many concurrent requests will all miss and hit the backend simultaneously.",
100
+ recommendation: "Implement request coalescing (singleflight pattern) so only one request fetches on a miss. Use stale-while-revalidate or lock-based refresh.",
101
+ reference: "Cache Stampede / Thundering Herd Problem",
102
+ });
103
+ }
104
+ // Caching secrets or tokens
105
+ const cacheSecretPattern = /cache\.(?:set|put)\s*\([^)]*(?:token|secret|password|credential|apikey|api_key)/gi;
106
+ const cacheSecretLines = getLineNumbers(code, cacheSecretPattern);
107
+ if (cacheSecretLines.length > 0) {
108
+ findings.push({
109
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
110
+ severity: "high",
111
+ title: "Secrets or tokens stored in cache",
112
+ description: "Sensitive values (tokens, secrets, passwords) are cached. Cached secrets may persist beyond their intended lifetime and can be exposed via cache inspection.",
113
+ lineNumbers: cacheSecretLines,
114
+ recommendation: "Never cache secrets or authentication tokens. Use a dedicated secrets manager with built-in rotation. If token caching is necessary, encrypt values and set strict TTLs.",
115
+ reference: "OWASP Secrets Management / Cache Security",
116
+ });
117
+ }
118
+ // Stale data served without revalidation
119
+ const hasCacheRead = /cache\.get|cache\.fetch|getFromCache|getCached/gi.test(code);
120
+ const hasRevalidation = /revalidate|stale-while-revalidate|refresh|ETag|If-None-Match|If-Modified-Since|304/gi.test(code);
121
+ if (hasCacheRead && !hasRevalidation && cacheSetLines.length > 0) {
122
+ findings.push({
123
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
124
+ severity: "low",
125
+ title: "Cached data served without revalidation mechanism",
126
+ description: "Data is cached and served without any revalidation strategy. Clients may receive stale data indefinitely until the TTL expires.",
127
+ recommendation: "Implement stale-while-revalidate: serve stale data immediately while refreshing in the background. Use ETags or Last-Modified for conditional fetches.",
128
+ reference: "HTTP Stale-While-Revalidate / RFC 5861",
129
+ });
130
+ }
131
+ // No cache warming strategy
132
+ const hasStartup = /listen\s*\(|bootstrap|main\s*\(|init\s*\(/gi.test(code);
133
+ const hasCacheWarm = /warm|preheat|preload|seed.*cache|cache.*seed|cache.*warm/gi.test(code);
134
+ if (hasStartup && hasCacheRead && !hasCacheWarm && code.split("\n").length > 50) {
135
+ findings.push({
136
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
137
+ severity: "info",
138
+ title: "No cache warming strategy for cold starts",
139
+ description: "Application uses caching but has no visible cache warming on startup. After deployments or restarts, all requests will miss the cache and hit backends simultaneously.",
140
+ recommendation: "Implement cache warming on startup for critical data. Pre-populate frequently accessed keys during deployment. Consider gradual traffic ramp-up after deploys.",
141
+ reference: "Cache Warming / Blue-Green Deployment Best Practices",
142
+ });
143
+ }
76
144
  return findings;
77
145
  }
78
146
  //# sourceMappingURL=caching.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"caching.js","sourceRoot":"","sources":["../../src/evaluators/caching.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,QAAgB;IAC3D,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,MAAM,GAAG,OAAO,CAAC;IAEvB,4BAA4B;IAC5B,MAAM,oBAAoB,GAAG,uEAAuE,CAAC;IACrG,MAAM,kBAAkB,GAAG,cAAc,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IACtE,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,GAAG,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;YACzD,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,oCAAoC;YAC3C,WAAW,EAAE,sJAAsJ;YACnK,WAAW,EAAE,kBAAkB;YAC/B,cAAc,EAAE,kLAAkL;YAClM,SAAS,EAAE,4CAA4C;SACxD,CAAC,CAAC;IACL,CAAC;IAED,sCAAsC;IACtC,MAAM,YAAY,GAAG,4DAA4D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7F,MAAM,QAAQ,GAAG,6CAA6C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1E,MAAM,UAAU,GAAG,yFAAyF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxH,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC9E,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,GAAG,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;YACzD,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,8CAA8C;YACrD,WAAW,EAAE,oKAAoK;YACjL,cAAc,EAAE,uKAAuK;YACvL,SAAS,EAAE,kDAAkD;SAC9D,CAAC,CAAC;IACL,CAAC;IAED,0BAA0B;IAC1B,MAAM,eAAe,GAAG,2CAA2C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/E,MAAM,eAAe,GAAG,+FAA+F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnI,IAAI,eAAe,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACxE,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,GAAG,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;YACzD,QAAQ,EAAE,KAAK;YACf,KAAK,EAAE,6BAA6B;YACpC,WAAW,EAAE,6JAA6J;YAC1K,cAAc,EAAE,8IAA8I;YAC9J,SAAS,EAAE,4CAA4C;SACxD,CAAC,CAAC;IACL,CAAC;IAED,sCAAsC;IACtC,MAAM,eAAe,GAAG,mEAAmE,CAAC;IAC5F,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAC5D,MAAM,eAAe,GAAG,6GAA6G,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjJ,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;QACjD,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,GAAG,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;YACzD,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,4CAA4C;YACnD,WAAW,EAAE,qIAAqI;YAClJ,WAAW,EAAE,aAAa;YAC1B,cAAc,EAAE,uJAAuJ;YACvK,SAAS,EAAE,+BAA+B;SAC3C,CAAC,CAAC;IACL,CAAC;IAED,sCAAsC;IACtC,MAAM,yBAAyB,GAAG,8CAA8C,CAAC;IACjF,MAAM,gBAAgB,GAAG,cAAc,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAAC;IACzE,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,GAAG,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;YACzD,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,qCAAqC;YAC5C,WAAW,EAAE,oKAAoK;YACjL,WAAW,EAAE,gBAAgB;YAC7B,cAAc,EAAE,wJAAwJ;YACxK,SAAS,EAAE,kCAAkC;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"caching.js","sourceRoot":"","sources":["../../src/evaluators/caching.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ci-cd.d.ts","sourceRoot":"","sources":["../../src/evaluators/ci-cd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA6FrE"}
1
+ {"version":3,"file":"ci-cd.d.ts","sourceRoot":"","sources":["../../src/evaluators/ci-cd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CAoKrE"}
@@ -84,6 +84,72 @@ export function analyzeCiCd(code, language) {
84
84
  reference: "Docker Best Practices / Supply Chain Security",
85
85
  });
86
86
  }
87
+ // Dockerfile without .dockerignore
88
+ const hasDockerfile = /^FROM\s+/gim.test(code);
89
+ const hasDockerignore = /\.dockerignore/gi.test(code);
90
+ const copiesEverything = /COPY\s+\.\s+\.|ADD\s+\.\s+\./gi.test(code);
91
+ if (hasDockerfile && copiesEverything && !hasDockerignore) {
92
+ findings.push({
93
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
94
+ severity: "medium",
95
+ title: "Dockerfile copies everything without .dockerignore",
96
+ description: "COPY . . or ADD . . copies the entire build context including node_modules, .git, .env, and other unnecessary files. This bloats images and may expose secrets.",
97
+ recommendation: "Create a .dockerignore file excluding node_modules, .git, .env, test files, and build artifacts. Only copy files needed for production.",
98
+ reference: "Docker Best Practices: .dockerignore / Multi-Stage Builds",
99
+ });
100
+ }
101
+ // Dockerfile without HEALTHCHECK
102
+ if (hasDockerfile && !/HEALTHCHECK/gi.test(code)) {
103
+ findings.push({
104
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
105
+ severity: "low",
106
+ title: "Dockerfile without HEALTHCHECK instruction",
107
+ description: "Docker container has no HEALTHCHECK defined. Without health checks, orchestrators (Docker Compose, Kubernetes) cannot detect unhealthy containers for restart.",
108
+ recommendation: "Add a HEALTHCHECK instruction: HEALTHCHECK --interval=30s CMD curl -f http://localhost:3000/health || exit 1. Or define health checks in docker-compose/k8s.",
109
+ reference: "Docker HEALTHCHECK / Container Health Best Practices",
110
+ });
111
+ }
112
+ // No test coverage configuration
113
+ const hasTests = /test|jest|mocha|vitest|ava|tape|jasmine|karma/gi.test(code);
114
+ const hasCoverage = /coverage|istanbul|nyc|c8|--coverage|coverageThreshold|coverageDirectory|lcov/gi.test(code);
115
+ if (hasTests && !hasCoverage) {
116
+ findings.push({
117
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
118
+ severity: "info",
119
+ title: "Test configuration without coverage tracking",
120
+ description: "Test tooling is referenced but no code coverage configuration is visible. Without coverage tracking, gaps in test coverage go undetected.",
121
+ recommendation: "Configure coverage reporting (jest --coverage, c8, nyc). Set minimum coverage thresholds. Integrate coverage reports into CI/CD pipeline.",
122
+ reference: "Jest Coverage / Istanbul.js",
123
+ });
124
+ }
125
+ // npm install instead of npm ci in CI
126
+ const npmInstallPattern = /npm\s+install(?!\s+--save|\s+-[gDEOS]|\s+\w)/gi;
127
+ const npmInstallLines = getLineNumbers(code, npmInstallPattern);
128
+ const isCIConfig = /\.github\/workflows|\.gitlab-ci|jenkinsfile|\.circleci|pipeline|ci\s*:/gi.test(code);
129
+ if (npmInstallLines.length > 0 && isCIConfig) {
130
+ findings.push({
131
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
132
+ severity: "medium",
133
+ title: "Using 'npm install' instead of 'npm ci' in CI",
134
+ description: "CI configuration uses 'npm install' which may modify package-lock.json and install different versions than intended. This makes builds non-deterministic.",
135
+ lineNumbers: npmInstallLines,
136
+ recommendation: "Use 'npm ci' in CI/CD pipelines for clean, reproducible installs from the lockfile. Only use 'npm install' during local development.",
137
+ reference: "npm ci Documentation / Reproducible Builds",
138
+ });
139
+ }
140
+ // Running as root in Docker
141
+ const hasRootUser = /^USER\s+root/gim.test(code);
142
+ const hasNonRootUser = /^USER\s+(?!root)\w+/gim.test(code);
143
+ if (hasDockerfile && !hasNonRootUser) {
144
+ findings.push({
145
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
146
+ severity: "high",
147
+ title: "Docker container runs as root user",
148
+ description: "No non-root USER instruction found in Dockerfile. Running as root inside containers increases the blast radius of container escape vulnerabilities.",
149
+ recommendation: "Add a non-root user: RUN addgroup -S app && adduser -S app -G app, then USER app. Use the --chown flag with COPY.",
150
+ reference: "Docker Security: Run as Non-Root / CIS Docker Benchmark",
151
+ });
152
+ }
87
153
  return findings;
88
154
  }
89
155
  //# sourceMappingURL=ci-cd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ci-cd.js","sourceRoot":"","sources":["../../src/evaluators/ci-cd.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ci-cd.js","sourceRoot":"","sources":["../../src/evaluators/ci-cd.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"configuration-management.d.ts","sourceRoot":"","sources":["../../src/evaluators/configuration-management.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA+ExF"}
1
+ {"version":3,"file":"configuration-management.d.ts","sourceRoot":"","sources":["../../src/evaluators/configuration-management.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA0JxF"}
@@ -71,6 +71,76 @@ export function analyzeConfigurationManagement(code, language) {
71
71
  reference: "12-Factor App: Config / dotenv Best Practices",
72
72
  });
73
73
  }
74
+ // Missing defaults on process.env reads
75
+ const envNoDefaultPattern = /process\.env\.\w+(?!\s*\|\||[^;\n]*?(?:\?\?|default|fallback))/g;
76
+ const envNoDefaultLines = getLineNumbers(code, envNoDefaultPattern);
77
+ const envWithDefaultPattern = /process\.env\.\w+\s*(?:\|\||&&|\?\?)/g;
78
+ const envWithDefaults = (code.match(envWithDefaultPattern) || []).length;
79
+ const envTotal = envNoDefaultLines.length;
80
+ if (envTotal > 0 && envWithDefaults === 0) {
81
+ findings.push({
82
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
83
+ severity: "low",
84
+ title: "Environment variable reads without defaults",
85
+ description: `Found ${envTotal} process.env reads without fallback defaults. Missing env vars will silently be undefined at runtime, causing hard-to-debug issues.`,
86
+ lineNumbers: envNoDefaultLines.slice(0, 5),
87
+ recommendation: "Provide defaults: process.env.PORT || 3000, or validate at startup that required variables are present. Use a config library that enforces defaults.",
88
+ reference: "Node.js Configuration Best Practices",
89
+ });
90
+ }
91
+ // Hardcoded feature flags
92
+ const featureFlagPattern = /(?:const|let|var)\s+(?:ENABLE|DISABLE|FEATURE|FLAG|TOGGLE|ALLOW|USE)_\w+\s*=\s*(?:true|false)/gi;
93
+ const featureFlagLines = getLineNumbers(code, featureFlagPattern);
94
+ if (featureFlagLines.length > 0) {
95
+ findings.push({
96
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
97
+ severity: "low",
98
+ title: "Feature flags hardcoded as constants",
99
+ description: `Found ${featureFlagLines.length} hardcoded feature flag(s). Hardcoded flags require code changes and redeployment to toggle features.`,
100
+ lineNumbers: featureFlagLines,
101
+ recommendation: "Use a feature flag service (LaunchDarkly, Unleash, AWS AppConfig) or environment variables. This allows toggling features without deploying.",
102
+ reference: "Feature Flag Best Practices / Martin Fowler: Feature Toggles",
103
+ });
104
+ }
105
+ // No secret rotation mechanism
106
+ const hasSecrets = /(?:password|secret|api_?key|token|private_?key)\s*[:=]/gi.test(code);
107
+ const hasRotation = /rotate|rotation|expir|renew|refresh.*token|refresh.*secret/gi.test(code);
108
+ if (hasSecrets && !hasRotation && code.split("\n").length > 30) {
109
+ findings.push({
110
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
111
+ severity: "low",
112
+ title: "No secret rotation mechanism detected",
113
+ description: "Secrets are used but no rotation logic is visible. Secrets that cannot be rotated become a liability — a single leak requires emergency credential replacement.",
114
+ recommendation: "Design for secret rotation: use short-lived tokens, implement token refresh flows, and use secrets managers with automatic rotation (Azure Key Vault, AWS Secrets Manager).",
115
+ reference: "NIST 800-53: Secret Rotation / Zero Trust Principles",
116
+ });
117
+ }
118
+ // Missing config schema / documentation
119
+ const hasConfigSchema = /schema|convict|joi\.object|zod\.object|yup\.object|ajv|configSchema|configSpec/gi.test(code);
120
+ if (hasEnvVars && !hasConfigSchema && code.split("\n").length > 40) {
121
+ findings.push({
122
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
123
+ severity: "info",
124
+ title: "No configuration schema or documentation",
125
+ description: "Environment variables are read but no config schema is defined. New developers won't know which variables are required, what types they should be, or what values are valid.",
126
+ recommendation: "Define a config schema using convict, Zod, or Joi. Document every env var in a .env.example file with comments explaining purpose, type, and valid values.",
127
+ reference: "Configuration Schema Validation / 12-Factor App",
128
+ });
129
+ }
130
+ // Environment-specific code
131
+ const envSpecificPattern = /(?:if|switch|case)\s*.*(?:NODE_ENV|ENVIRONMENT|ENV)\s*(?:===?|!==?|==)\s*["'`](?:production|staging|development|test)/gi;
132
+ const envSpecificLines = getLineNumbers(code, envSpecificPattern);
133
+ if (envSpecificLines.length > 2) {
134
+ findings.push({
135
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
136
+ severity: "low",
137
+ title: "Excessive environment-specific branching in code",
138
+ description: `Found ${envSpecificLines.length} environment-specific conditional(s). Too many if(NODE_ENV) checks scatter config logic across the codebase instead of centralizing it.`,
139
+ lineNumbers: envSpecificLines.slice(0, 5),
140
+ recommendation: "Centralize environment-specific config in a config module. Use dependency injection or config objects rather than environment checks throughout the codebase.",
141
+ reference: "12-Factor App: Config / Clean Architecture",
142
+ });
143
+ }
74
144
  return findings;
75
145
  }
76
146
  //# sourceMappingURL=configuration-management.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"configuration-management.js","sourceRoot":"","sources":["../../src/evaluators/configuration-management.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configuration-management.js","sourceRoot":"","sources":["../../src/evaluators/configuration-management.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/evaluators/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CAkIzE"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/evaluators/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA4LzE"}
@@ -120,6 +120,60 @@ export function analyzeDatabase(code, language) {
120
120
  reference: "12-Factor App: Config / OWASP Secrets Management",
121
121
  });
122
122
  }
123
+ // DROP TABLE / TRUNCATE without safeguards
124
+ const destructiveDbPattern = /(?:DROP\s+TABLE|TRUNCATE\s+TABLE|DROP\s+DATABASE|DROP\s+SCHEMA)/gi;
125
+ const destructiveDbLines = getLineNumbers(code, destructiveDbPattern);
126
+ if (destructiveDbLines.length > 0) {
127
+ findings.push({
128
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
129
+ severity: "critical",
130
+ title: "Destructive DDL statements in application code",
131
+ description: `Found ${destructiveDbLines.length} DROP/TRUNCATE statement(s). These permanently delete data or schema. If executed accidentally (e.g., via injection), data loss is irreversible.`,
132
+ lineNumbers: destructiveDbLines,
133
+ recommendation: "Never run destructive DDL from application code. Use migration tools (Prisma, Flyway, Alembic) with review and rollback support. Require elevated permissions for DDL.",
134
+ reference: "Database Migration Best Practices / Least Privilege",
135
+ });
136
+ }
137
+ // No migration tooling
138
+ const hasMigrations = /migration|migrate|knex\.schema|Schema\.create|CreateTable|createTable|sequelize\.define|prisma\s+migrate|alembic|flyway|liquibase|db-migrate|umzug/gi.test(code);
139
+ const hasSchemaChanges = /CREATE\s+TABLE|ALTER\s+TABLE|ADD\s+COLUMN|DROP\s+COLUMN/gi.test(code);
140
+ if (hasSchemaChanges && !hasMigrations) {
141
+ findings.push({
142
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
143
+ severity: "medium",
144
+ title: "Schema changes without migration tooling",
145
+ description: "DDL statements (CREATE TABLE, ALTER TABLE) found without migration tooling. Manual schema changes are unreproducible and error-prone across environments.",
146
+ recommendation: "Use a database migration tool (Prisma, Knex, Flyway, Alembic) to version schema changes. Migrations should be idempotent and reversible.",
147
+ reference: "Database Migration Best Practices / Evolutionary Database Design",
148
+ });
149
+ }
150
+ // Missing database indexes heuristic
151
+ const hasWhereClause = /WHERE\s+\w+\s*(?:=|IN\s*\(|LIKE|>|<|BETWEEN)/gi.test(code);
152
+ const hasIndexHint = /CREATE\s+INDEX|ADD\s+INDEX|ensureIndex|createIndex|\.index\s*\(/gi.test(code);
153
+ if (hasWhereClause && !hasIndexHint && rawSqlLines.length > 2) {
154
+ findings.push({
155
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
156
+ severity: "low",
157
+ title: "Queries with WHERE clauses but no index definitions",
158
+ description: "SQL queries filter on columns but no index creation is visible. Without indexes, queries perform full table scans which degrade exponentially with data volume.",
159
+ recommendation: "Create indexes on columns used in WHERE, JOIN, and ORDER BY clauses. Monitor slow query logs. Use EXPLAIN to verify query plans.",
160
+ reference: "SQL Indexing Best Practices / Use The Index, Luke!",
161
+ });
162
+ }
163
+ // Database credentials in connection string
164
+ const credInConnPattern = /(?:postgres|mysql|mongodb|mssql):\/\/\w+:\w+@/gi;
165
+ const credInConnLines = getLineNumbers(code, credInConnPattern);
166
+ if (credInConnLines.length > 0) {
167
+ findings.push({
168
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
169
+ severity: "high",
170
+ title: "Database credentials embedded in connection string",
171
+ description: "Connection string contains inline username and password. These credentials are visible in source code, logs, and process listings.",
172
+ lineNumbers: credInConnLines,
173
+ recommendation: "Use separate credential parameters or environment variables. Consider IAM/managed identity for passwordless database connections in cloud environments.",
174
+ reference: "OWASP: Credential Management / Azure Managed Identity",
175
+ });
176
+ }
123
177
  return findings;
124
178
  }
125
179
  //# sourceMappingURL=database.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/evaluators/database.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/evaluators/database.ts"],"names":[],"mappings":"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"}