Skip to content

Commit f32e7a5

Browse files
committed
feat: improve security lab tests coverage
1 parent 2d283e5 commit f32e7a5

9 files changed

Lines changed: 1686 additions & 47 deletions

File tree

.pentest/README.md

Lines changed: 71 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Lab de testes de segurança para a API ProStaff
66

77
- **API**: http://localhost:3333/api/v1
88
- **WebSocket**: ws://localhost:3333/cable
9-
- **Stack**: Rails 7.1, PostgreSQL, Redis, JWT, Pundit, Rack::Attack, Meilisearch
9+
- **Stack**: Rails 7.2, PostgreSQL, Redis, JWT, Pundit, Rack::Attack, Meilisearch
1010

1111
## Pre-requisitos
1212

@@ -15,7 +15,7 @@ API rodando localmente:
1515
```bash
1616
cd /home/bullet/PROJETOS/prostaff-api
1717
docker compose up -d
18-
docker exec prostaff-api-api-1 bundle exec rails runner scripts/create_test_user.rb
18+
docker exec prostaff-api bundle exec rails runner scripts/create_test_user.rb
1919
```
2020

2121
Credenciais de teste: `test@prostaff.gg` / `Test123!@#`
@@ -28,39 +28,43 @@ Credenciais de teste: `test@prostaff.gg` / `Test123!@#`
2828
```
2929

3030
## Scripts — API (scripts/)
31-
32-
| Script | Vetor | Destrutivo |
33-
|--------|-------|-----------|
34-
| 01_health_recon.sh | Info disclosure nos endpoints de health | Nao |
35-
| 02_auth_fingerprint.sh | Fingerprint do sistema JWT + timing oracle | Nao |
36-
| 03_jwt_attacks.sh | alg:none, RS256→HS256, claims tampering, token replay | Nao |
37-
| 04_org_isolation.sh | IDOR + isolamento multi-tenant | Nao |
38-
| 05_rbac_probe.sh | Privilege escalation + Pundit bypass | Nao |
39-
| 06_rate_limit_probe.sh | Rack::Attack + bypass via X-Forwarded-For | Nao |
40-
| 07_param_fuzzing.sh | SQLi, XSS, SSTI, type confusion, oversized payloads | Nao |
41-
| 08_ssrf_probe.sh | SSRF via integracao Riot API | Nao |
42-
| 09_export_injection.sh | CSV/Formula injection nos exports | Sim (cria player) |
43-
| 10_websocket_probe.sh | Action Cable auth + IDOR de canal | Nao |
44-
| 11_search_injection.sh | Meilisearch operators + cross-org search | Nao |
45-
| 12_info_disclosure.sh | Rails routes expostos, headers, CORS, 500 stack traces | Nao |
46-
| 13_nuclei_scan.sh | Templates customizados + headers/auth/Rails exposures | Nao |
47-
| 14_httpx_recon.sh | Recon completo de paths e headers | Nao |
48-
| 15_full_audit.sh | Roda todos os scripts em sequencia | Opcional |
49-
| 16_security_headers.sh | CarameloScan checkers #1-7, #10, #13-16 (HSTS, CSP, CORS) | Nao |
50-
| 17_cookie_security.sh | Flags Secure/HttpOnly/SameSite, escopo, invalidacao no logout | Nao |
51-
| 18_content_security.sh | Server disclosure, Referrer-Policy, Cache-Control, stack trace | Nao |
52-
| 19_info_disclosure.sh | .env, .git, swagger, rails/info, sidekiq, logs, Gemfile | Nao |
53-
| 20_dns_email_spoof.sh | SPF, DMARC, DKIM, MX, zone transfer AXFR, subdomain takeover | Nao |
31+
32+
| Script | Vetor | Destrutivo |
33+
|--------------------------|-------------------------------------------------------|----------------|
34+
| 01_health_recon.sh | Info disclosure nos endpoints de health | Nao |
35+
| 02_auth_fingerprint.sh | Fingerprint do sistema JWT + timing oracle | Nao |
36+
| 03_jwt_attacks.sh | alg:none, RS256→HS256, claims tampering, token replay | Nao |
37+
| 04_org_isolation.sh | IDOR + isolamento multi-tenant | Nao |
38+
| 05_rbac_probe.sh | Privilege escalation + Pundit bypass | Nao |
39+
| 06_rate_limit_probe.sh | Rack::Attack + bypass via X-Forwarded-For | Nao |
40+
| 07_param_fuzzing.sh | SQLi, XSS, SSTI, type confusion, oversized payloads | Nao |
41+
| 08_ssrf_probe.sh | SSRF via integracao Riot API | Nao |
42+
| 09_export_injection.sh | CSV/Formula injection nos exports |Sim(cria player)|
43+
| 10_websocket_probe.sh | Action Cable auth + IDOR de canal | Nao |
44+
| 11_search_injection.sh | Meilisearch operators + cross-org search | Nao |
45+
| 12_info_disclosure.sh | Rails routes expostos, headers, CORS, 500 stack traces| Nao |
46+
| 13_nuclei_scan.sh | Templates customizados + headers/auth/Rails exposures | Nao |
47+
| 14_httpx_recon.sh | Recon completo de paths e headers | Nao |
48+
| 15_full_audit.sh | Roda todos os scripts em sequencia | opcional |
49+
| 16_security_headers.sh | Checkers #1-7, #10, #13-16 (HSTS, CSP, CORS) | Nao |
50+
| 17_cookie_security.sh | Flags Secure/HttpOnly/SameSite, escopo, invalidacao | Nao |
51+
| 18_content_security.sh | Server disclosure, Referrer-Policy, stack trace, cache| Nao |
52+
| 19_info_disclosure.sh | .env, .git, swagger, info, sidekiq, logs, Gemfile | Nao |
53+
| 20_dns_email_spoof.sh | SPF, DMARC, DKIM, MX, zone transfer AXFR, subtakeover | Nao |
54+
| 22_race_conditions.sh | TOCTOU em registro, refresh tk cc, rate limit burst | Nao |
55+
| 23_token_rotation.sh | Ciclo de vida do token: single-use, type confusion | Nao |
56+
| 24_host_header.sh | Host header injection em pass reset, config.hosts | Nao |
57+
| 25_mass_assignment.sh | Strong Param: role, org_id, puuid, plan escalation | Nao |
5458

5559
## Scripts — Frontend (front/)
5660

57-
| Script | Vetor |
58-
|--------|-------|
59-
| check-security-headers.sh | Todos os 22 checkers CarameloScan no prostaff.gg |
60-
| check-cookies.sh | Flags de cookie, SameSite, duracao, CSRF token |
61-
| check-sri.sh | SRI em scripts/CSS externos, source maps, scripts inline |
61+
| Script | Vetor |
62+
|---------------------------|-----------------------------------------------------------------------|
63+
| check-security-headers.sh | Todos os 22 checkers CaramelScan no prostaff.gg |
64+
| check-cookies.sh | Flags de cookie, SameSite, duracao, CSRF token |
65+
| check-sri.sh | SRI em scripts/CSS externos, source maps, scripts inline |
6266
| check-content-security.sh | Version disclosure, Referrer-Policy, cache em paginas auth, COOP/CORP |
63-
| check-info-disclosure.sh | .env, .git, __NEXT_DATA__, BUILD_ID, comentarios HTML, robots.txt |
67+
| check-info-disclosure.sh | .env, .git, __NEXT_DATA__, BUILD_ID, comentarios HTML, robots.txt |
6468

6569
Todos os scripts de frontend aceitam o target como primeiro argumento:
6670
```bash
@@ -73,16 +77,22 @@ Todos os scripts de frontend aceitam o target como primeiro argumento:
7377
# Todos os testes API (sem os destrutivos)
7478
./scripts/15_full_audit.sh --skip-destructive
7579

