📦 deps(thirdparty): update snapshots
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antigravity-bundle-aas-secure-app-builder",
|
||||
"version": "12.9.0",
|
||||
"version": "13.0.0",
|
||||
"description": "Editorial \"AAS Secure App Builder\" bundle for Claude Code from Antigravity Awesome Skills.",
|
||||
"author": {
|
||||
"name": "sickn33 and contributors",
|
||||
|
||||
+10
-5
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "agyb-aas-secure-app-builder",
|
||||
"version": "12.9.0",
|
||||
"description": "Install the \"AAS Secure App Builder\" editorial skill bundle from Antigravity Awesome Skills.",
|
||||
"version": "13.0.0",
|
||||
"description": "Install the \"AAS Secure App Builder\" workflow plugin from Antigravity Awesome Skills.",
|
||||
"author": {
|
||||
"name": "sickn33 and contributors",
|
||||
"url": "https://github.com/sickn33/antigravity-awesome-skills"
|
||||
@@ -19,8 +19,8 @@
|
||||
"skills": "./skills/",
|
||||
"interface": {
|
||||
"displayName": "AAS Secure App Builder",
|
||||
"shortDescription": "Specialized Product Plugins · 8 curated skills",
|
||||
"longDescription": "Application developers who want security embedded while building features. Covers API Security Best Practices, Auth Implementation Patterns, and 6 more skills.",
|
||||
"shortDescription": "Build application features with auth, access control, API security, PCI, SAST, and defensive review baked in.",
|
||||
"longDescription": "Build application features with auth, access control, API security, PCI, SAST, and defensive review baked in. Separates defensive implementation from offensive assessment, making a safer and clearer plugin for product engineering teams. Recommended for: Application developers, Product engineering teams, Security-conscious backend and frontend builders. Not for: Offensive pentest engagements, Infrastructure-only reviews. Covers API Security Best Practices, Auth Implementation Patterns, and 8 more skills.",
|
||||
"developerName": "sickn33 and contributors",
|
||||
"category": "Specialized Product Plugins",
|
||||
"capabilities": [
|
||||
@@ -28,6 +28,11 @@
|
||||
"Write"
|
||||
],
|
||||
"websiteURL": "https://github.com/sickn33/antigravity-awesome-skills",
|
||||
"brandColor": "#111827"
|
||||
"brandColor": "#111827",
|
||||
"defaultPrompt": [
|
||||
"Use this plugin to review this PR for auth, access control, data exposure, injection, and secrets risks.",
|
||||
"Use this plugin to design a secure API feature with validation, authorization, and auditability.",
|
||||
"Use this plugin to harden this payment, authentication, or user-data flow before release."
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
+480
@@ -0,0 +1,480 @@
|
||||
---
|
||||
name: broken-authentication
|
||||
description: "Identify and exploit authentication and session management vulnerabilities in web applications. Broken authentication consistently ranks in the OWASP Top 10 and can lead to account takeover, identity theft, and unauthorized access to sensitive systems."
|
||||
risk: unknown
|
||||
source: community
|
||||
author: zebbern
|
||||
date_added: "2026-02-27"
|
||||
---
|
||||
|
||||
# Broken Authentication Testing
|
||||
|
||||
## Purpose
|
||||
|
||||
Identify and exploit authentication and session management vulnerabilities in web applications. Broken authentication consistently ranks in the OWASP Top 10 and can lead to account takeover, identity theft, and unauthorized access to sensitive systems. This skill covers testing methodologies for password policies, session handling, multi-factor authentication, and credential management.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Required Knowledge
|
||||
- HTTP protocol and session mechanisms
|
||||
- Authentication types (SFA, 2FA, MFA)
|
||||
- Cookie and token handling
|
||||
- Common authentication frameworks
|
||||
|
||||
### Required Tools
|
||||
- Burp Suite Professional or Community
|
||||
- Hydra or similar brute-force tools
|
||||
- Custom wordlists for credential testing
|
||||
- Browser developer tools
|
||||
|
||||
### Required Access
|
||||
- Target application URL
|
||||
- Test account credentials
|
||||
- Written authorization for testing
|
||||
|
||||
## Outputs and Deliverables
|
||||
|
||||
1. **Authentication Assessment Report** - Document all identified vulnerabilities
|
||||
2. **Credential Testing Results** - Brute-force and dictionary attack outcomes
|
||||
3. **Session Security Analysis** - Token randomness and timeout evaluation
|
||||
4. **Remediation Recommendations** - Security hardening guidance
|
||||
|
||||
## Core Workflow
|
||||
|
||||
### Phase 1: Authentication Mechanism Analysis
|
||||
|
||||
Understand the application's authentication architecture:
|
||||
|
||||
```
|
||||
# Identify authentication type
|
||||
- Password-based (forms, basic auth, digest)
|
||||
- Token-based (JWT, OAuth, API keys)
|
||||
- Certificate-based (mutual TLS)
|
||||
- Multi-factor (SMS, TOTP, hardware tokens)
|
||||
|
||||
# Map authentication endpoints
|
||||
/login, /signin, /authenticate
|
||||
/register, /signup
|
||||
/forgot-password, /reset-password
|
||||
/logout, /signout
|
||||
/api/auth/*, /oauth/*
|
||||
```
|
||||
|
||||
Capture and analyze authentication requests:
|
||||
|
||||
```http
|
||||
POST /login HTTP/1.1
|
||||
Host: target.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
username=test&password=test123
|
||||
```
|
||||
|
||||
### Phase 2: Password Policy Testing
|
||||
|
||||
Evaluate password requirements and enforcement:
|
||||
|
||||
```bash
|
||||
# Test minimum length (a, ab, abcdefgh)
|
||||
# Test complexity (password, password1, Password1!)
|
||||
# Test common weak passwords (123456, password, qwerty, admin)
|
||||
# Test username as password (admin/admin, test/test)
|
||||
```
|
||||
|
||||
Document policy gaps: Minimum length <8, no complexity, common passwords allowed, username as password.
|
||||
|
||||
### Phase 3: Credential Enumeration
|
||||
|
||||
Test for username enumeration vulnerabilities:
|
||||
|
||||
```bash
|
||||
# Compare responses for valid vs invalid usernames
|
||||
# Invalid: "Invalid username" vs Valid: "Invalid password"
|
||||
# Check timing differences, response codes, registration messages
|
||||
```
|
||||
|
||||
# Password reset
|
||||
"Email sent if account exists" (secure)
|
||||
"No account with that email" (leaks info)
|
||||
|
||||
# API responses
|
||||
{"error": "user_not_found"}
|
||||
{"error": "invalid_password"}
|
||||
```
|
||||
|
||||
### Phase 4: Brute Force Testing
|
||||
|
||||
Test account lockout and rate limiting:
|
||||
|
||||
```bash
|
||||
# Using Hydra for form-based auth
|
||||
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
|
||||
target.com http-post-form \
|
||||
"/login:username=^USER^&password=^PASS^:Invalid credentials"
|
||||
|
||||
# Using Burp Intruder
|
||||
1. Capture login request
|
||||
2. Send to Intruder
|
||||
3. Set payload positions on password field
|
||||
4. Load wordlist
|
||||
5. Start attack
|
||||
6. Analyze response lengths/codes
|
||||
```
|
||||
|
||||
Check for protections:
|
||||
|
||||
```bash
|
||||
# Account lockout
|
||||
- After how many attempts?
|
||||
- Duration of lockout?
|
||||
- Lockout notification?
|
||||
|
||||
# Rate limiting
|
||||
- Requests per minute limit?
|
||||
- IP-based or account-based?
|
||||
- Bypass via headers (X-Forwarded-For)?
|
||||
|
||||
# CAPTCHA
|
||||
- After failed attempts?
|
||||
- Easily bypassable?
|
||||
```
|
||||
|
||||
### Phase 5: Credential Stuffing
|
||||
|
||||
Test with known breached credentials:
|
||||
|
||||
```bash
|
||||
# Credential stuffing differs from brute force
|
||||
# Uses known email:password pairs from breaches
|
||||
|
||||
# Using Burp Intruder with Pitchfork attack
|
||||
1. Set username and password as positions
|
||||
2. Load email list as payload 1
|
||||
3. Load password list as payload 2 (matched pairs)
|
||||
4. Analyze for successful logins
|
||||
|
||||
# Detection evasion
|
||||
- Slow request rate
|
||||
- Rotate source IPs
|
||||
- Randomize user agents
|
||||
- Add delays between attempts
|
||||
```
|
||||
|
||||
### Phase 6: Session Management Testing
|
||||
|
||||
Analyze session token security:
|
||||
|
||||
```bash
|
||||
# Capture session cookie
|
||||
Cookie: SESSIONID=abc123def456
|
||||
|
||||
# Test token characteristics
|
||||
1. Entropy - Is it random enough?
|
||||
2. Length - Sufficient length (128+ bits)?
|
||||
3. Predictability - Sequential patterns?
|
||||
4. Secure flags - HttpOnly, Secure, SameSite?
|
||||
```
|
||||
|
||||
Session token analysis:
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import requests
|
||||
import hashlib
|
||||
|
||||
# Collect multiple session tokens
|
||||
tokens = []
|
||||
for i in range(100):
|
||||
response = requests.get("https://target.com/login")
|
||||
token = response.cookies.get("SESSIONID")
|
||||
tokens.append(token)
|
||||
|
||||
# Analyze for patterns
|
||||
# Check for sequential increments
|
||||
# Calculate entropy
|
||||
# Look for timestamp components
|
||||
```
|
||||
|
||||
### Phase 7: Session Fixation Testing
|
||||
|
||||
Test if session is regenerated after authentication:
|
||||
|
||||
```bash
|
||||
# Step 1: Get session before login
|
||||
GET /login HTTP/1.1
|
||||
Response: Set-Cookie: SESSIONID=abc123
|
||||
|
||||
# Step 2: Login with same session
|
||||
POST /login HTTP/1.1
|
||||
Cookie: SESSIONID=abc123
|
||||
username=valid&password=valid
|
||||
|
||||
# Step 3: Check if session changed
|
||||
# VULNERABLE if SESSIONID remains abc123
|
||||
# SECURE if new session assigned after login
|
||||
```
|
||||
|
||||
Attack scenario:
|
||||
|
||||
```bash
|
||||
# Attacker workflow:
|
||||
1. Attacker visits site, gets session: SESSIONID=attacker_session
|
||||
2. Attacker sends link to victim with fixed session:
|
||||
https://target.com/login?SESSIONID=attacker_session
|
||||
3. Victim logs in with attacker's session
|
||||
4. Attacker now has authenticated session
|
||||
```
|
||||
|
||||
### Phase 8: Session Timeout Testing
|
||||
|
||||
Verify session expiration policies:
|
||||
|
||||
```bash
|
||||
# Test idle timeout
|
||||
1. Login and note session cookie
|
||||
2. Wait without activity (15, 30, 60 minutes)
|
||||
3. Attempt to use session
|
||||
4. Check if session is still valid
|
||||
|
||||
# Test absolute timeout
|
||||
1. Login and continuously use session
|
||||
2. Check if forced logout after set period (8 hours, 24 hours)
|
||||
|
||||
# Test logout functionality
|
||||
1. Login and note session
|
||||
2. Click logout
|
||||
3. Attempt to reuse old session cookie
|
||||
4. Session should be invalidated server-side
|
||||
```
|
||||
|
||||
### Phase 9: Multi-Factor Authentication Testing
|
||||
|
||||
Assess MFA implementation security:
|
||||
|
||||
```bash
|
||||
# OTP brute force
|
||||
- 4-digit OTP = 10,000 combinations
|
||||
- 6-digit OTP = 1,000,000 combinations
|
||||
- Test rate limiting on OTP endpoint
|
||||
|
||||
# OTP bypass techniques
|
||||
- Skip MFA step by direct URL access
|
||||
- Modify response to indicate MFA passed
|
||||
- Null/empty OTP submission
|
||||
- Previous valid OTP reuse
|
||||
|
||||
# API Version Downgrade Attack (crAPI example)
|
||||
# If /api/v3/check-otp has rate limiting, try older versions:
|
||||
POST /api/v2/check-otp
|
||||
{"otp": "1234"}
|
||||
# Older API versions may lack security controls
|
||||
|
||||
# Using Burp for OTP testing
|
||||
1. Capture OTP verification request
|
||||
2. Send to Intruder
|
||||
3. Set OTP field as payload position
|
||||
4. Use numbers payload (0000-9999)
|
||||
5. Check for successful bypass
|
||||
```
|
||||
|
||||
Test MFA enrollment:
|
||||
|
||||
```bash
|
||||
# Forced enrollment
|
||||
- Can MFA be skipped during setup?
|
||||
- Can backup codes be accessed without verification?
|
||||
|
||||
# Recovery process
|
||||
- Can MFA be disabled via email alone?
|
||||
- Social engineering potential?
|
||||
```
|
||||
|
||||
### Phase 10: Password Reset Testing
|
||||
|
||||
Analyze password reset security:
|
||||
|
||||
```bash
|
||||
# Token security
|
||||
1. Request password reset
|
||||
2. Capture reset link
|
||||
3. Analyze token:
|
||||
- Length and randomness
|
||||
- Expiration time
|
||||
- Single-use enforcement
|
||||
- Account binding
|
||||
|
||||
# Token manipulation
|
||||
https://target.com/reset?token=abc123&user=victim
|
||||
# Try changing user parameter while using valid token
|
||||
|
||||
# Host header injection
|
||||
POST /forgot-password HTTP/1.1
|
||||
Host: attacker.com
|
||||
email=victim@email.com
|
||||
# Reset email may contain attacker's domain
|
||||
```
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Common Vulnerability Types
|
||||
|
||||
| Vulnerability | Risk | Test Method |
|
||||
|--------------|------|-------------|
|
||||
| Weak passwords | High | Policy testing, dictionary attack |
|
||||
| No lockout | High | Brute force testing |
|
||||
| Username enumeration | Medium | Differential response analysis |
|
||||
| Session fixation | High | Pre/post-login session comparison |
|
||||
| Weak session tokens | High | Entropy analysis |
|
||||
| No session timeout | Medium | Long-duration session testing |
|
||||
| Insecure password reset | High | Token analysis, workflow bypass |
|
||||
| MFA bypass | Critical | Direct access, response manipulation |
|
||||
|
||||
### Credential Testing Payloads
|
||||
|
||||
```bash
|
||||
# Default credentials
|
||||
admin:admin
|
||||
admin:password
|
||||
admin:123456
|
||||
root:root
|
||||
test:test
|
||||
user:user
|
||||
|
||||
# Common passwords
|
||||
123456
|
||||
password
|
||||
12345678
|
||||
qwerty
|
||||
abc123
|
||||
password1
|
||||
admin123
|
||||
|
||||
# Breached credential databases
|
||||
- Have I Been Pwned dataset
|
||||
- SecLists passwords
|
||||
- Custom targeted lists
|
||||
```
|
||||
|
||||
### Session Cookie Flags
|
||||
|
||||
| Flag | Purpose | Vulnerability if Missing |
|
||||
|------|---------|------------------------|
|
||||
| HttpOnly | Prevent JS access | XSS can steal session |
|
||||
| Secure | HTTPS only | Sent over HTTP |
|
||||
| SameSite | CSRF protection | Cross-site requests allowed |
|
||||
| Path | URL scope | Broader exposure |
|
||||
| Domain | Domain scope | Subdomain access |
|
||||
| Expires | Lifetime | Persistent sessions |
|
||||
|
||||
### Rate Limiting Bypass Headers
|
||||
|
||||
```http
|
||||
X-Forwarded-For: 127.0.0.1
|
||||
X-Real-IP: 127.0.0.1
|
||||
X-Originating-IP: 127.0.0.1
|
||||
X-Client-IP: 127.0.0.1
|
||||
X-Remote-IP: 127.0.0.1
|
||||
True-Client-IP: 127.0.0.1
|
||||
```
|
||||
|
||||
## Constraints and Limitations
|
||||
|
||||
### Legal Requirements
|
||||
- Only test with explicit written authorization
|
||||
- Avoid testing with real breached credentials
|
||||
- Do not access actual user accounts
|
||||
- Document all testing activities
|
||||
|
||||
### Technical Limitations
|
||||
- CAPTCHA may prevent automated testing
|
||||
- Rate limiting affects brute force timing
|
||||
- MFA significantly increases attack difficulty
|
||||
- Some vulnerabilities require victim interaction
|
||||
|
||||
### Scope Considerations
|
||||
- Test accounts may behave differently than production
|
||||
- Some features may be disabled in test environments
|
||||
- Third-party authentication may be out of scope
|
||||
- Production testing requires extra caution
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Account Lockout Bypass
|
||||
|
||||
**Scenario:** Test if account lockout can be bypassed
|
||||
|
||||
```bash
|
||||
# Step 1: Identify lockout threshold
|
||||
# Try 5 wrong passwords for admin account
|
||||
# Result: "Account locked for 30 minutes"
|
||||
|
||||
# Step 2: Test bypass via IP rotation
|
||||
# Use X-Forwarded-For header
|
||||
POST /login HTTP/1.1
|
||||
X-Forwarded-For: 192.168.1.1
|
||||
username=admin&password=attempt1
|
||||
|
||||
# Increment IP for each attempt
|
||||
X-Forwarded-For: 192.168.1.2
|
||||
# Continue until successful or confirmed blocked
|
||||
|
||||
# Step 3: Test bypass via case manipulation
|
||||
username=Admin (vs admin)
|
||||
username=ADMIN
|
||||
# Some systems treat these as different accounts
|
||||
```
|
||||
|
||||
### Example 2: JWT Token Attack
|
||||
|
||||
**Scenario:** Exploit weak JWT implementation
|
||||
|
||||
```bash
|
||||
# Step 1: Capture JWT token
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidGVzdCJ9.signature
|
||||
|
||||
# Step 2: Decode and analyze
|
||||
# Header: {"alg":"HS256","typ":"JWT"}
|
||||
# Payload: {"user":"test","role":"user"}
|
||||
|
||||
# Step 3: Try "none" algorithm attack
|
||||
# Change header to: {"alg":"none","typ":"JWT"}
|
||||
# Remove signature
|
||||
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4ifQ.
|
||||
|
||||
# Step 4: Submit modified token
|
||||
Authorization: Bearer eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4ifQ.
|
||||
```
|
||||
|
||||
### Example 3: Password Reset Token Exploitation
|
||||
|
||||
**Scenario:** Test password reset functionality
|
||||
|
||||
```bash
|
||||
# Step 1: Request reset for test account
|
||||
POST /forgot-password
|
||||
email=test@example.com
|
||||
|
||||
# Step 2: Capture reset link
|
||||
https://target.com/reset?token=a1b2c3d4e5f6
|
||||
|
||||
# Step 3: Test token properties
|
||||
# Reuse: Try using same token twice
|
||||
# Expiration: Wait 24+ hours and retry
|
||||
# Modification: Change characters in token
|
||||
|
||||
# Step 4: Test for user parameter manipulation
|
||||
https://target.com/reset?token=a1b2c3d4e5f6&email=admin@example.com
|
||||
# Check if admin's password can be reset with test user's token
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | Solutions |
|
||||
|-------|-----------|
|
||||
| Brute force too slow | Identify rate limit scope; IP rotation; add delays; use targeted wordlists |
|
||||
| Session analysis inconclusive | Collect 1000+ tokens; use statistical tools; check for timestamps; compare accounts |
|
||||
| MFA cannot be bypassed | Document as secure; test backup/recovery mechanisms; check MFA fatigue; verify enrollment |
|
||||
| Account lockout prevents testing | Request multiple test accounts; test threshold first; use slower timing |
|
||||
|
||||
## When to Use
|
||||
This skill is applicable to execute the workflow or actions described in the overview.
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
---
|
||||
name: django-access-review
|
||||
description: django-access-review
|
||||
risk: unknown
|
||||
source: community
|
||||
---
|
||||
|
||||
---
|
||||
name: django-access-review
|
||||
description: Django access control and IDOR security review. Use when reviewing Django views, DRF viewsets, ORM queries, or any Python/Django code handling user authorization. Trigger keywords: "IDOR", "access control", "authorization", "Django permissions", "object permissions", "tenant...
|
||||
--- LICENSE
|
||||
---
|
||||
|
||||
<!--
|
||||
Reference material based on OWASP Cheat Sheet Series (CC BY-SA 4.0)
|
||||
https://cheatsheetseries.owasp.org/
|
||||
-->
|
||||
|
||||
# Django Access Control & IDOR Review
|
||||
|
||||
Find access control vulnerabilities by investigating how the codebase answers one question:
|
||||
|
||||
**Can User A access, modify, or delete User B's data?**
|
||||
|
||||
## When to Use
|
||||
- You need to review Django or DRF code for access control gaps, IDOR risk, or object-level authorization failures.
|
||||
- The task involves confirming whether one user can access, modify, or delete another user's data.
|
||||
- You want an investigation-driven authorization review instead of generic pattern matching.
|
||||
|
||||
## Philosophy: Investigation Over Pattern Matching
|
||||
|
||||
Do NOT scan for predefined vulnerable patterns. Instead:
|
||||
|
||||
1. **Understand** how authorization works in THIS codebase
|
||||
2. **Ask questions** about specific data flows
|
||||
3. **Trace code** to find where (or if) access checks happen
|
||||
4. **Report** only what you've confirmed through investigation
|
||||
|
||||
Every codebase implements authorization differently. Your job is to understand this specific implementation, then find gaps.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Understand the Authorization Model
|
||||
|
||||
Before looking for bugs, answer these questions about the codebase:
|
||||
|
||||
### How is authorization enforced?
|
||||
|
||||
Research the codebase to find:
|
||||
|
||||
```
|
||||
□ Where are permission checks implemented?
|
||||
- Decorators? (@login_required, @permission_required, custom?)
|
||||
- Middleware? (TenantMiddleware, AuthorizationMiddleware?)
|
||||
- Base classes? (BaseAPIView, TenantScopedViewSet?)
|
||||
- Permission classes? (DRF permission_classes?)
|
||||
- Custom mixins? (OwnershipMixin, TenantMixin?)
|
||||
|
||||
□ How are queries scoped?
|
||||
- Custom managers? (TenantManager, UserScopedManager?)
|
||||
- get_queryset() overrides?
|
||||
- Middleware that sets query context?
|
||||
|
||||
□ What's the ownership model?
|
||||
- Single user ownership? (document.owner_id)
|
||||
- Organization/tenant ownership? (document.organization_id)
|
||||
- Hierarchical? (org -> team -> user -> resource)
|
||||
- Role-based within context? (org admin vs member)
|
||||
```
|
||||
|
||||
### Investigation commands
|
||||
|
||||
```bash
|
||||
# Find how auth is typically done
|
||||
grep -rn "permission_classes\|@login_required\|@permission_required" --include="*.py" | head -20
|
||||
|
||||
# Find base classes that views inherit from
|
||||
grep -rn "class Base.*View\|class.*Mixin.*:" --include="*.py" | head -20
|
||||
|
||||
# Find custom managers
|
||||
grep -rn "class.*Manager\|def get_queryset" --include="*.py" | head -20
|
||||
|
||||
# Find ownership fields on models
|
||||
grep -rn "owner\|user_id\|organization\|tenant" --include="models.py" | head -30
|
||||
```
|
||||
|
||||
**Do not proceed until you understand the authorization model.**
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Map the Attack Surface
|
||||
|
||||
Identify endpoints that handle user-specific data:
|
||||
|
||||
### What resources exist?
|
||||
|
||||
```
|
||||
□ What models contain user data?
|
||||
□ Which have ownership fields (owner_id, user_id, organization_id)?
|
||||
□ Which are accessed via ID in URLs or request bodies?
|
||||
```
|
||||
|
||||
### What operations are exposed?
|
||||
|
||||
For each resource, map:
|
||||
- List endpoints - what data is returned?
|
||||
- Detail/retrieve endpoints - how is the object fetched?
|
||||
- Create endpoints - who sets the owner?
|
||||
- Update endpoints - can users modify others' data?
|
||||
- Delete endpoints - can users delete others' data?
|
||||
- Custom actions - what do they access?
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Ask Questions and Investigate
|
||||
|
||||
For each endpoint that handles user data, ask:
|
||||
|
||||
### The Core Question
|
||||
|
||||
**"If I'm User A and I know the ID of User B's resource, can I access it?"**
|
||||
|
||||
Trace the code to answer this:
|
||||
|
||||
```
|
||||
1. Where does the resource ID enter the system?
|
||||
- URL path: /api/documents/{id}/
|
||||
- Query param: ?document_id=123
|
||||
- Request body: {"document_id": 123}
|
||||
|
||||
2. Where is that ID used to fetch data?
|
||||
- Find the ORM query or database call
|
||||
|
||||
3. Between (1) and (2), what checks exist?
|
||||
- Is the query scoped to current user?
|
||||
- Is there an explicit ownership check?
|
||||
- Is there a permission check on the object?
|
||||
- Does a base class or mixin enforce access?
|
||||
|
||||
4. If you can't find a check, is there one you missed?
|
||||
- Check parent classes
|
||||
- Check middleware
|
||||
- Check managers
|
||||
- Check decorators at URL level
|
||||
```
|
||||
|
||||
### Follow-Up Questions
|
||||
|
||||
```
|
||||
□ For list endpoints: Does the query filter to user's data, or return everything?
|
||||
|
||||
□ For create endpoints: Who sets the owner - the server or the request?
|
||||
|
||||
□ For bulk operations: Are they scoped to user's data?
|
||||
|
||||
□ For related resources: If I can access a document, can I access its comments?
|
||||
What if the document belongs to someone else?
|
||||
|
||||
□ For tenant/org resources: Can User in Org A access Org B's data by changing
|
||||
the org_id in the URL?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Trace Specific Flows
|
||||
|
||||
Pick a concrete endpoint and trace it completely.
|
||||
|
||||
### Example Investigation
|
||||
|
||||
```
|
||||
Endpoint: GET /api/documents/{pk}/
|
||||
|
||||
1. Find the view handling this URL
|
||||
→ DocumentViewSet.retrieve() in api/views.py
|
||||
|
||||
2. Check what DocumentViewSet inherits from
|
||||
→ class DocumentViewSet(viewsets.ModelViewSet)
|
||||
→ No custom base class with authorization
|
||||
|
||||
3. Check permission_classes
|
||||
→ permission_classes = [IsAuthenticated]
|
||||
→ Only checks login, not ownership
|
||||
|
||||
4. Check get_queryset()
|
||||
→ def get_queryset(self):
|
||||
→ return Document.objects.all()
|
||||
→ Returns ALL documents!
|
||||
|
||||
5. Check for has_object_permission()
|
||||
→ Not implemented
|
||||
|
||||
6. Check retrieve() method
|
||||
→ Uses default, which calls get_object()
|
||||
→ get_object() uses get_queryset(), which returns all
|
||||
|
||||
7. Conclusion: IDOR - Any authenticated user can access any document
|
||||
```
|
||||
|
||||
### What to look for when tracing
|
||||
|
||||
```
|
||||
Potential gap indicators (investigate further, don't auto-flag):
|
||||
- get_queryset() returns .all() or filters without user
|
||||
- Direct Model.objects.get(pk=pk) without ownership in query
|
||||
- ID comes from request body for sensitive operations
|
||||
- Permission class checks auth but not ownership
|
||||
- No has_object_permission() and queryset isn't scoped
|
||||
|
||||
Likely safe patterns (but verify the implementation):
|
||||
- get_queryset() filters by request.user or user's org
|
||||
- Custom permission class with has_object_permission()
|
||||
- Base class that enforces scoping
|
||||
- Manager that auto-filters
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Report Findings
|
||||
|
||||
Only report issues you've confirmed through investigation.
|
||||
|
||||
### Confidence Levels
|
||||
|
||||
| Level | Meaning | Action |
|
||||
|-------|---------|--------|
|
||||
| **HIGH** | Traced the flow, confirmed no check exists | Report with evidence |
|
||||
| **MEDIUM** | Check may exist but couldn't confirm | Note for manual verification |
|
||||
| **LOW** | Theoretical, likely mitigated | Do not report |
|
||||
|
||||
### Suggested Fixes Must Enforce, Not Document
|
||||
|
||||
**Bad fix**: Adding a comment saying "caller must validate permissions"
|
||||
**Good fix**: Adding code that actually validates permissions
|
||||
|
||||
A comment or docstring does not enforce authorization. Your suggested fix must include actual code that:
|
||||
- Validates the user has permission before proceeding
|
||||
- Raises an exception or returns an error if unauthorized
|
||||
- Makes unauthorized access impossible, not just discouraged
|
||||
|
||||
Example of a BAD fix suggestion:
|
||||
```python
|
||||
def get_resource(resource_id):
|
||||
# IMPORTANT: Caller must ensure user has access to this resource
|
||||
return Resource.objects.get(pk=resource_id)
|
||||
```
|
||||
|
||||
Example of a GOOD fix suggestion:
|
||||
```python
|
||||
def get_resource(resource_id, user):
|
||||
resource = Resource.objects.get(pk=resource_id)
|
||||
if resource.owner_id != user.id:
|
||||
raise PermissionDenied("Access denied")
|
||||
return resource
|
||||
```
|
||||
|
||||
If you can't determine the right enforcement mechanism, say so - but never suggest documentation as the fix.
|
||||
|
||||
### Report Format
|
||||
|
||||
```markdown
|
||||
## Access Control Review: [Component]
|
||||
|
||||
### Authorization Model
|
||||
[Brief description of how this codebase handles authorization]
|
||||
|
||||
### Findings
|
||||
|
||||
#### [IDOR-001] [Title] (Severity: High/Medium)
|
||||
- **Location**: `path/to/file.py:123`
|
||||
- **Confidence**: High - confirmed through code tracing
|
||||
- **The Question**: Can User A access User B's documents?
|
||||
- **Investigation**:
|
||||
1. Traced GET /api/documents/{pk}/ to DocumentViewSet
|
||||
2. Checked get_queryset() - returns Document.objects.all()
|
||||
3. Checked permission_classes - only IsAuthenticated
|
||||
4. Checked for has_object_permission() - not implemented
|
||||
5. Verified no relevant middleware or base class checks
|
||||
- **Evidence**: [Code snippet showing the gap]
|
||||
- **Impact**: Any authenticated user can read any document by ID
|
||||
- **Suggested Fix**: [Code that enforces authorization - NOT a comment]
|
||||
|
||||
### Needs Manual Verification
|
||||
[Issues where authorization exists but couldn't confirm effectiveness]
|
||||
|
||||
### Areas Not Reviewed
|
||||
[Endpoints or flows not covered in this review]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Django Authorization Patterns
|
||||
|
||||
These are patterns you might find - not a checklist to match against.
|
||||
|
||||
### Query Scoping
|
||||
```python
|
||||
# Scoped to user
|
||||
Document.objects.filter(owner=request.user)
|
||||
|
||||
# Scoped to organization
|
||||
Document.objects.filter(organization=request.user.organization)
|
||||
|
||||
# Using a custom manager
|
||||
Document.objects.for_user(request.user) # Investigate what this does
|
||||
```
|
||||
|
||||
### Permission Enforcement
|
||||
```python
|
||||
# DRF permission classes
|
||||
permission_classes = [IsAuthenticated, IsOwner]
|
||||
|
||||
# Custom has_object_permission
|
||||
def has_object_permission(self, request, view, obj):
|
||||
return obj.owner == request.user
|
||||
|
||||
# Django decorators
|
||||
@permission_required('app.view_document')
|
||||
|
||||
# Manual checks
|
||||
if document.owner != request.user:
|
||||
raise PermissionDenied()
|
||||
```
|
||||
|
||||
### Ownership Assignment
|
||||
```python
|
||||
# Server-side (safe)
|
||||
def perform_create(self, serializer):
|
||||
serializer.save(owner=self.request.user)
|
||||
|
||||
# From request (investigate)
|
||||
serializer.save(**request.data) # Does request.data include owner?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Investigation Checklist
|
||||
|
||||
Use this to guide your review, not as a pass/fail checklist:
|
||||
|
||||
```
|
||||
□ I understand how authorization is typically implemented in this codebase
|
||||
□ I've identified the ownership model (user, org, tenant, etc.)
|
||||
□ I've mapped the key endpoints that handle user data
|
||||
□ For each sensitive endpoint, I've traced the flow and asked:
|
||||
- Where does the ID come from?
|
||||
- Where is data fetched?
|
||||
- What checks exist between input and data access?
|
||||
□ I've verified my findings by checking parent classes and middleware
|
||||
□ I've only reported issues I've confirmed through investigation
|
||||
```
|
||||
|
||||
## Limitations
|
||||
- Use this skill only when the task clearly matches the scope described above.
|
||||
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
|
||||
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
|
||||
Reference in New Issue
Block a user