Lines 130-170javascript
132 async testRateLimit(scope, findings) {
133 const authEndpoint = scope.target.auth?.endpoint;
136 id: stableFindingId({ saas: scope.target.name, camada: this.category, rule: "rate-limit-not-tested" }),
139 category: this.category,
140 camada: this.category,
142 title: "Rate limit n\xE3o testado \u2014 auth.endpoint n\xE3o configurado",
143 description: "Configure auth.endpoint no targets.yaml para testar prote\xE7\xE3o contra brute force.",
144 recommendation: "Adicione auth.endpoint no targets.yaml:\n```yaml\nauth:\n endpoint: /api/auth/login\n```",
145 createdAt: /* @__PURE__ */ new Date()
149 const client = new FractaHttpClient(scope.target.url);
150 const body = { email: "brute@fracta.test", password: "wrong-password-fracta-12345" };
151 const requests = Array.from(
153 () => client.request(authEndpoint, { method: "POST", body, timeoutMs: 5e3 }).catch(() => null)
155 const results = await Promise.all(requests);
156 const rateLimited = results.filter((r) => r?.status === 429).length;
157 if (rateLimited < 2) {
159 id: stableFindingId({ saas: scope.target.name, camada: this.category, rule: `brute-force:${authEndpoint}`, location: authEndpoint }),
162 category: this.category,
163 camada: this.category,
165 title: "Rate limiting ausente no endpoint de login",
166 description: `10 requisi\xE7\xF5es simult\xE2neas de login inv\xE1lido retornaram apenas ${rateLimited} respostas 429. Prote\xE7\xE3o contra brute force insuficiente.`,
167 endpoint: authEndpoint,
168 evidence: `10 POST ${authEndpoint} com credenciais erradas \u2192 ${rateLimited}/10 retornaram 429`,
169 recommendation: "Implemente rate limiting no endpoint de login:\n```typescript\nimport { ThrottlerGuard } from '@nestjs/throttler';\n\n@UseGuards(ThrottlerGuard)\n@Post('login')\nasync login(@Body() dto: LoginDto) { ... }\n```",
170 references: ["https://owasp.org/www-community/attacks/Brute_force_attack"],