80+
# JWT e token lifecycle (novos)
81+
./scripts/22_race_conditions.sh
82+
./scripts/23_token_rotation.sh
83+
7684
# Auditoria de headers API (producao)
7785
./scripts/16_security_headers.sh
7886
./scripts/16_security_headers.sh http://localhost:3333 # local
7987

80-
# Auditoria completa de seguranca (CarameloScan + extras)
88+
# Auditoria completa de seguranca (CarameloScan + extras + novos)
8189
./scripts/16_security_headers.sh
8290
./scripts/17_cookie_security.sh
8391
./scripts/18_content_security.sh
8492
./scripts/19_info_disclosure.sh
8593
./scripts/20_dns_email_spoof.sh
94+
./scripts/24_host_header.sh
95+
./scripts/25_mass_assignment.sh
8696

8797
# Auditoria completa frontend
8898
./front/check-security-headers.sh
@@ -96,21 +106,34 @@ Todos os scripts de frontend aceitam o target como primeiro argumento:
96106

97107
1. `01``02` (recon e auth - baseline)
98108
2. `03``04``05` (atacar auth e autorizacao)
99-
3. `06``07` (rate limits e fuzzing)
100-
4. `08``09` (integracao externa e exports)
101-
5. `10``11` (WebSocket e search)
102-
6. `12``13``14` (info disclosure e scan automatizado)
103-
7. `16``17``18``19``20` (headers, cookies, content, DNS)
104-
8. `front/check-*` (auditoria frontend)
109+
3. `22``23` (race conditions e lifecycle do token)
110+
4. `06``07` (rate limits e fuzzing)
111+
5. `08``09` (integracao externa e exports)
112+
6. `10``11` (WebSocket e search)
113+
7. `12``13``14` (info disclosure e scan automatizado)
114+
8. `16``17``18``19``20``24``25` (headers, cookies, content, DNS, host header, mass assignment)
115+
9. `front/check-*` (auditoria frontend)
105116

