insecure-design
Skill23 starsChanged 7 months agoMITView on GitHub
Detect, analyze, and remediate OWASP A06:2025 Insecure Design vulnerabilities in Python web applications (FastAPI and Flask). Use this skill whenever the user asks about architecture-level security flaws, threat modeling, rate limiting gaps, business logic vulnerabilities, insecure file uploads, race conditions, tenant isolation failures, or client-side enforcement of server-side security. Trigger even if the user doesn't say "Insecure Design" explicitly — common signals include: "missing rate limiting", "file upload security", "business logic flaw", "race condition", "multi-tenant isolation", "threat modeling", "STRIDE", "design review", or "can users abuse this flow". Also trigger for code reviews or audits where architecture-level security controls are being evaluated, not just implementation bugs.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- thejefflarson/soundchecktheir own version, first seen Jul 31, 2026
- swapniltamse/claude-security-engineertheir own version, first seen May 25, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- thejefflarson/soundcheck★ 20same name
- swapniltamse/claude-security-engineer★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository9 other files it gives its agents.
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 4 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 48
Verify that login, registration, password reset, and high-value transaction endpoints enforce rate limits.
- Distinctive: line 104
No file size cap
- Distinctive: line 131
No idempotency key or duplicate-check on financial transactions
- Distinctive: line 209
Use STRIDE to find design flaws before they reach code:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
OWASP A06:2025 — Insecure Design
What This Skill Does
Guides detection, analysis, and remediation of Insecure Design vulnerabilities — architecture-level failures where security controls are absent or structurally inadequate. Unlike implementation bugs, insecure design cannot be fixed by patching code alone; it requires redesigning the flow or adding missing control layers.
OWASP 2025 position: #6 (down from #4 in 2021, as threat modeling adoption has improved)
CWEs covered: 39 | Avg incidence: 1.86%
Key CWEs: CWE-434, CWE-269, CWE-362, CWE-799, CWE-602
Core Concepts
Design vs. Implementation
| Insecure Design (A06) | Implementation Bug (other categories) |
| Rate limiting never architected into login flow | Rate limiter present but misconfigured |
| File upload stored in web root by design | Upload handler missing extension check |
| No tenant isolation in multi-tenant DB schema | Query missing WHERE clause |
| Business logic allows negative quantities | Missing server-side input validation |
A design flaw requires adding a new control or refactoring the architecture, not just patching existing code.
Testing Checklist for FastAPI / Flask
1. Rate Limiting (CWE-799)
Verify that login, registration, password reset, and high-value transaction endpoints enforce rate limits.
FastAPI — SlowAPI:
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
@app.post("/login")
@limiter.limit("5/minute")
async def login(request: Request, ...): ...Flask — Flask-Limiter:
from flask_limiter import Limiter
limiter = Limiter(app, key_func=get_remote_address)
@app.route("/login", methods=["POST"])
@limiter.limit("5 per minute")
def login(): ...Red flags to flag in review:
- Login,
/register,/reset-password,/checkoutroutes with no rate-limiting decorator RATELIMIT_ENABLED = Falseor limiter initialized without being applied to sensitive routes- Rate limits too permissive (e.g.,
1000/minuteon auth endpoints)
2. File Upload Security (CWE-434)
File uploads must be validated by content, not just extension, and stored outside the web root.
import magic # python-magic
ALLOWED_MIME = {"image/jpeg", "image/png", "application/pdf"}
MAX_SIZE = 5 * 1024 * 1024 # 5 MB
@app.post("/upload")
async def upload(file: UploadFile):
content = await file.read(MAX_SIZE + 1)
if len(content) > MAX_SIZE:
raise HTTPException(400, "File too large")
mime = magic.from_buffer(content[:2048], mime=True)
if mime not in ALLOWED_MIME:
raise HTTPException(400, "Unsupported file type")
# Store in /var/app/uploads/ — NOT inside static/ or public/
safe_path = UPLOAD_DIR / secrets.token_hex(16)
safe_path.write_bytes(content)Red flags:
- Relying on
file.content_typeor extension alone (filename.endswith(".jpg")) - Storing uploads in
static/,public/, or any web-accessible path - No file size cap
- Serving uploaded files via direct URL without authentication
3. Business Logic Flaws
Business logic flaws are application-specific — they exploit valid flows in unintended ways.
Common patterns to test:
| Scenario | Test |
| Negative quantity in cart | POST with quantity: -1, verify order total doesn't go negative |
| Price manipulation | POST with a price field — verify server ignores client-supplied price |
| Concurrent purchase race | Parallel requests to buy last item — verify only one succeeds |
| Booking system abuse | Book same slot twice in parallel |
| Coupon reuse | Apply same coupon twice before first transaction commits |
FastAPI example — safe quantity handling:
class OrderItem(BaseModel):
product_id: int
quantity: int = Field(..., ge=1, le=100) # enforced server-sideRed flags:
- Price, discount, or role fields accepted from client payload
- No idempotency key or duplicate-check on financial transactions
- Quantity or amount not bounded with
ge=1in Pydantic or equivalent
4. Tenant Isolation (CWE-269)
In multi-tenant apps, every DB query must scope to the authenticated tenant.
Pattern to enforce:
# UNSAFE — returns data across all tenants
def get_reports(db: Session):
return db.query(Report).all()
# SAFE — scoped to current tenant
def get_reports(db: Session, current_user: User):
return db.query(Report).filter(Report.tenant_id == current_user.tenant_id).all()Red flags:
- Any
db.query(Model).all()without tenant/user filter - Admin-like queries reachable from user-facing endpoints
- Tenant ID passed in request body (must come from JWT/session, not user input)
5. Client-Side Enforcement of Server-Side Security (CWE-602)
Security enforced only in the browser is trivially bypassed via direct API calls.
Red flags:
- Authorization check only in JavaScript / frontend, not in the API route
- Hidden form fields controlling price, role, or access level
- Feature flags based on client-provided values (use JWT claims or server session)
# WRONG — trusting client-supplied role
@app.post("/admin/action")
async def admin_action(role: str = Body(...)): # never do this
if role == "admin":
...
# CORRECT — derive from authenticated token
@app.post("/admin/action")
async def admin_action(current_user: User = Depends(get_current_user)):
if current_user.role != "admin":
raise HTTPException(403)
...6. Credential / Account Recovery Design
Insecure recovery flows are a design flaw, not an implementation bug.
Red flags:
- Knowledge-based security questions (mother's maiden name, pet name) — guessable from social media
- Password reset link not expiring within 15–60 minutes
- Reset token sent over HTTP or stored without hashing
- Account enumeration possible via reset flow ("no account found" vs. silent success)
Safe pattern:
# Generate short-lived, single-use, high-entropy token
token = secrets.token_urlsafe(32)
expiry = datetime.utcnow() + timedelta(minutes=30)
# Store hash of token, not the token itself
db_token = PasswordResetToken(
user_id=user.id,
token_hash=hashlib.sha256(token.encode()).hexdigest(),
expires_at=expiry,
used=False
)Threat Modeling Guidance (STRIDE)
Use STRIDE to find design flaws before they reach code:
| Threat | Applies to | Example in FastAPI/Flask |
| Spoofing | Auth flows | Predictable session tokens, missing MFA |
| Tampering | Data in transit/storage | Missing HMAC on signed data, writable uploads |
| Repudiation | Audit logs | Missing request logging on financial actions |
| Information Disclosure | Error messages, API docs | /docs open in prod, stack traces in 500 |
| Denial of Service | Rate limiting, resource use | No request size cap, missing rate limiter |
| Elevation of Privilege | Authorization design | Client-supplied role, missing tenant scope |
Remediation Priority Matrix
| Finding | Severity | Fix complexity |
| No rate limiting on auth/payment endpoints | High | Low — add SlowAPI/Flask-Limiter |
| File uploads stored in web root | High | Medium — move storage path, add serving layer |
| Client-supplied price/role fields | Critical | Low — remove field from request model |
| Missing tenant scope on DB queries | Critical | Medium — audit all queries |
| Knowledge-based security questions | Medium | High — redesign recovery flow |
| Race condition on inventory/booking | Medium | High — add DB-level locking or idempotency |
Reference Material
For deeper dives, see:
references/cwe-details.md— full CWE descriptions and examples for all 39 CWEs in A06references/threat-modeling.md— STRIDE worksheet template for FastAPI/Flask apps
For related OWASP categories that overlap with design issues:
- A01 Broken Access Control — when the design grants too much access by default
- A07 Authentication Failures — when auth flow design is the root cause
- A10 Mishandling of Exceptional Conditions — when error recovery design fails closed
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

