| name | pentest-web-angular |
| description | Pentest de frontend Angular (Web) — OWASP Top 10 2025, DOM security, XSS, CSRF, CSP,
template injection, sanitização, storage de tokens, open redirect, clickjacking, cache poisoning.
TRIGGERS: pentest web, pentest angular, angular security, xss angular, csp angular, frontend security, dom xss, bypass security trust, angular storage, cookie httponly
|
🕷️ pentest-web-angular — Auditoria Ofensiva de Angular
Superfície: aplicações Angular standalone (v17+) com PrimeNG, signals e roteamento lazy. Foco em vulnerabilidades que persistem mesmo com o DomSanitizer ativo.
Required Reading
.agent/System/angular_best_practices.md
.agent/System/primeng_best_practices.md
angular.json e tsconfig.app.json (CSP, source maps, i18n)
apps/web/src/index.html (headers, meta CSP, fontes externas)
proxy.conf.json (evitar proxy aberto em prod)
1. XSS — Cross-Site Scripting
1.1 Reflected/Stored
rg -n "\[innerHTML\]=" libs/ apps/
rg -n "bypassSecurityTrust(Html|Script|Style|Url|ResourceUrl)" libs/ apps/
rg -n "DomSanitizer" libs/ apps/ -A 3
rg -n "Renderer2.*setProperty.*innerHTML" libs/ apps/
Checklist:
1.2 DOM XSS
Procurar sinks: location.hash, document.write, eval, setTimeout('string'), $sce.trustAsHtml.
rg -n "location\.(hash|search|href)" libs/ apps/
rg -n "document\.(write|writeln)" libs/ apps/
rg -n "window\.postMessage" libs/ apps/ -A 5
1.3 Template Injection
Nunca compilar templates dinamicamente com input do usuário:
rg -n "compileModuleAsync|createComponent.*userInput" libs/ apps/
2. CSRF & Same-Origin
Checklist
rg -n "withCredentials\s*:\s*true" libs/ apps/
rg -n "HttpClientXsrfModule|provideHttpClient" apps/ libs/
3. Storage de Tokens (JWT/Session)
Regra de ouro: JWT não deve viver em localStorage nem sessionStorage. Use cookie HttpOnly+Secure+SameSite.
rg -n "localStorage\.(setItem|getItem).*(token|jwt|auth|session)" libs/ apps/ -i
rg -n "sessionStorage\.(setItem|getItem).*(token|jwt|auth|session)" libs/ apps/ -i
Se usar localStorage (legacy), auditar se há mitigação: short-lived token + refresh rotativo + CSP estrita.
4. CSP (Content Security Policy)
Verificar em index.html e response headers:
rg -n "Content-Security-Policy" apps/ .
CSP mínima recomendada:
default-src 'self';
script-src 'self' 'nonce-<random>';
style-src 'self' 'nonce-<random>';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
object-src 'none';
5. Open Redirect
rg -n "window\.location\s*=" libs/ apps/
rg -n "Router.*navigateByUrl\(.*(queryParams|route\.snapshot)" libs/ apps/
rg -n "returnUrl|redirect|callback|next" libs/ apps/ -i
Validar se parâmetros ?returnUrl= são normalizados para URL relativa (new URL(u, origin).origin === origin).
6. Clickjacking & UI Redressing
7. Service Worker & Cache
rg -n "ngsw-config\.json|service-worker" apps/
8. SSR / Angular Universal
Se o projeto usa SSR:
9. Dependências Frontend Específicas
pnpm dlx retire --jspath apps/web/dist/
Libs frequentemente vulneráveis:
lodash < 4.17.21 (prototype pollution)
moment (deprecated; trocar por date-fns ou luxon)
dompurify < 3.0.6 (múltiplos bypasses de XSS)
marked < 11.1.1 (XSS em links)
highlight.js < 10.4.1 (ReDoS)
10. PrimeNG / UI
11. Source Maps em Produção
cat angular.json | jq '.projects[].architect.build.configurations.production.sourceMap'
Production deve ser false ou { scripts: true, styles: false, vendor: false, hidden: true }. Source maps públicos expõem estrutura de libs internas.
12. Headers Adicionais
Via nginx/traefik/Cloudfront:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Output Snippet (para incorporar no relatório do @pentester)
### 🌐 Web (Angular) — N findings
| ID | Severity | CWE | CVSS | File:Line | Issue |
|----|---|---|---|---|---|
| W-001 | 🔴 Critical | CWE-79 | 8.8 | libs/admin/feature/.../comment.component.ts:34 | Stored XSS via `[innerHTML]` sem sanitização |
| W-002 | 🟠 High | CWE-352 | 7.5 | apps/web/src/app/core/http.interceptor.ts | CSRF não habilitado |
Anti-patterns a SEMPRE reportar
- Qualquer uso de
bypassSecurityTrustHtml com variável
- JWT em
localStorage sem justificativa
- CSP com
'unsafe-inline' em produção
- Source map
production habilitado
- Rotas sem guard acessando dados sensíveis (
/admin, /settings, /api-keys)
innerText em vez de textContent combinado com input do usuário (diferença em <br> quebra escapes em alguns cenários)