@korayda4/vibe-security 0.3.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 +240 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +333 -0
- package/dist/cli.js.map +1 -0
- package/dist/engine/baseline.d.ts +19 -0
- package/dist/engine/baseline.js +48 -0
- package/dist/engine/baseline.js.map +1 -0
- package/dist/engine/config.d.ts +26 -0
- package/dist/engine/config.js +41 -0
- package/dist/engine/config.js.map +1 -0
- package/dist/engine/fixer.d.ts +22 -0
- package/dist/engine/fixer.js +87 -0
- package/dist/engine/fixer.js.map +1 -0
- package/dist/engine/language.d.ts +27 -0
- package/dist/engine/language.js +364 -0
- package/dist/engine/language.js.map +1 -0
- package/dist/engine/output.d.ts +6 -0
- package/dist/engine/output.js +155 -0
- package/dist/engine/output.js.map +1 -0
- package/dist/engine/reporter.d.ts +3 -0
- package/dist/engine/reporter.js +145 -0
- package/dist/engine/reporter.js.map +1 -0
- package/dist/engine/rules/_helpers.d.ts +9 -0
- package/dist/engine/rules/_helpers.js +64 -0
- package/dist/engine/rules/_helpers.js.map +1 -0
- package/dist/engine/rules/backend/fileUpload.d.ts +3 -0
- package/dist/engine/rules/backend/fileUpload.js +40 -0
- package/dist/engine/rules/backend/fileUpload.js.map +1 -0
- package/dist/engine/rules/backend/hashing.d.ts +3 -0
- package/dist/engine/rules/backend/hashing.js +40 -0
- package/dist/engine/rules/backend/hashing.js.map +1 -0
- package/dist/engine/rules/backend/idor.d.ts +3 -0
- package/dist/engine/rules/backend/idor.js +40 -0
- package/dist/engine/rules/backend/idor.js.map +1 -0
- package/dist/engine/rules/backend/index.d.ts +12 -0
- package/dist/engine/rules/backend/index.js +22 -0
- package/dist/engine/rules/backend/index.js.map +1 -0
- package/dist/engine/rules/backend/inputValidation.d.ts +3 -0
- package/dist/engine/rules/backend/inputValidation.js +37 -0
- package/dist/engine/rules/backend/inputValidation.js.map +1 -0
- package/dist/engine/rules/backend/jwt.d.ts +3 -0
- package/dist/engine/rules/backend/jwt.js +42 -0
- package/dist/engine/rules/backend/jwt.js.map +1 -0
- package/dist/engine/rules/backend/rateLimit.d.ts +3 -0
- package/dist/engine/rules/backend/rateLimit.js +45 -0
- package/dist/engine/rules/backend/rateLimit.js.map +1 -0
- package/dist/engine/rules/backend/sqlInjection.d.ts +3 -0
- package/dist/engine/rules/backend/sqlInjection.js +41 -0
- package/dist/engine/rules/backend/sqlInjection.js.map +1 -0
- package/dist/engine/rules/backend/tokenExpiry.d.ts +3 -0
- package/dist/engine/rules/backend/tokenExpiry.js +85 -0
- package/dist/engine/rules/backend/tokenExpiry.js.map +1 -0
- package/dist/engine/rules/backend/tokenInUrl.d.ts +3 -0
- package/dist/engine/rules/backend/tokenInUrl.js +112 -0
- package/dist/engine/rules/backend/tokenInUrl.js.map +1 -0
- package/dist/engine/rules/cicd/dependencies.d.ts +3 -0
- package/dist/engine/rules/cicd/dependencies.js +44 -0
- package/dist/engine/rules/cicd/dependencies.js.map +1 -0
- package/dist/engine/rules/cicd/dockerfile.d.ts +3 -0
- package/dist/engine/rules/cicd/dockerfile.js +42 -0
- package/dist/engine/rules/cicd/dockerfile.js.map +1 -0
- package/dist/engine/rules/cicd/index.d.ts +6 -0
- package/dist/engine/rules/cicd/index.js +10 -0
- package/dist/engine/rules/cicd/index.js.map +1 -0
- package/dist/engine/rules/cicd/secrets.d.ts +3 -0
- package/dist/engine/rules/cicd/secrets.js +41 -0
- package/dist/engine/rules/cicd/secrets.js.map +1 -0
- package/dist/engine/rules/database/encryption.d.ts +3 -0
- package/dist/engine/rules/database/encryption.js +37 -0
- package/dist/engine/rules/database/encryption.js.map +1 -0
- package/dist/engine/rules/database/index.d.ts +5 -0
- package/dist/engine/rules/database/index.js +8 -0
- package/dist/engine/rules/database/index.js.map +1 -0
- package/dist/engine/rules/database/privileges.d.ts +3 -0
- package/dist/engine/rules/database/privileges.js +40 -0
- package/dist/engine/rules/database/privileges.js.map +1 -0
- package/dist/engine/rules/frontend/clickjacking.d.ts +3 -0
- package/dist/engine/rules/frontend/clickjacking.js +41 -0
- package/dist/engine/rules/frontend/clickjacking.js.map +1 -0
- package/dist/engine/rules/frontend/cookies.d.ts +3 -0
- package/dist/engine/rules/frontend/cookies.js +35 -0
- package/dist/engine/rules/frontend/cookies.js.map +1 -0
- package/dist/engine/rules/frontend/envVars.d.ts +3 -0
- package/dist/engine/rules/frontend/envVars.js +34 -0
- package/dist/engine/rules/frontend/envVars.js.map +1 -0
- package/dist/engine/rules/frontend/eval.d.ts +3 -0
- package/dist/engine/rules/frontend/eval.js +35 -0
- package/dist/engine/rules/frontend/eval.js.map +1 -0
- package/dist/engine/rules/frontend/index.d.ts +9 -0
- package/dist/engine/rules/frontend/index.js +16 -0
- package/dist/engine/rules/frontend/index.js.map +1 -0
- package/dist/engine/rules/frontend/sourceMaps.d.ts +3 -0
- package/dist/engine/rules/frontend/sourceMaps.js +79 -0
- package/dist/engine/rules/frontend/sourceMaps.js.map +1 -0
- package/dist/engine/rules/frontend/xss.d.ts +3 -0
- package/dist/engine/rules/frontend/xss.js +70 -0
- package/dist/engine/rules/frontend/xss.js.map +1 -0
- package/dist/engine/rules/index.d.ts +8 -0
- package/dist/engine/rules/index.js +38 -0
- package/dist/engine/rules/index.js.map +1 -0
- package/dist/engine/rules/kotlin/index.d.ts +5 -0
- package/dist/engine/rules/kotlin/index.js +8 -0
- package/dist/engine/rules/kotlin/index.js.map +1 -0
- package/dist/engine/rules/kotlin/kotlinxHtml.d.ts +3 -0
- package/dist/engine/rules/kotlin/kotlinxHtml.js +54 -0
- package/dist/engine/rules/kotlin/kotlinxHtml.js.map +1 -0
- package/dist/engine/rules/kotlin/sqlInjection.d.ts +3 -0
- package/dist/engine/rules/kotlin/sqlInjection.js +57 -0
- package/dist/engine/rules/kotlin/sqlInjection.js.map +1 -0
- package/dist/engine/rules/network/cors.d.ts +3 -0
- package/dist/engine/rules/network/cors.js +106 -0
- package/dist/engine/rules/network/cors.js.map +1 -0
- package/dist/engine/rules/network/headers.d.ts +3 -0
- package/dist/engine/rules/network/headers.js +51 -0
- package/dist/engine/rules/network/headers.js.map +1 -0
- package/dist/engine/rules/network/index.d.ts +6 -0
- package/dist/engine/rules/network/index.js +10 -0
- package/dist/engine/rules/network/index.js.map +1 -0
- package/dist/engine/rules/network/tls.d.ts +3 -0
- package/dist/engine/rules/network/tls.js +40 -0
- package/dist/engine/rules/network/tls.js.map +1 -0
- package/dist/engine/rules/observability/errorHandler.d.ts +3 -0
- package/dist/engine/rules/observability/errorHandler.js +34 -0
- package/dist/engine/rules/observability/errorHandler.js.map +1 -0
- package/dist/engine/rules/observability/index.d.ts +5 -0
- package/dist/engine/rules/observability/index.js +8 -0
- package/dist/engine/rules/observability/index.js.map +1 -0
- package/dist/engine/rules/observability/logging.d.ts +3 -0
- package/dist/engine/rules/observability/logging.js +38 -0
- package/dist/engine/rules/observability/logging.js.map +1 -0
- package/dist/engine/rules/php/index.d.ts +6 -0
- package/dist/engine/rules/php/index.js +10 -0
- package/dist/engine/rules/php/index.js.map +1 -0
- package/dist/engine/rules/php/sqlInjection.d.ts +3 -0
- package/dist/engine/rules/php/sqlInjection.js +58 -0
- package/dist/engine/rules/php/sqlInjection.js.map +1 -0
- package/dist/engine/rules/php/weakHashing.d.ts +3 -0
- package/dist/engine/rules/php/weakHashing.js +36 -0
- package/dist/engine/rules/php/weakHashing.js.map +1 -0
- package/dist/engine/rules/php/xss.d.ts +3 -0
- package/dist/engine/rules/php/xss.js +56 -0
- package/dist/engine/rules/php/xss.js.map +1 -0
- package/dist/engine/rules/ruby/index.d.ts +6 -0
- package/dist/engine/rules/ruby/index.js +10 -0
- package/dist/engine/rules/ruby/index.js.map +1 -0
- package/dist/engine/rules/ruby/sqlInjection.d.ts +3 -0
- package/dist/engine/rules/ruby/sqlInjection.js +56 -0
- package/dist/engine/rules/ruby/sqlInjection.js.map +1 -0
- package/dist/engine/rules/ruby/strongParams.d.ts +3 -0
- package/dist/engine/rules/ruby/strongParams.js +35 -0
- package/dist/engine/rules/ruby/strongParams.js.map +1 -0
- package/dist/engine/rules/ruby/xss.d.ts +3 -0
- package/dist/engine/rules/ruby/xss.js +55 -0
- package/dist/engine/rules/ruby/xss.js.map +1 -0
- package/dist/engine/rules/rust/index.d.ts +6 -0
- package/dist/engine/rules/rust/index.js +10 -0
- package/dist/engine/rules/rust/index.js.map +1 -0
- package/dist/engine/rules/rust/secretInCode.d.ts +3 -0
- package/dist/engine/rules/rust/secretInCode.js +36 -0
- package/dist/engine/rules/rust/secretInCode.js.map +1 -0
- package/dist/engine/rules/rust/sqlInjection.d.ts +3 -0
- package/dist/engine/rules/rust/sqlInjection.js +55 -0
- package/dist/engine/rules/rust/sqlInjection.js.map +1 -0
- package/dist/engine/rules/rust/unsafeExpect.d.ts +3 -0
- package/dist/engine/rules/rust/unsafeExpect.js +56 -0
- package/dist/engine/rules/rust/unsafeExpect.js.map +1 -0
- package/dist/engine/scanner.d.ts +5 -0
- package/dist/engine/scanner.js +135 -0
- package/dist/engine/scanner.js.map +1 -0
- package/dist/engine/walker.d.ts +11 -0
- package/dist/engine/walker.js +90 -0
- package/dist/engine/walker.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +36 -0
- package/dist/server.js +360 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +92 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputValidation.js","sourceRoot":"","sources":["../../../../src/engine/rules/backend/inputValidation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,mDAAmD;IAC1D,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,MAAM;IAChB,WAAW,EACT,uOAAuO;IACzO,MAAM,EAAE,6DAA6D;IACrE,WAAW,EACT,yEAAyE;QACzE,2DAA2D;QAC3D,qGAAqG;QACrG,qGAAqG;QACrG,qFAAqF;IACvF,UAAU,EAAE;QACV,iFAAiF;QACjF,kBAAkB;KACnB;IACD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,0BAA0B;IACjC,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,QAAQ,GAAa;YAC/B,8GAA8G;YACxG,gGAAgG;YACtG,8BAA8B;YAC9B,+BAA+B;YAC/B,iDAAiD;SAC5C,CAAC;QAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { grepRule } from '../_helpers.js';
|
|
2
|
+
const rule = {
|
|
3
|
+
id: 'BE-003',
|
|
4
|
+
title: 'Insecure JWT configuration (alg: none / weak secret / no verify)',
|
|
5
|
+
layer: 'backend',
|
|
6
|
+
severity: 'critical',
|
|
7
|
+
description: 'JWT token uretimi veya dogrulamasi yapilirken `alg: none`, zayif HMAC secret, hardcoded secret veya `verify` atlama gibi hatalar yapildiginda saldirgan imzayi atlayip kendi token\'ini uretebilir.',
|
|
8
|
+
threat: 'Authentication bypass → full account takeover',
|
|
9
|
+
remediation: '1) **Asla `alg: none`** kullanmayin; her zaman explicit `algorithms: [\'RS256\']` veya `[\'HS256\']` whitelist edin. ' +
|
|
10
|
+
'2) HMAC secret\'i en az 256-bit (32 byte) random uretin, **asla** commit\'lemeyin. Asimetrik (RS256/ES256) tercih edin. ' +
|
|
11
|
+
'3) `jwt.verify()` her zaman cagirin, payload\'i dogrudan kabul etmeyin. ' +
|
|
12
|
+
'4) `exp`, `iss`, `aud` claim\'lerini dogrulayin. ' +
|
|
13
|
+
'5) Access token\'i 15 dakika ile sinirlayin, refresh token icin rotation + revocation store kullanin. ' +
|
|
14
|
+
'6) `Authorization: Bearer` basligini okuyun, query string\'de token tasimalarini reddedin.',
|
|
15
|
+
references: [
|
|
16
|
+
'https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html',
|
|
17
|
+
'https://datatracker.ietf.org/doc/html/rfc8725',
|
|
18
|
+
'https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/',
|
|
19
|
+
],
|
|
20
|
+
cwe: 'CWE-347',
|
|
21
|
+
owasp: 'A02:2021 Cryptographic Failures',
|
|
22
|
+
languages: ['javascript', 'typescript', 'python', 'java', 'go'],
|
|
23
|
+
check: (ctx) => {
|
|
24
|
+
const patterns = [
|
|
25
|
+
/algorithm\s*[:=]\s*['"`]none['"`]/gi,
|
|
26
|
+
/algorithms\s*:\s*\[\s*['"`]none['"`]\s*\]/g,
|
|
27
|
+
/jwt\.sign\s*\([^)]*['"`\s]none['"`\s]/gi,
|
|
28
|
+
/jwt\.decode\s*\([^)]*\)/g, // decode without verify
|
|
29
|
+
/['"`]secret['"`]\s*[:=]\s*['"`][a-zA-Z0-9_\-]{1,31}['"`]/g, // short hardcoded secret
|
|
30
|
+
/JWT_SECRET\s*[:=]\s*['"`][^'"`\n]{1,15}['"`]/g,
|
|
31
|
+
/verify\s*:\s*false/gi,
|
|
32
|
+
/verify=False/g,
|
|
33
|
+
];
|
|
34
|
+
const findings = [];
|
|
35
|
+
for (const re of patterns) {
|
|
36
|
+
findings.push(...grepRule(rule, ctx, re));
|
|
37
|
+
}
|
|
38
|
+
return findings;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
export default rule;
|
|
42
|
+
//# sourceMappingURL=jwt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../../../src/engine/rules/backend/jwt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,kEAAkE;IACzE,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,UAAU;IACpB,WAAW,EACT,qMAAqM;IACvM,MAAM,EAAE,+CAA+C;IACvD,WAAW,EACT,uHAAuH;QACvH,0HAA0H;QAC1H,0EAA0E;QAC1E,mDAAmD;QACnD,wGAAwG;QACxG,4FAA4F;IAC9F,UAAU,EAAE;QACV,yFAAyF;QACzF,+CAA+C;QAC/C,8EAA8E;KAC/E;IACD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,iCAAiC;IACxC,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,QAAQ,GAAa;YACzB,qCAAqC;YACrC,4CAA4C;YAC5C,yCAAyC;YACzC,0BAA0B,EAAE,wBAAwB;YACpD,2DAA2D,EAAE,yBAAyB;YACtF,+CAA+C;YAC/C,sBAAsB;YACtB,eAAe;SAChB,CAAC;QAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { grepRule } from '../_helpers.js';
|
|
2
|
+
const rule = {
|
|
3
|
+
id: 'BE-006',
|
|
4
|
+
title: 'Missing rate limiting / throttling on sensitive endpoints',
|
|
5
|
+
layer: 'backend',
|
|
6
|
+
severity: 'medium',
|
|
7
|
+
description: 'Login, signup, password reset, OTP dogrulama gibi endpointlerde rate limiting yoksa brute-force, credential stuffing ve DoS kolaylastirilir.',
|
|
8
|
+
threat: 'Brute force, credential stuffing, OTP enumeration, denial of service, scraping',
|
|
9
|
+
remediation: '1) **express-rate-limit**, **rate-limiter-flexible**, **slowapi** (Python) kullanin. ' +
|
|
10
|
+
'2) IP bazli + user/token bazli iki katman uygulayin. ' +
|
|
11
|
+
'3) Login endpointleri icin 5 deneme / 15 dakika cap\'i koyun. ' +
|
|
12
|
+
'4) Exponential backoff ile basarisiz denemeleri yavaslatin. ' +
|
|
13
|
+
'5) 5 basarisiz denemede account\'u gecici kilitleyin + kullaniciya bildirim gonderin. ' +
|
|
14
|
+
'6) Captcha veya Turnstile ekleyin. ' +
|
|
15
|
+
'7) Edge seviyesinde (Cloudflare, API Gateway) global limit ekleyin.',
|
|
16
|
+
references: [
|
|
17
|
+
'https://owasp.org/www-community/controls/Blocking_Brute_Force_Attacks',
|
|
18
|
+
'https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#login-throttling',
|
|
19
|
+
],
|
|
20
|
+
cwe: 'CWE-307',
|
|
21
|
+
owasp: 'A07:2021 Identification and Authentication Failures',
|
|
22
|
+
languages: ['javascript', 'typescript', 'python', 'java', 'go'],
|
|
23
|
+
check: (ctx) => {
|
|
24
|
+
const isServerFile = /(?:server|app|main|index|routes)\.(?:ts|js|py|go|java)$/i.test(ctx.relativePath) ||
|
|
25
|
+
/\/routes?\//i.test(ctx.relativePath) ||
|
|
26
|
+
/\/api\//i.test(ctx.relativePath);
|
|
27
|
+
if (!isServerFile)
|
|
28
|
+
return [];
|
|
29
|
+
const hasRateLimit = /rate[-_]?limit|rateLimit|throttle|bruteforce|slowapi|express-rate-limit/i.test(ctx.source);
|
|
30
|
+
if (hasRateLimit)
|
|
31
|
+
return [];
|
|
32
|
+
const authRoutes = [
|
|
33
|
+
/\bapp\.(?:post|put|get)\s*\(\s*['"`](?:\/api)?\/?(?:login|signin|signup|register|auth|reset-?password|forgot-?password|verify-?otp|2fa)/gi,
|
|
34
|
+
/@app\.route\s*\(\s*['"`](?:\/api)?\/?(?:login|signin|signup|register|auth|reset-?password|forgot-?password)/gi,
|
|
35
|
+
/router\.post\s*\(\s*['"`](?:\/api)?\/?(?:login|signin|signup|register|auth|reset-?password|forgot-?password)/gi,
|
|
36
|
+
];
|
|
37
|
+
const findings = [];
|
|
38
|
+
for (const re of authRoutes) {
|
|
39
|
+
findings.push(...grepRule(rule, ctx, re));
|
|
40
|
+
}
|
|
41
|
+
return findings;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
export default rule;
|
|
45
|
+
//# sourceMappingURL=rateLimit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../../../src/engine/rules/backend/rateLimit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,2DAA2D;IAClE,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,QAAQ;IAClB,WAAW,EACT,8IAA8I;IAChJ,MAAM,EAAE,gFAAgF;IACxF,WAAW,EACT,uFAAuF;QACvF,uDAAuD;QACvD,gEAAgE;QAChE,8DAA8D;QAC9D,wFAAwF;QACxF,qCAAqC;QACrC,qEAAqE;IACvE,UAAU,EAAE;QACV,uEAAuE;QACvE,iGAAiG;KAClG;IACD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,qDAAqD;IAC5D,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,YAAY,GAChB,0DAA0D,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC;YACjF,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC;YACrC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAEpC,IAAI,CAAC,YAAY;YAAE,OAAO,EAAE,CAAC;QAE7B,MAAM,YAAY,GAChB,0EAA0E,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE9F,IAAI,YAAY;YAAE,OAAO,EAAE,CAAC;QAE5B,MAAM,UAAU,GAAG;YACjB,2IAA2I;YAC3I,+GAA+G;YAC/G,gHAAgH;SACjH,CAAC;QAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { grepRule } from '../_helpers.js';
|
|
2
|
+
const rule = {
|
|
3
|
+
id: 'BE-004',
|
|
4
|
+
title: 'SQL / NoSQL injection via string concatenation',
|
|
5
|
+
layer: 'backend',
|
|
6
|
+
severity: 'critical',
|
|
7
|
+
description: 'SQL sorgulari veya NoSQL filtreleri string concatenation / template literals ile olusturuldugunda, kullanici girdisi sorgu yapisina enjekte edilebilir. ' +
|
|
8
|
+
'Senaryolar: `query: "SELECT * FROM users WHERE id = " + req.params.id` veya `db.users.find({ $where: req.body.filter })` gibi.',
|
|
9
|
+
threat: 'Data breach, authentication bypass, remote code execution (DB-specific), full DB compromise',
|
|
10
|
+
remediation: '1) **Parametrik sorgular** / prepared statements kullanin: `db.query(\'SELECT * FROM users WHERE id = $1\', [id])`. ' +
|
|
11
|
+
'2) ORM (Prisma, TypeORM, Sequelize, SQLAlchemy) otomatik parameterize eder. ' +
|
|
12
|
+
'3) String concatenation ile SQL asla olusturmayin. ' +
|
|
13
|
+
'4) NoSQL: `$where`, `$function`, `$regex` gibi operatorlari kullanici girdisinden GEÇMEYIN; explicit whitelist kullanin. ' +
|
|
14
|
+
'5) Stored procedure kullaniyorsaniz bile icindeki SQL\'i dinamik olusturmayin. ' +
|
|
15
|
+
'6) Tum user input\'u once validate edin (Zod, Joi, class-validator).',
|
|
16
|
+
references: [
|
|
17
|
+
'https://owasp.org/www-community/attacks/SQL_Injection',
|
|
18
|
+
'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html',
|
|
19
|
+
'https://owasp.org/www-project-top-ten/2017/A1_2017-Injection',
|
|
20
|
+
],
|
|
21
|
+
cwe: 'CWE-89',
|
|
22
|
+
owasp: 'A03:2021 Injection',
|
|
23
|
+
languages: ['javascript', 'typescript', 'python', 'java', 'go'],
|
|
24
|
+
check: (ctx) => {
|
|
25
|
+
const patterns = [
|
|
26
|
+
/(SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER)\s+[^;\n]*['"`]\s*\+\s*(req\.|request\.|input|params|body|query)/gi,
|
|
27
|
+
/\$\{[^}]*(req\.|request\.|input|params|body|query)[^}]*\}\s*['"`]\s*(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE)/gi,
|
|
28
|
+
/f['"`](?:SELECT|INSERT|UPDATE|DELETE|DROP).*\{[^}]*(?:request|input|args|params)/gi,
|
|
29
|
+
/['"`](?:SELECT|INSERT|UPDATE|DELETE|FROM|WHERE)[^'"`]*['"`]\s*%\s*\(/g,
|
|
30
|
+
/(?:createQuery|createNativeQuery)\s*\([^)]*\+[^)]*(?:request|param)/g,
|
|
31
|
+
/\$(?:where|function|regex|ne|gt|lt)\s*:/g,
|
|
32
|
+
];
|
|
33
|
+
const findings = [];
|
|
34
|
+
for (const re of patterns) {
|
|
35
|
+
findings.push(...grepRule(rule, ctx, re));
|
|
36
|
+
}
|
|
37
|
+
return findings;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
export default rule;
|
|
41
|
+
//# sourceMappingURL=sqlInjection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlInjection.js","sourceRoot":"","sources":["../../../../src/engine/rules/backend/sqlInjection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,gDAAgD;IACvD,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,UAAU;IACpB,WAAW,EACT,0JAA0J;QAC1J,gIAAgI;IAClI,MAAM,EAAE,6FAA6F;IACrG,WAAW,EACT,sHAAsH;QACtH,8EAA8E;QAC9E,qDAAqD;QACrD,2HAA2H;QAC3H,iFAAiF;QACjF,sEAAsE;IACxE,UAAU,EAAE;QACV,uDAAuD;QACvD,0FAA0F;QAC1F,8DAA8D;KAC/D;IACD,GAAG,EAAE,QAAQ;IACb,KAAK,EAAE,oBAAoB;IAC3B,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,QAAQ,GAAa;YAC/B,mHAAmH;YAC7G,gHAAgH;YACtH,oFAAoF;YAC9E,uEAAuE;YAC7E,sEAAsE;YACtE,0CAA0C;SACrC,CAAC;QAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { lineColumnFromIndex, snippetAt } from '../_helpers.js';
|
|
2
|
+
const rule = {
|
|
3
|
+
id: 'BE-009',
|
|
4
|
+
title: 'Long-lived token — missing or excessive expiry',
|
|
5
|
+
layer: 'backend',
|
|
6
|
+
severity: 'high',
|
|
7
|
+
description: 'JWT access token\'larinda `expiresIn` claim yoksa veya asiri uzunsa (30 gun+) token sizdirildiginda sonsuza kadar gecerli kalir. Ayni sekilde session cookie maxAge > 24 saat veya "remember me" tarzi kalici oturumlar kontrolsuzse saldırganin eline gecmis token ile yapacagi hasar sinirsiz olur.',
|
|
8
|
+
threat: 'Stolen token remains valid indefinitely → no logout, no password reset can revoke access',
|
|
9
|
+
remediation: '1) **Access token** icin `expiresIn: \'15m\'` veya daha kisa (5m). ' +
|
|
10
|
+
'2) **Refresh token** icin 7-30 gun + her kullanimda rotation + revocation store (Redis). ' +
|
|
11
|
+
'3) `jwt.sign()`\'de mutlaka `expiresIn` veya `exp` belirt, default davranisa guvenme. ' +
|
|
12
|
+
'4) `jwt.verify()`\'de `maxAge` veya explicit `exp` kontrolu yap. ' +
|
|
13
|
+
'5) `req.session.cookie.maxAge` 24 saatten fazla olmasin. ' +
|
|
14
|
+
'6) "Remember me" icin ayri, rotation\'lu, revocation\'lu token uret. ' +
|
|
15
|
+
'7) Tum sizdirilmis token\'lar icin blacklist / revocation list tut.',
|
|
16
|
+
references: [
|
|
17
|
+
'https://datatracker.ietf.org/doc/html/rfc8725#section-3.12',
|
|
18
|
+
'https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html#token-expiration',
|
|
19
|
+
'https://auth0.com/docs/secure/tokens/access-tokens/access-token-lifetime',
|
|
20
|
+
],
|
|
21
|
+
cwe: 'CWE-613',
|
|
22
|
+
owasp: 'A07:2021 Identification and Authentication Failures',
|
|
23
|
+
languages: ['javascript', 'typescript', 'python', 'java', 'go'],
|
|
24
|
+
check: (ctx) => {
|
|
25
|
+
const findings = [];
|
|
26
|
+
const longExpiry = [
|
|
27
|
+
/expiresIn\s*:\s*['"`](?:30d|60d|90d|365d|1y|'none'|"none"|0|null|undefined)['"`]/gi,
|
|
28
|
+
/expiresIn\s*:\s*['"`]\d{4,}\s*d['"`]/gi, // >999 gun
|
|
29
|
+
/jwt\.sign\s*\([^)]*\)\s*;(?![^]*expiresIn)/g, // expiresIn yok
|
|
30
|
+
/pyjwt\.encode\s*\([^)]*\)\s*(?![^]*exp)/g,
|
|
31
|
+
/new\s+UnsecuredJWT\s*\([^)]*\)/g,
|
|
32
|
+
];
|
|
33
|
+
for (const re of longExpiry) {
|
|
34
|
+
for (const m of ctx.source.matchAll(re)) {
|
|
35
|
+
if (m.index === undefined)
|
|
36
|
+
continue;
|
|
37
|
+
const { line } = lineColumnFromIndex(ctx.source, m.index);
|
|
38
|
+
findings.push({
|
|
39
|
+
id: `${rule.id}-${ctx.relativePath}-${line}-e`,
|
|
40
|
+
ruleId: rule.id,
|
|
41
|
+
title: rule.title,
|
|
42
|
+
layer: rule.layer,
|
|
43
|
+
severity: rule.severity,
|
|
44
|
+
file: ctx.relativePath,
|
|
45
|
+
match: { snippet: snippetAt(ctx.source, line), line, column: m.index },
|
|
46
|
+
description: rule.description,
|
|
47
|
+
impact: rule.threat,
|
|
48
|
+
remediation: rule.remediation,
|
|
49
|
+
references: rule.references,
|
|
50
|
+
cwe: rule.cwe,
|
|
51
|
+
owasp: rule.owasp,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const longSession = [
|
|
56
|
+
/maxAge\s*:\s*\d{2,}\s*\*\s*60\s*\*\s*60\s*\*\s*1000/g, // > 24 saat
|
|
57
|
+
/cookie\s*:\s*\{[^}]*maxAge\s*:\s*\d{8,}/g, // cok buyuk sayi (ms olarak)
|
|
58
|
+
];
|
|
59
|
+
for (const re of longSession) {
|
|
60
|
+
for (const m of ctx.source.matchAll(re)) {
|
|
61
|
+
if (m.index === undefined)
|
|
62
|
+
continue;
|
|
63
|
+
const { line } = lineColumnFromIndex(ctx.source, m.index);
|
|
64
|
+
findings.push({
|
|
65
|
+
id: `${rule.id}-${ctx.relativePath}-${line}-s`,
|
|
66
|
+
ruleId: rule.id,
|
|
67
|
+
title: rule.title,
|
|
68
|
+
layer: rule.layer,
|
|
69
|
+
severity: rule.severity,
|
|
70
|
+
file: ctx.relativePath,
|
|
71
|
+
match: { snippet: snippetAt(ctx.source, line), line, column: m.index },
|
|
72
|
+
description: rule.description,
|
|
73
|
+
impact: rule.threat,
|
|
74
|
+
remediation: rule.remediation,
|
|
75
|
+
references: rule.references,
|
|
76
|
+
cwe: rule.cwe,
|
|
77
|
+
owasp: rule.owasp,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return findings;
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
export default rule;
|
|
85
|
+
//# sourceMappingURL=tokenExpiry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenExpiry.js","sourceRoot":"","sources":["../../../../src/engine/rules/backend/tokenExpiry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { lineColumnFromIndex, snippetAt } from '../_helpers.js';
|
|
2
|
+
const rule = {
|
|
3
|
+
id: 'BE-008',
|
|
4
|
+
title: 'Token transmitted in URL (query string or path)',
|
|
5
|
+
layer: 'backend',
|
|
6
|
+
severity: 'high',
|
|
7
|
+
description: 'Access token, API key, session ID veya baska hassas token URL\'in query string\'inde (`?token=...`) veya path\'inde (`/users/:token/...`) tasindiginda, sunucu access log\'larinda, reverse proxy log\'larinda, browser history\'de, referer header\'inda veya ekran goruntulerinde ifsa olur. Ayni zamanda OWASP API3:2023 (Broken Object Property Level Authorization) ile zincir saldirilara kapilar acar.',
|
|
8
|
+
threat: 'Token leakage via logs/history/referer → session hijack, account takeover, lateral movement',
|
|
9
|
+
remediation: '1) Token\'i **MUTLAKA Authorization: Bearer** header\'inda tasima (query veya path degil). ' +
|
|
10
|
+
'2) API key gibi kalici secret\'lari client\'a hic gonderme; server-side proxy kullan. ' +
|
|
11
|
+
'3) Frontend\'den API\'ye istek atarken `fetch(url, { headers: { Authorization: \'Bearer \' + token } })`. ' +
|
|
12
|
+
'4) Express middleware: `app.use((req, res, next) => { if (req.query.token) return res.status(400).send(\'token in URL\'); next(); })` — hard reject. ' +
|
|
13
|
+
'5) Reverse proxy / Nginx log format\'larindan query string\'i cikar. ' +
|
|
14
|
+
'6) Eger gercekten URL\'de olmasi gerekiyorsa (ornek: download link\'i) one-time, short-TTL signed URL kullan.',
|
|
15
|
+
references: [
|
|
16
|
+
'https://owasp.org/API-Security/editions/2023/en/0xa2-broken-authentication/',
|
|
17
|
+
'https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html',
|
|
18
|
+
'https://cwe.mitre.org/data/definitions/598.html',
|
|
19
|
+
],
|
|
20
|
+
cwe: 'CWE-598',
|
|
21
|
+
owasp: 'A07:2021 Identification and Authentication Failures',
|
|
22
|
+
languages: ['javascript', 'typescript', 'python', 'java', 'go'],
|
|
23
|
+
check: (ctx) => {
|
|
24
|
+
const findings = [];
|
|
25
|
+
const queryToken = [
|
|
26
|
+
/req\.query\.(?:token|api_?key|apikey|access_?token|session)/gi,
|
|
27
|
+
/request\.GET\[['"](?:token|api_?key|apikey|access_?token|session)['"]\]/g,
|
|
28
|
+
/c\.Query\s*\(\s*['"`](?:token|api_?key|apikey|access_?token|session)/gi,
|
|
29
|
+
/request\.query_params\.get\s*\(\s*['"`](?:token|api_?key|apikey)/gi,
|
|
30
|
+
];
|
|
31
|
+
for (const re of queryToken) {
|
|
32
|
+
for (const m of ctx.source.matchAll(re)) {
|
|
33
|
+
if (m.index === undefined)
|
|
34
|
+
continue;
|
|
35
|
+
const { line } = lineColumnFromIndex(ctx.source, m.index);
|
|
36
|
+
findings.push({
|
|
37
|
+
id: `${rule.id}-${ctx.relativePath}-${line}-q`,
|
|
38
|
+
ruleId: rule.id,
|
|
39
|
+
title: rule.title,
|
|
40
|
+
layer: rule.layer,
|
|
41
|
+
severity: rule.severity,
|
|
42
|
+
file: ctx.relativePath,
|
|
43
|
+
match: { snippet: snippetAt(ctx.source, line), line, column: m.index },
|
|
44
|
+
description: rule.description,
|
|
45
|
+
impact: rule.threat,
|
|
46
|
+
remediation: rule.remediation,
|
|
47
|
+
references: rule.references,
|
|
48
|
+
cwe: rule.cwe,
|
|
49
|
+
owasp: rule.owasp,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const fetchWithToken = [
|
|
54
|
+
/fetch\s*\(\s*[`'"](?:[^`'"]*)\$\{[^}]*(?:token|api_?key|apikey|secret)[^}]*\}/gi,
|
|
55
|
+
/fetch\s*\(\s*[`'"][^`'"]*\?(?:[^`'"]*)\$\{[^}]*(?:token|api_?key|apikey|secret)/gi,
|
|
56
|
+
/axios\.(?:get|post)\s*\(\s*[`'"](?:[^`'"]*)\$\{[^}]*(?:token|api_?key|apikey|secret)/gi,
|
|
57
|
+
/requests\.(?:get|post)\s*\(\s*[`'"]f?(?:[^`'"]*)\{[^}]*(?:token|api_?key|apikey|secret)/gi,
|
|
58
|
+
];
|
|
59
|
+
for (const re of fetchWithToken) {
|
|
60
|
+
for (const m of ctx.source.matchAll(re)) {
|
|
61
|
+
if (m.index === undefined)
|
|
62
|
+
continue;
|
|
63
|
+
const { line } = lineColumnFromIndex(ctx.source, m.index);
|
|
64
|
+
findings.push({
|
|
65
|
+
id: `${rule.id}-${ctx.relativePath}-${line}-f`,
|
|
66
|
+
ruleId: rule.id,
|
|
67
|
+
title: rule.title,
|
|
68
|
+
layer: rule.layer,
|
|
69
|
+
severity: rule.severity,
|
|
70
|
+
file: ctx.relativePath,
|
|
71
|
+
match: { snippet: snippetAt(ctx.source, line), line, column: m.index },
|
|
72
|
+
description: rule.description,
|
|
73
|
+
impact: rule.threat,
|
|
74
|
+
remediation: rule.remediation,
|
|
75
|
+
references: rule.references,
|
|
76
|
+
cwe: rule.cwe,
|
|
77
|
+
owasp: rule.owasp,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const pathParam = [
|
|
82
|
+
/\/:\s*(?:token|api_?key|apikey|secret)\b/gi,
|
|
83
|
+
/\/<(?:\w+:)?(?:token|api_?key|apikey|secret)>/gi,
|
|
84
|
+
/\/\{(?:token|api_?key|apikey|secret)\}/gi,
|
|
85
|
+
];
|
|
86
|
+
for (const re of pathParam) {
|
|
87
|
+
for (const m of ctx.source.matchAll(re)) {
|
|
88
|
+
if (m.index === undefined)
|
|
89
|
+
continue;
|
|
90
|
+
const { line } = lineColumnFromIndex(ctx.source, m.index);
|
|
91
|
+
findings.push({
|
|
92
|
+
id: `${rule.id}-${ctx.relativePath}-${line}-p`,
|
|
93
|
+
ruleId: rule.id,
|
|
94
|
+
title: rule.title,
|
|
95
|
+
layer: rule.layer,
|
|
96
|
+
severity: rule.severity,
|
|
97
|
+
file: ctx.relativePath,
|
|
98
|
+
match: { snippet: snippetAt(ctx.source, line), line, column: m.index },
|
|
99
|
+
description: rule.description,
|
|
100
|
+
impact: rule.threat,
|
|
101
|
+
remediation: rule.remediation,
|
|
102
|
+
references: rule.references,
|
|
103
|
+
cwe: rule.cwe,
|
|
104
|
+
owasp: rule.owasp,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return findings;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
export default rule;
|
|
112
|
+
//# sourceMappingURL=tokenInUrl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenInUrl.js","sourceRoot":"","sources":["../../../../src/engine/rules/backend/tokenInUrl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { grepRule } from '../_helpers.js';
|
|
2
|
+
const rule = {
|
|
3
|
+
id: 'CI-001',
|
|
4
|
+
title: 'Dependency hygiene — missing lockfile, audit, or pinning',
|
|
5
|
+
layer: 'cicd',
|
|
6
|
+
severity: 'medium',
|
|
7
|
+
description: 'Lockfile (package-lock.json / yarn.lock / poetry.lock / go.sum) eksikse bagimlilik versiyonlari tekrarlanamaz sekilde cozumlenir (tedarik zinciri riski). Audit script\'i yoksa CVE\'ler sessizce slider.',
|
|
8
|
+
threat: 'Software supply chain attack, dependency confusion, known CVE exploitation',
|
|
9
|
+
remediation: '1) Lockfile\'i her zaman commit\'leyin ve `.gitignore`\'a ALMAYIN. ' +
|
|
10
|
+
'2) CI\'da `npm audit --audit-level=high`, `pip-audit`, `govulncheck`, `snyk test`, `dependabot` calistirin. ' +
|
|
11
|
+
'3) Container imajlarinda minimal taban (`distroless`, `alpine`) ve **non-root** user kullanin. ' +
|
|
12
|
+
'4) `npm ci` ile build yapin (lockfile\'a zorlar). ' +
|
|
13
|
+
'5) Renovate / Dependabot ile guvenlik PR\'leri otomatik acilsin. ' +
|
|
14
|
+
'6) `package.json` `scripts.audit` tanimlayin.',
|
|
15
|
+
references: [
|
|
16
|
+
'https://docs.npmjs.com/cli/v10/commands/npm-audit',
|
|
17
|
+
'https://github.com/pypa/pip-audit',
|
|
18
|
+
'https://github.com/govulncheck/govulncheck',
|
|
19
|
+
],
|
|
20
|
+
cwe: 'CWE-1357',
|
|
21
|
+
owasp: 'A06:2021 Vulnerable and Outdated Components',
|
|
22
|
+
languages: ['javascript', 'typescript', 'python', 'go', 'json'],
|
|
23
|
+
check: (ctx) => {
|
|
24
|
+
const patterns = [
|
|
25
|
+
/^(\s*)\}\s*$/gm,
|
|
26
|
+
/pip\s+install\s+(?!.*--require-hashes)/g,
|
|
27
|
+
/npm\s+install\s+(?!.*--ignore-scripts)/g,
|
|
28
|
+
/FROM\s+[^:\n]+:latest/g,
|
|
29
|
+
];
|
|
30
|
+
if (/(?:package\.json|requirements\.txt|pyproject\.toml|go\.mod)$/i.test(ctx.relativePath)) {
|
|
31
|
+
const hasAudit = /"audit"|pip-audit|snyk|dependabot|renovate/i.test(ctx.source);
|
|
32
|
+
if (!hasAudit && /(?:package\.json)$/i.test(ctx.relativePath)) {
|
|
33
|
+
return grepRule(rule, ctx, /"scripts"\s*:\s*\{/g);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const findings = [];
|
|
37
|
+
for (const re of patterns) {
|
|
38
|
+
findings.push(...grepRule(rule, ctx, re));
|
|
39
|
+
}
|
|
40
|
+
return findings;
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
export default rule;
|
|
44
|
+
//# sourceMappingURL=dependencies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../../../src/engine/rules/cicd/dependencies.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,0DAA0D;IACjE,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,QAAQ;IAClB,WAAW,EACT,2MAA2M;IAC7M,MAAM,EAAE,4EAA4E;IACpF,WAAW,EACT,qEAAqE;QACrE,8GAA8G;QAC9G,iGAAiG;QACjG,oDAAoD;QACpD,mEAAmE;QACnE,+CAA+C;IACjD,UAAU,EAAE;QACV,mDAAmD;QACnD,mCAAmC;QACnC,4CAA4C;KAC7C;IACD,GAAG,EAAE,UAAU;IACf,KAAK,EAAE,6CAA6C;IACpD,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,QAAQ,GAAa;YAC/B,gBAAgB;YAChB,yCAAyC;YACnC,yCAAyC;YAC/C,wBAAwB;SACnB,CAAC;QAEF,IAAI,+DAA+D,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YAC3F,MAAM,QAAQ,GAAG,6CAA6C,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAChF,IAAI,CAAC,QAAQ,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC9D,OAAO,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,qBAAqB,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { grepRule } from '../_helpers.js';
|
|
2
|
+
const rule = {
|
|
3
|
+
id: 'CI-003',
|
|
4
|
+
title: 'Insecure Dockerfile (root user, latest tag, ADD with URL)',
|
|
5
|
+
layer: 'cicd',
|
|
6
|
+
severity: 'medium',
|
|
7
|
+
description: 'Dockerfile\'da `USER` belirtilmemisse konteyner root olarak calisir; `latest` tag tekrarlanamaz; `ADD` URL\'den dosya cekmek MITM\'e aciktir.',
|
|
8
|
+
threat: 'Container escape, root privilege escalation, unpredictable builds, supply chain',
|
|
9
|
+
remediation: '1) `FROM <image>:<pinned-version>` kullanin (digest\'e pinleyin: `@sha256:...`). ' +
|
|
10
|
+
'2) `USER nonroot:nonroot` veya specific UID ile calistirin. ' +
|
|
11
|
+
'3) `COPY` kullanin; sadece gerekli dosyalari kopyalayin. `ADD <url>` kullanmayin (curl/wget ile indirip checksum dogrulayin). ' +
|
|
12
|
+
'4) Multi-stage build ile build tool\'lari final imaja sokmayin. ' +
|
|
13
|
+
'5) Minimal taban (`gcr.io/distroless/*`, `alpine`) kullanin. ' +
|
|
14
|
+
'6) `.dockerignore` ile secret / node_modules / .git\'i disarida birakin.',
|
|
15
|
+
references: [
|
|
16
|
+
'https://docs.docker.com/develop/dev-best-practices/',
|
|
17
|
+
'https://snyk.io/learn/docker-security/',
|
|
18
|
+
'https://github.com/hadolint/hadolint',
|
|
19
|
+
],
|
|
20
|
+
cwe: 'CWE-250',
|
|
21
|
+
owasp: 'A05:2021 Security Misconfiguration',
|
|
22
|
+
languages: ['dockerfile'],
|
|
23
|
+
check: (ctx) => {
|
|
24
|
+
const findings = [];
|
|
25
|
+
const lines = ctx.lines;
|
|
26
|
+
const hasUser = /^USER\s+/m.test(ctx.source);
|
|
27
|
+
const hasLatest = /FROM\s+\S+:latest\b/.exec(ctx.source);
|
|
28
|
+
const hasAddUrl = /^ADD\s+https?:\/\//m.test(ctx.source);
|
|
29
|
+
if (!hasUser) {
|
|
30
|
+
findings.push(...grepRule(rule, ctx, /^FROM\s+/gm));
|
|
31
|
+
}
|
|
32
|
+
if (hasLatest) {
|
|
33
|
+
findings.push(...grepRule(rule, ctx, /FROM\s+\S+:latest\b/g));
|
|
34
|
+
}
|
|
35
|
+
if (hasAddUrl) {
|
|
36
|
+
findings.push(...grepRule(rule, ctx, /^ADD\s+https?:\/\//gm));
|
|
37
|
+
}
|
|
38
|
+
return findings;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
export default rule;
|
|
42
|
+
//# sourceMappingURL=dockerfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dockerfile.js","sourceRoot":"","sources":["../../../../src/engine/rules/cicd/dockerfile.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,2DAA2D;IAClE,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,QAAQ;IAClB,WAAW,EACT,+IAA+I;IACjJ,MAAM,EAAE,iFAAiF;IACzF,WAAW,EACT,mFAAmF;QACnF,8DAA8D;QAC9D,gIAAgI;QAChI,kEAAkE;QAClE,+DAA+D;QAC/D,0EAA0E;IAC5E,UAAU,EAAE;QACV,qDAAqD;QACrD,wCAAwC;QACxC,sCAAsC;KACvC;IACD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,oCAAoC;IAC3C,SAAS,EAAE,CAAC,YAAY,CAAC;IACzB,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;QAExB,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,SAAS,EAAE,CAAC;YACd,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,sBAAsB,CAAC,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,SAAS,EAAE,CAAC;YACd,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,sBAAsB,CAAC,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/engine/rules/cicd/index.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,UAAU,MAAM,iBAAiB,CAAC;AAEzC,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,YAAY;IACZ,OAAO;IACP,UAAU;CACX,CAAC;AAEF,eAAe,KAAK,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { grepRule } from '../_helpers.js';
|
|
2
|
+
const rule = {
|
|
3
|
+
id: 'CI-002',
|
|
4
|
+
title: 'Hardcoded secret / credential in source',
|
|
5
|
+
layer: 'cicd',
|
|
6
|
+
severity: 'critical',
|
|
7
|
+
description: 'API key, private key, DB password, OAuth secret, AWS access key gibi hassas degerlerin kaynak kodunda veya .env dosyasinda duz metin bulunmasi, Git reposuna sizmasi demektir.',
|
|
8
|
+
threat: 'Cloud takeover, financial fraud, data breach, lateral movement',
|
|
9
|
+
remediation: '1) Tum secret\'lari **Vault / AWS Secrets Manager / GCP Secret Manager / Doppler** ile yonetin. ' +
|
|
10
|
+
'2) Pre-commit hook olarak **gitleaks** veya **trufflehog** kurun. ' +
|
|
11
|
+
'3) `.gitignore`\'a `.env`, `.env.local`, `*.pem`, `*.key` ekleyin. ' +
|
|
12
|
+
'4) `.env.example` sadece anahtar isimlerini icersin, degerler bos olmali. ' +
|
|
13
|
+
'5) CI ortaminda secret\'lari environment variable olarak inject edin (GitHub Actions secrets, GitLab CI variables). ' +
|
|
14
|
+
'6) Bir secret commit olduysa HEMEN rotate edin; Git history\'de kalir.',
|
|
15
|
+
references: [
|
|
16
|
+
'https://github.com/gitleaks/gitleaks',
|
|
17
|
+
'https://github.com/trufflesecurity/trufflehog',
|
|
18
|
+
'https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html',
|
|
19
|
+
],
|
|
20
|
+
cwe: 'CWE-798',
|
|
21
|
+
owasp: 'A05:2021 Security Misconfiguration',
|
|
22
|
+
languages: ['javascript', 'typescript', 'python', 'java', 'go', 'yaml', 'dockerfile'],
|
|
23
|
+
check: (ctx) => {
|
|
24
|
+
const patterns = [
|
|
25
|
+
/AKIA[0-9A-Z]{16}/g,
|
|
26
|
+
/api[_-]?key\s*[:=]\s*['"`]([a-zA-Z0-9_\-]{20,})['"`]/gi,
|
|
27
|
+
/-----BEGIN (?:RSA |EC |DSA |OPENSSH |PGP )?PRIVATE KEY-----/g,
|
|
28
|
+
/(?:password|passwd|pwd|secret)\s*[:=]\s*['"`]([^'"`\s]{6,})['"`]/gi,
|
|
29
|
+
/sk_live_[0-9a-zA-Z]{24,}/g,
|
|
30
|
+
/gh[pousr]_[0-9a-zA-Z]{36,}/g,
|
|
31
|
+
/eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g,
|
|
32
|
+
];
|
|
33
|
+
const findings = [];
|
|
34
|
+
for (const re of patterns) {
|
|
35
|
+
findings.push(...grepRule(rule, ctx, re));
|
|
36
|
+
}
|
|
37
|
+
return findings;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
export default rule;
|
|
41
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../../src/engine/rules/cicd/secrets.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,yCAAyC;IAChD,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,UAAU;IACpB,WAAW,EACT,gLAAgL;IAClL,MAAM,EAAE,gEAAgE;IACxE,WAAW,EACT,kGAAkG;QAClG,oEAAoE;QACpE,qEAAqE;QACrE,4EAA4E;QAC5E,sHAAsH;QACtH,wEAAwE;IAC1E,UAAU,EAAE;QACV,sCAAsC;QACtC,+CAA+C;QAC/C,oFAAoF;KACrF;IACD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,oCAAoC;IAC3C,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC;IACrF,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,QAAQ,GAAa;YAC/B,mBAAmB;YACnB,wDAAwD;YACxD,8DAA8D;YAC9D,oEAAoE;YACpE,2BAA2B;YAC3B,6BAA6B;YAC7B,gEAAgE;SAC3D,CAAC;QAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { grepRule } from '../_helpers.js';
|
|
2
|
+
const rule = {
|
|
3
|
+
id: 'DB-002',
|
|
4
|
+
title: 'Sensitive data not encrypted at rest (PII / payment / health)',
|
|
5
|
+
layer: 'database',
|
|
6
|
+
severity: 'high',
|
|
7
|
+
description: 'TC kimlik, kredi karti, saglik verisi, parolalar gibi PII alanlari duz metin (plain text) ile saklaniyorsa fiziksel veya yedek sizintisinda aninda okunabilir hale gelir.',
|
|
8
|
+
threat: 'GDPR / KVKK / PCI-DSS violation, identity theft, regulatory fines',
|
|
9
|
+
remediation: '1) In-transit: tum baglantilari **TLS 1.2+** ile sifreleyin. Baglanti string\'inde `sslmode=require` veya `ssl=true`. ' +
|
|
10
|
+
'2) At-rest: kritik kolonlari uygulama seviyesinde **AES-256-GCM** ile sifreleyin (deterministic olmayan, random IV). ' +
|
|
11
|
+
'3) Veya TDE / column-level encryption (pgcrypto, AWS RDS encryption, MongoDB CSFLE). ' +
|
|
12
|
+
'4) KMS / Vault ile key\'leri yonetin, kodda saklamayin. ' +
|
|
13
|
+
'5) Backup\'lar da sifrelenmis olmali. ' +
|
|
14
|
+
'6) PCI scope\'a giren veriler icin tokenization (Stripe, Adyen) kullanin, ham PAN\'i ASLA saklamayin.',
|
|
15
|
+
references: [
|
|
16
|
+
'https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html',
|
|
17
|
+
'https://www.postgresql.org/docs/current/encryption-options.html',
|
|
18
|
+
'https://www.pcisecuritystandards.org/',
|
|
19
|
+
],
|
|
20
|
+
cwe: 'CWE-311',
|
|
21
|
+
owasp: 'A02:2021 Cryptographic Failures',
|
|
22
|
+
languages: ['javascript', 'typescript', 'python', 'java', 'go'],
|
|
23
|
+
check: (ctx) => {
|
|
24
|
+
const patterns = [
|
|
25
|
+
/(?:nationalId|tckimlik|ssn|socialSecurityNumber|creditCard|cardNumber|cvv|pan|tc_kimlik)\s*[:=]\s*['"`]?String['"`]?/gi,
|
|
26
|
+
/(?:nationalId|tckimlik|ssn|socialSecurityNumber|creditCard|cardNumber|cvv|pan)\s+(?:String|VARCHAR|TEXT)/g,
|
|
27
|
+
/(?:postgres|mysql|mongodb):\/\/[^@\s]+@/gi,
|
|
28
|
+
];
|
|
29
|
+
const findings = [];
|
|
30
|
+
for (const re of patterns) {
|
|
31
|
+
findings.push(...grepRule(rule, ctx, re));
|
|
32
|
+
}
|
|
33
|
+
return findings;
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
export default rule;
|
|
37
|
+
//# sourceMappingURL=encryption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../../../src/engine/rules/database/encryption.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,IAAI,GAAS;IACjB,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,+DAA+D;IACtE,KAAK,EAAE,UAAU;IACjB,QAAQ,EAAE,MAAM;IAChB,WAAW,EACT,2KAA2K;IAC7K,MAAM,EAAE,mEAAmE;IAC3E,WAAW,EACT,wHAAwH;QACxH,uHAAuH;QACvH,uFAAuF;QACvF,0DAA0D;QAC1D,wCAAwC;QACxC,uGAAuG;IACzG,UAAU,EAAE;QACV,uFAAuF;QACvF,iEAAiE;QACjE,uCAAuC;KACxC;IACD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,iCAAiC;IACxC,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,QAAQ,GAAa;YAC/B,wHAAwH;YAClH,2GAA2G;YACjH,2CAA2C;SACtC,CAAC;QAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|