106117
## Relatorios
107118

108119
Salvos em `reports/` com data no nome. Formato: `security-audit-YYYY-MM-DD.md`.
109120
Nunca commitar - adicione ao .gitignore.
110121

111122

112-
| Relatorio | Data | Criticos | Status |
113-
|-----------|------|----------|--------|
123+
| Relatorio | Data | Criticos | Status |
124+
|--------------------------------------|----------------|----------|-----------|
125+
| JWT Race Condition + Token Confusion | 2026-04-11 | 3 | Corrigido |
126+
127+
### Historico de vulnerabilidades corrigidas
128+
129+
| ID | Script | Severidade | Descricao | Correcao |
130+
|--------|--------|------------|----------------------------------------------------------------------|----------|
131+
| JWT-01 | 23 | Medium | Refresh token aceito como access token (`type` claim nao validado em `authenticate_request!`)
132+
| | Adicionado `valid_access_token_type?` no concern `Authenticatable`
133+
| JWT-02 | 23 | Medium | Refresh token sobrevive ao logout (logout nao blacklistava o refresh token)
134+
| | `logout` agora blacklista `params[:refresh_token]` se presente
135+
| JWT-03 | 22 | Medium | TOCTOU no `refresh_access_token` (decode + blacklist nao atomicos ----- 2 sessoes paralelas possiveis)
136+
| | `TokenBlacklist.claim_for_rotation` com Redis SET NX EX antes de gerar novos tokens |
114137

115138

116139
## Vetores principais (Rails/JWT)
@@ -120,6 +143,9 @@ Salvos em `reports/` com data no nome. Formato: `security-audit-YYYY-MM-DD.md`.
120143
- Modificacao de claims (role, org_id)
121144
- Timing oracle para enumeracao de usuarios
122145
- Token replay apos logout
146+
- **[CORRIGIDO 2026-04-11]** Refresh token TOCTOU race condition — 2x HTTP 200 em requests paralelas com o mesmo token
147+
- **[CORRIGIDO 2026-04-11]** Refresh token sobrevive ao logout — cliente deve enviar refresh_token no body do logout
148+
- **[CORRIGIDO 2026-04-11]** Refresh token aceito como access token em todos os endpoints autenticados
123149

124150
### Autorizacao
125151
- Multi-tenant IDOR (organization_id scope)
@@ -160,5 +186,9 @@ Salvos em `reports/` com data no nome. Formato: `security-audit-YYYY-MM-DD.md`.
160186

161187
## Resultados
162188

163-
Salvos em `snapshots/` com timestamp. Nunca commitar - adicione ao .gitignore.
189+
Salvos em `snapshots/` com timestamp.
190+
191+
- Nunca commitados
192+
193+
- adicionados ao .gitignore.
164194

0 commit comments

Comments
 (0)