openhack 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. openhack/__init__.py +2 -0
  2. openhack/__main__.py +225 -0
  3. openhack/agents/__init__.py +30 -0
  4. openhack/agents/base.py +230 -0
  5. openhack/agents/browser_verifier.py +679 -0
  6. openhack/agents/browser_verifier_swarm.py +256 -0
  7. openhack/agents/checkpoint.py +89 -0
  8. openhack/agents/context_manager.py +356 -0
  9. openhack/agents/coordinator.py +1105 -0
  10. openhack/agents/endpoint_analyst.py +307 -0
  11. openhack/agents/feature_hunter.py +93 -0
  12. openhack/agents/hunter.py +481 -0
  13. openhack/agents/hunter_swarm.py +385 -0
  14. openhack/agents/llm.py +334 -0
  15. openhack/agents/recon.py +19 -0
  16. openhack/agents/sandbox_verifier.py +396 -0
  17. openhack/agents/sandbox_verifier_swarm.py +250 -0
  18. openhack/agents/session.py +286 -0
  19. openhack/agents/validator.py +217 -0
  20. openhack/agents/validator_swarm.py +106 -0
  21. openhack/auth.py +175 -0
  22. openhack/browser/__init__.py +12 -0
  23. openhack/browser/runner.py +385 -0
  24. openhack/categories.py +130 -0
  25. openhack/config.py +201 -0
  26. openhack/deterministic_recon.py +464 -0
  27. openhack/entry_points.py +745 -0
  28. openhack/framework_classifier.py +515 -0
  29. openhack/framework_detection.py +269 -0
  30. openhack/headless_scan.py +179 -0
  31. openhack/prompts/__init__.py +108 -0
  32. openhack/prompts/browser_verifier.py +171 -0
  33. openhack/prompts/coordinator.py +31 -0
  34. openhack/prompts/django/__init__.py +32 -0
  35. openhack/prompts/django/auth_bypass.py +76 -0
  36. openhack/prompts/django/csrf.py +62 -0
  37. openhack/prompts/django/data_exposure.py +67 -0
  38. openhack/prompts/django/idor.py +74 -0
  39. openhack/prompts/django/injection.py +67 -0
  40. openhack/prompts/django/misconfiguration.py +70 -0
  41. openhack/prompts/django/ssrf.py +64 -0
  42. openhack/prompts/endpoint_analyst.py +122 -0
  43. openhack/prompts/express/__init__.py +29 -0
  44. openhack/prompts/express/auth_bypass.py +71 -0
  45. openhack/prompts/express/data_exposure.py +77 -0
  46. openhack/prompts/express/idor.py +69 -0
  47. openhack/prompts/express/injection.py +75 -0
  48. openhack/prompts/express/misconfiguration.py +72 -0
  49. openhack/prompts/express/ssrf.py +63 -0
  50. openhack/prompts/feature_hunter.py +140 -0
  51. openhack/prompts/flask/__init__.py +29 -0
  52. openhack/prompts/flask/auth_bypass.py +86 -0
  53. openhack/prompts/flask/data_exposure.py +78 -0
  54. openhack/prompts/flask/idor.py +83 -0
  55. openhack/prompts/flask/injection.py +77 -0
  56. openhack/prompts/flask/misconfiguration.py +73 -0
  57. openhack/prompts/flask/ssrf.py +65 -0
  58. openhack/prompts/hunter.py +362 -0
  59. openhack/prompts/hunter_continuation_loop.py +12 -0
  60. openhack/prompts/hunter_continuation_no_findings.py +19 -0
  61. openhack/prompts/hunter_continuation_no_progress.py +22 -0
  62. openhack/prompts/hunter_tool_instructions.py +55 -0
  63. openhack/prompts/nextjs/__init__.py +42 -0
  64. openhack/prompts/nextjs/auth_bypass.py +80 -0
  65. openhack/prompts/nextjs/csrf.py +71 -0
  66. openhack/prompts/nextjs/data_exposure.py +88 -0
  67. openhack/prompts/nextjs/idor.py +64 -0
  68. openhack/prompts/nextjs/injection.py +65 -0
  69. openhack/prompts/nextjs/middleware_bypass.py +75 -0
  70. openhack/prompts/nextjs/misconfiguration.py +92 -0
  71. openhack/prompts/nextjs/server_actions.py +97 -0
  72. openhack/prompts/nextjs/ssrf.py +66 -0
  73. openhack/prompts/nextjs/xss.py +69 -0
  74. openhack/prompts/pr_analysis_system.py +80 -0
  75. openhack/prompts/pr_analysis_user.py +11 -0
  76. openhack/prompts/project_context.py +89 -0
  77. openhack/prompts/recon.py +199 -0
  78. openhack/prompts/reporter.py +88 -0
  79. openhack/prompts/researchers.py +434 -0
  80. openhack/prompts/sandbox_verifier.py +128 -0
  81. openhack/prompts/supabase/__init__.py +39 -0
  82. openhack/prompts/supabase/auth_tokens.py +131 -0
  83. openhack/prompts/supabase/edge_functions.py +150 -0
  84. openhack/prompts/supabase/graphql.py +102 -0
  85. openhack/prompts/supabase/postgrest.py +99 -0
  86. openhack/prompts/supabase/realtime.py +93 -0
  87. openhack/prompts/supabase/rls.py +110 -0
  88. openhack/prompts/supabase/rpc_functions.py +127 -0
  89. openhack/prompts/supabase/storage.py +110 -0
  90. openhack/prompts/supabase/tenant_isolation.py +118 -0
  91. openhack/prompts/validator.py +319 -0
  92. openhack/prompts/validator_continuation_incomplete.py +12 -0
  93. openhack/prompts/validator_tool_instructions.py +29 -0
  94. openhack/quality.py +231 -0
  95. openhack/sandbox/__init__.py +12 -0
  96. openhack/sandbox/orchestrator.py +517 -0
  97. openhack/sandbox/runner.py +177 -0
  98. openhack/scan_session.py +245 -0
  99. openhack/setup.py +452 -0
  100. openhack/static_validator.py +612 -0
  101. openhack/tools/__init__.py +1 -0
  102. openhack/tools/ast_tools.py +307 -0
  103. openhack/tools/coverage.py +1078 -0
  104. openhack/tools/filesystem.py +404 -0
  105. openhack/tools/nextjs.py +258 -0
  106. openhack/tools/registry.py +52 -0
  107. openhack/tui.py +3450 -0
  108. openhack/updates.py +170 -0
  109. openhack-0.1.0.dist-info/METADATA +189 -0
  110. openhack-0.1.0.dist-info/RECORD +113 -0
  111. openhack-0.1.0.dist-info/WHEEL +4 -0
  112. openhack-0.1.0.dist-info/entry_points.txt +2 -0
  113. openhack-0.1.0.dist-info/licenses/LICENSE +661 -0
@@ -0,0 +1,140 @@
1
+ """
2
+ Feature Deep Dive hunter prompt templates.
3
+ """
4
+
5
+ FEATURE_HUNTER_PROMPT = """You are a security researcher performing a deep audit of a codebase. You work exactly like a human security researcher — you read the code, understand the architecture, decide what's interesting, and go deep on the riskiest areas.
6
+
7
+ {project_context}
8
+
9
+ ## Application Context
10
+
11
+ {recon_context}
12
+
13
+ ## How to Work
14
+
15
+ You are NOT a pattern matcher. You are a researcher. Work like this:
16
+
17
+ ### Step 1: Read the Map
18
+ Start by understanding the application's structure:
19
+ - Read the route definitions / URL config to see every endpoint
20
+ - Read the auth middleware / policies to understand how access control works
21
+ - Read the main config files to understand the tech stack
22
+ - Spend your first 10-15 iterations building a mental model of the app
23
+
24
+ ### Step 2: Pick Your Targets
25
+ Based on what you read, identify 3-5 features that are MOST LIKELY to have vulnerabilities:
26
+ - Features that make outbound HTTP requests (webhooks, notifications, URL fetching, favicon download)
27
+ - Features that serve user-uploaded content (file downloads, image serving, attachments)
28
+ - Features that handle authentication or authorization (login, token exchange, permission checks)
29
+ - Features where similar functionality is implemented in multiple places (compare them for inconsistencies)
30
+
31
+ Say out loud which features you're targeting and why.
32
+
33
+ ### Step 3: Go Deep on Each Feature
34
+ For each feature you picked:
35
+
36
+ **Read all the relevant files.** Not just the controller — follow the imports. Read the helper functions, the model definitions, the middleware. Understand the full data flow from user input to dangerous operation.
37
+
38
+ **Compare similar code paths.** This is where the real bugs are. If two endpoints both make outbound requests, compare their URL validation. If two endpoints both serve files, compare their Content-Type handling. Inconsistencies between similar features are the #1 source of CVEs.
39
+
40
+ **Check protection completeness.** When you find a security control (blocklist, sanitizer, auth check), ask: is it complete? Does it cover all cases? What's NOT blocked? What's NOT checked?
41
+
42
+ **Trace cross-file data flows.** When a value is set in file A and used in file B, is it re-validated? Or is it trusted because "it came from our own database"? Look for properties set during creation that change behavior during retrieval.
43
+
44
+ ### Step 4: Report What You Found
45
+ For each finding, provide:
46
+ - The exact vulnerable code (file, line, snippet)
47
+ - The exact protection that's missing or incomplete
48
+ - If it's an inconsistency: show both the secure and insecure version
49
+ - The attack scenario: what request does an attacker send?
50
+
51
+ ## What Makes a Real Finding
52
+
53
+ **Inconsistencies between similar endpoints** — endpoint A validates URLs, endpoint B doesn't. Both make outbound requests. That's an SSRF.
54
+
55
+ **Incomplete protection** — a blocklist that blocks 8 out of 50 dangerous values. A sanitizer that handles HTML but not SVG. An auth check that covers the API but not the websocket.
56
+
57
+ **Cross-file logic bugs** — upload sets mimeType, download uses mimeType to set Content-Type and decides whether to serve inline. If SVGs are processed as images, they get served inline with JavaScript execution.
58
+
59
+ **Missing await / async bugs** — an auth check that isn't awaited, so it returns a Promise (truthy) instead of the actual auth result. The check appears to pass but never actually runs.
60
+
61
+ ## What is NOT a Finding
62
+
63
+ - Dev-only fallbacks (`process.env.SECRET || "default"`)
64
+ - UUIDs as object IDs — can't be brute-forced
65
+ - Intentionally public endpoints (forgot-password, signup)
66
+ - Missing security headers without a companion injection
67
+ - Features working as designed in well-maintained projects
68
+
69
+ ## CRITICAL: Production Code Only
70
+
71
+ Before reporting ANY finding, look at the file path and ask: **"Does this code run in production and is it reachable by attackers?"**
72
+
73
+ DO NOT report findings in:
74
+ - Test, demo, example, sample, tutorial, playground, benchmark, or documentation code
75
+ - CLI tools or scripts that run on the developer's machine, not on a server
76
+ - Debug/diagnostic utilities not meant for production deployment
77
+ - Code generators, build scripts, or migration scripts
78
+
79
+ Use your judgment based on the full path and context. A vulnerability in `demos/http3/demo-server.c` is NOT a finding because nobody deploys demo servers. A vulnerability in `src/tls/handshake.c` IS a finding because it runs in every deployment.
80
+
81
+ **The rule: only report vulnerabilities in code that actually ships to production.**
82
+
83
+ ## Severity Calibration
84
+
85
+ | Category | Default | Raise when... |
86
+ |------------------------|----------|----------------------------------------------------|
87
+ | SQL Injection | critical | -- |
88
+ | Command Injection | critical | -- |
89
+ | RCE | critical | -- |
90
+ | Authentication Bypass | critical | -- |
91
+ | SSRF | high | Internal service reachable, metadata endpoint hit |
92
+ | Path Traversal | high | Sensitive files readable |
93
+ | IDOR | high | Enumerable IDs, sensitive data exposed |
94
+ | Stored XSS | high | No CSP, account takeover possible |
95
+ | Authorization Bypass | high | Privilege escalation to admin |
96
+ | Data Exposure | high | PII or credentials |
97
+ | Open Redirect | medium | Only raise if chained with token theft |
98
+ | CSRF | medium | State-changing on sensitive resource |
99
+
100
+ Think out loud at every step. Explain what you're reading, what you're looking for, what you found, and why it matters.
101
+ """
102
+
103
+ # Keep the extraction prompt for backward compatibility but it's no longer used
104
+ # in the primary flow
105
+ FEATURE_EXTRACTION_PROMPT = """You are analyzing a security reconnaissance report to identify high-risk features for deep-dive vulnerability analysis.
106
+
107
+ Given the reconnaissance summary below, extract the 3-5 features that are MOST LIKELY to contain security vulnerabilities.
108
+
109
+ ## What Makes a Feature High-Risk
110
+
111
+ Prioritize features that:
112
+ 1. **Handle user-controlled data crossing trust boundaries** — file uploads, URL fetching/scraping, deserialization, template rendering, webhook/callback URLs
113
+ 2. **Have custom security logic** — hand-rolled sanitizers, custom blocklists, bespoke auth checks (NOT library-provided protections like Django ORM, Prisma, etc.)
114
+ 3. **Span multiple files** — data set in one place, transformed in another, used in a third. Cross-file data flows are where logic bugs hide.
115
+ 4. **Make outbound requests** — webhook delivery, favicon fetching, URL previews, notification services, RSS fetching
116
+ 5. **Serve user content** — file downloads, image serving, PDF generation, markdown rendering
117
+
118
+ Do NOT select:
119
+ - Standard framework-provided features (login with Passport.js, ORM queries, session management)
120
+ - Features that only exist in test/CLI/docs code
121
+ - Pure client-side features with no server component
122
+
123
+ ## Reconnaissance Summary
124
+
125
+ {recon_summary}
126
+
127
+ ## Attack Surface Data
128
+
129
+ {attack_surface}
130
+
131
+ ## Output Format
132
+
133
+ Return a JSON array of features. Each feature must have:
134
+ - `name`: short snake_case identifier (e.g., "file_uploads", "webhook_delivery")
135
+ - `description`: one sentence describing what the feature does
136
+ - `entry_files`: list of 2-5 key file paths to start the analysis from
137
+ - `risk_reason`: one sentence explaining WHY this feature is high-risk
138
+
139
+ Return ONLY the JSON array, no other text. Keep descriptions under 20 words.
140
+ """
@@ -0,0 +1,29 @@
1
+ """
2
+ Flask vulnerability detection prompts, organized by attack type.
3
+ """
4
+
5
+ from .injection import FLASK_INJECTION_PROMPT
6
+ from .auth_bypass import FLASK_AUTH_BYPASS_PROMPT
7
+ from .idor import FLASK_IDOR_PROMPT
8
+ from .ssrf import FLASK_SSRF_PROMPT
9
+ from .data_exposure import FLASK_DATA_EXPOSURE_PROMPT
10
+ from .misconfiguration import FLASK_MISCONFIGURATION_PROMPT
11
+
12
+ FLASK_PROMPTS = {
13
+ "injection": FLASK_INJECTION_PROMPT,
14
+ "auth_bypass": FLASK_AUTH_BYPASS_PROMPT,
15
+ "idor": FLASK_IDOR_PROMPT,
16
+ "ssrf": FLASK_SSRF_PROMPT,
17
+ "data_exposure": FLASK_DATA_EXPOSURE_PROMPT,
18
+ "misconfiguration": FLASK_MISCONFIGURATION_PROMPT,
19
+ }
20
+
21
+ __all__ = [
22
+ "FLASK_PROMPTS",
23
+ "FLASK_INJECTION_PROMPT",
24
+ "FLASK_AUTH_BYPASS_PROMPT",
25
+ "FLASK_IDOR_PROMPT",
26
+ "FLASK_SSRF_PROMPT",
27
+ "FLASK_DATA_EXPOSURE_PROMPT",
28
+ "FLASK_MISCONFIGURATION_PROMPT",
29
+ ]
@@ -0,0 +1,86 @@
1
+ """
2
+ Flask authentication/authorization bypass detection prompt.
3
+ """
4
+
5
+ FLASK_AUTH_BYPASS_PROMPT = """## Authentication/Authorization Bypass in Flask
6
+
7
+ ### What to Look For
8
+
9
+ 1. **Missing @login_required decorators**
10
+ 2. **Broken Flask-Login is_authenticated checks**
11
+ 3. **Unprotected Blueprint routes**
12
+ 4. **Flask-Admin without auth**
13
+
14
+ ### Flask-Specific Patterns
15
+
16
+ **Missing Decorator (Vulnerable)**:
17
+ ```python
18
+ # VULNERABLE: No auth on sensitive endpoint
19
+ @app.route('/admin/users', methods=['GET', 'DELETE'])
20
+ def manage_users():
21
+ if request.method == 'DELETE':
22
+ User.query.filter_by(id=request.form['id']).delete()
23
+ db.session.commit()
24
+ return jsonify([u.to_dict() for u in User.query.all()])
25
+
26
+ # SAFE: Auth required
27
+ @app.route('/admin/users')
28
+ @login_required
29
+ def manage_users():
30
+ ...
31
+ ```
32
+
33
+ **Blueprint Without Auth (Vulnerable)**:
34
+ ```python
35
+ # VULNERABLE: Entire blueprint has no auth
36
+ admin_bp = Blueprint('admin', __name__, url_prefix='/admin')
37
+
38
+ @admin_bp.route('/settings')
39
+ def admin_settings():
40
+ return jsonify(get_all_settings()) # Exposed!
41
+
42
+ # SAFE: before_request hook for entire blueprint
43
+ @admin_bp.before_request
44
+ @login_required
45
+ def admin_auth():
46
+ if not current_user.is_admin:
47
+ abort(403)
48
+ ```
49
+
50
+ **Flask-Admin Exposure (Vulnerable)**:
51
+ ```python
52
+ # VULNERABLE: Flask-Admin with no auth
53
+ from flask_admin import Admin
54
+ admin = Admin(app)
55
+ admin.add_view(ModelView(User, db.session)) # Anyone can CRUD users!
56
+
57
+ # SAFE: Custom ModelView with auth
58
+ class SecureModelView(ModelView):
59
+ def is_accessible(self):
60
+ return current_user.is_authenticated and current_user.is_admin
61
+ ```
62
+
63
+ **JWT Misconfiguration (Vulnerable)**:
64
+ ```python
65
+ # VULNERABLE: No algorithm restriction
66
+ import jwt
67
+ decoded = jwt.decode(token, secret, algorithms=None) # Accepts 'none'!
68
+
69
+ # VULNERABLE: Weak/hardcoded secret
70
+ app.config['JWT_SECRET_KEY'] = 'super-secret'
71
+ ```
72
+
73
+ ### Search Patterns
74
+
75
+ 1. `grep` for: `@app\\.route`, `@.*\\.route` -- check for `@login_required`
76
+ 2. `grep` for: `Blueprint\\(` -- check if before_request has auth
77
+ 3. `grep` for: `Flask-Admin`, `ModelView` -- check for `is_accessible`
78
+ 4. `grep` for: `jwt\\.decode`, `JWT_SECRET_KEY`
79
+
80
+ ### Severity Assessment
81
+
82
+ - **Critical**: Admin panels or management endpoints without auth
83
+ - **High**: User data modification without auth
84
+ - **Medium**: Read access to non-sensitive data
85
+ - **Low**: Informational endpoints exposed
86
+ """
@@ -0,0 +1,78 @@
1
+ """
2
+ Flask data exposure detection prompt.
3
+ """
4
+
5
+ FLASK_DATA_EXPOSURE_PROMPT = """## Data Exposure in Flask
6
+
7
+ ### What to Look For
8
+
9
+ 1. **jsonify(model.__dict__) leaking internal fields**
10
+ 2. **Marshmallow schemas exposing sensitive fields**
11
+ 3. **DEBUG=True with Werkzeug debugger (RCE!)**
12
+ 4. **Hardcoded app.secret_key**
13
+
14
+ ### Flask-Specific Patterns
15
+
16
+ **Model Dump (Vulnerable)**:
17
+ ```python
18
+ # VULNERABLE: Dumping full model including password hash
19
+ @app.route('/api/users/<int:uid>')
20
+ def get_user(uid):
21
+ user = User.query.get_or_404(uid)
22
+ return jsonify(user.__dict__) # Includes _sa_instance_state, password_hash!
23
+
24
+ # VULNERABLE: vars() or to_dict() without filtering
25
+ return jsonify(vars(user))
26
+ return jsonify({c.name: getattr(user, c.name) for c in user.__table__.columns})
27
+ ```
28
+
29
+ **Marshmallow Over-Exposure (Vulnerable)**:
30
+ ```python
31
+ # VULNERABLE: Includes sensitive fields
32
+ class UserSchema(Schema):
33
+ class Meta:
34
+ fields = ('id', 'username', 'email', 'password_hash', 'is_admin', 'api_key')
35
+
36
+ # SAFE: Exclude sensitive fields
37
+ class UserSchema(Schema):
38
+ class Meta:
39
+ fields = ('id', 'username', 'email')
40
+ ```
41
+
42
+ **Werkzeug Debugger (Critical)**:
43
+ ```python
44
+ # VULNERABLE: DEBUG=True in production = Remote Code Execution!
45
+ app.run(debug=True, host='0.0.0.0')
46
+ # The Werkzeug debugger allows arbitrary Python execution in the browser
47
+ # via the interactive console at /__debugger__
48
+
49
+ # Also check:
50
+ app.config['DEBUG'] = True
51
+ FLASK_DEBUG=1 # in .env or environment
52
+ ```
53
+
54
+ **Secret Key Exposure (Vulnerable)**:
55
+ ```python
56
+ # VULNERABLE: Hardcoded secret (session forgery)
57
+ app.secret_key = 'my-secret-key'
58
+ app.config['SECRET_KEY'] = 'dev-secret'
59
+
60
+ # VULNERABLE: Weak fallback
61
+ app.secret_key = os.environ.get('SECRET_KEY', 'fallback-insecure')
62
+ ```
63
+
64
+ ### Search Patterns
65
+
66
+ 1. `grep` for: `jsonify\\(.*__dict__`, `jsonify\\(vars\\(`, `to_dict\\(`
67
+ 2. `grep` for: `debug=True`, `DEBUG = True`, `FLASK_DEBUG`
68
+ 3. `grep` for: `secret_key =`, `SECRET_KEY`
69
+ 4. `grep` for: `class.*Schema` -- check Meta.fields for sensitive columns
70
+
71
+ ### Severity Assessment
72
+
73
+ - **Critical**: DEBUG=True in production (Werkzeug debugger = RCE)
74
+ - **Critical**: Password hashes or API keys in API responses
75
+ - **High**: Hardcoded SECRET_KEY (session forgery)
76
+ - **High**: PII exposed to unauthorized users
77
+ - **Medium**: Non-sensitive internal data leakage
78
+ """
@@ -0,0 +1,83 @@
1
+ """
2
+ Flask IDOR (Insecure Direct Object Reference) detection prompt.
3
+ """
4
+
5
+ FLASK_IDOR_PROMPT = """## IDOR (Insecure Direct Object Reference) Detection in Flask
6
+
7
+ ### What to Look For
8
+
9
+ 1. **URL parameters used directly in SQLAlchemy queries without ownership check**
10
+ 2. **Missing filter_by(user_id=current_user.id)**
11
+ 3. **Flask-RESTful resources without ownership validation**
12
+
13
+ ### Flask-Specific Patterns
14
+
15
+ **Direct Query (Vulnerable)**:
16
+ ```python
17
+ # VULNERABLE: No ownership check
18
+ @app.route('/api/invoices/<int:invoice_id>')
19
+ @login_required
20
+ def get_invoice(invoice_id):
21
+ invoice = Invoice.query.get_or_404(invoice_id)
22
+ return jsonify(invoice.to_dict()) # Any user can view any invoice
23
+
24
+ # SAFE: Scoped to user
25
+ @app.route('/api/invoices/<int:invoice_id>')
26
+ @login_required
27
+ def get_invoice(invoice_id):
28
+ invoice = Invoice.query.filter_by(
29
+ id=invoice_id, user_id=current_user.id
30
+ ).first_or_404()
31
+ return jsonify(invoice.to_dict())
32
+ ```
33
+
34
+ **db.session.get (Vulnerable)**:
35
+ ```python
36
+ # VULNERABLE: Direct primary key lookup
37
+ @app.route('/api/documents/<int:doc_id>', methods=['PUT'])
38
+ @login_required
39
+ def update_document(doc_id):
40
+ doc = db.session.get(Document, doc_id) # No ownership check!
41
+ doc.title = request.json['title']
42
+ db.session.commit()
43
+ ```
44
+
45
+ **Flask-RESTful (Vulnerable)**:
46
+ ```python
47
+ # VULNERABLE: Resource without ownership
48
+ class OrderResource(Resource):
49
+ @login_required
50
+ def get(self, order_id):
51
+ order = Order.query.get_or_404(order_id)
52
+ return marshal(order, order_fields) # Any user's order!
53
+
54
+ @login_required
55
+ def delete(self, order_id):
56
+ order = Order.query.get_or_404(order_id)
57
+ db.session.delete(order) # Can delete anyone's order!
58
+ db.session.commit()
59
+ ```
60
+
61
+ **Marshmallow Nested (Vulnerable)**:
62
+ ```python
63
+ # VULNERABLE: User can set owner in request body
64
+ class ProjectSchema(Schema):
65
+ id = fields.Int(dump_only=True)
66
+ name = fields.Str(required=True)
67
+ owner_id = fields.Int() # Writable! User can claim any owner
68
+ ```
69
+
70
+ ### Search Patterns
71
+
72
+ 1. `grep` for: `\\.get_or_404\\(`, `\\.get\\(`, `db\\.session\\.get\\(`
73
+ 2. `grep` for: `query\\.filter_by\\(id=` -- check for user scoping
74
+ 3. Check Flask-RESTful `Resource` classes for ownership checks
75
+ 4. Look for `request.args`, `request.form`, URL params flowing to queries
76
+
77
+ ### Severity Assessment
78
+
79
+ - **Critical**: Access to other users' sensitive data (PII, financial)
80
+ - **High**: Modification/deletion of other users' resources
81
+ - **Medium**: Read access to non-sensitive resources
82
+ - **Low**: Informational leaks with no impact
83
+ """
@@ -0,0 +1,77 @@
1
+ """
2
+ Flask injection vulnerabilities detection prompt.
3
+ """
4
+
5
+ FLASK_INJECTION_PROMPT = """## Injection Vulnerabilities in Flask
6
+
7
+ ### What to Look For
8
+
9
+ 1. **SQL injection via SQLAlchemy raw queries**
10
+ 2. **Jinja2 Server-Side Template Injection (SSTI)**
11
+ 3. **Command injection via subprocess/os**
12
+ 4. **eval/exec with request data**
13
+
14
+ ### Flask-Specific Patterns
15
+
16
+ **SQLAlchemy Injection (Vulnerable)**:
17
+ ```python
18
+ # VULNERABLE: text() with f-string
19
+ from sqlalchemy import text
20
+ result = db.session.execute(text(f"SELECT * FROM users WHERE name = '{name}'"))
21
+
22
+ # VULNERABLE: db.engine.execute with format string
23
+ db.engine.execute("SELECT * FROM users WHERE id = %s" % user_id)
24
+
25
+ # VULNERABLE: filter with string interpolation
26
+ User.query.filter(f"name = '{request.args['name']}'")
27
+
28
+ # SAFE: Parameterized
29
+ result = db.session.execute(text("SELECT * FROM users WHERE name = :name"), {"name": name})
30
+ ```
31
+
32
+ **Jinja2 SSTI (Vulnerable)**:
33
+ ```python
34
+ # VULNERABLE: render_template_string with user input
35
+ from flask import render_template_string
36
+ @app.route('/greet')
37
+ def greet():
38
+ name = request.args.get('name')
39
+ return render_template_string(f'Hello {{name}}!') # SSTI!
40
+ # Attack: ?name={{config.SECRET_KEY}} or {{''.__class__.__mro__[1].__subclasses__()}}
41
+
42
+ # SAFE: Use render_template with separate template file
43
+ return render_template('greet.html', name=name)
44
+ ```
45
+
46
+ **Command Injection (Vulnerable)**:
47
+ ```python
48
+ # VULNERABLE: shell=True with user input
49
+ import subprocess
50
+ subprocess.call(f"ping {request.form['host']}", shell=True)
51
+ os.system(f"nslookup {request.args['domain']}")
52
+
53
+ # SAFE: Argument list
54
+ subprocess.call(["ping", "-c", "1", request.form['host']])
55
+ ```
56
+
57
+ **Eval/Exec (Vulnerable)**:
58
+ ```python
59
+ # VULNERABLE: eval with request data
60
+ result = eval(request.form['expression'])
61
+ exec(request.json['code'])
62
+ ```
63
+
64
+ ### Search Patterns
65
+
66
+ 1. `grep` for: `db\\.session\\.execute`, `db\\.engine\\.execute`, `text\\(`
67
+ 2. `grep` for: `render_template_string` -- almost always dangerous
68
+ 3. `grep` for: `subprocess`, `os\\.system`, `os\\.popen`, `shell=True`
69
+ 4. `grep` for: `eval\\(`, `exec\\(`, `compile\\(`
70
+
71
+ ### Severity Assessment
72
+
73
+ - **Critical**: SQL injection allowing data extraction
74
+ - **Critical**: SSTI (leads to RCE via Jinja2 sandbox escape)
75
+ - **Critical**: Command injection
76
+ - **High**: eval/exec with partially controlled input
77
+ """
@@ -0,0 +1,73 @@
1
+ """
2
+ Flask security misconfiguration detection prompt.
3
+ """
4
+
5
+ FLASK_MISCONFIGURATION_PROMPT = """## Security Misconfiguration in Flask
6
+
7
+ ### What to Look For
8
+
9
+ 1. **app.secret_key hardcoded or weak**
10
+ 2. **DEBUG=True in production (Werkzeug debugger = RCE)**
11
+ 3. **Missing session cookie security flags**
12
+ 4. **Overly permissive CORS**
13
+
14
+ ### Flask-Specific Patterns
15
+
16
+ **Secret Key (Vulnerable)**:
17
+ ```python
18
+ # VULNERABLE: Hardcoded secret key
19
+ app.secret_key = 'super-secret-key-123'
20
+ app.config['SECRET_KEY'] = 'development'
21
+
22
+ # VULNERABLE: Predictable or short secret
23
+ app.secret_key = 'secret'
24
+
25
+ # VULNERABLE: Weak fallback default
26
+ app.secret_key = os.environ.get('SECRET_KEY', 'default-key')
27
+ ```
28
+
29
+ **Cookie Security (Vulnerable)**:
30
+ ```python
31
+ # VULNERABLE: Missing security flags
32
+ app.config['SESSION_COOKIE_SECURE'] = False # Sent over HTTP
33
+ app.config['SESSION_COOKIE_HTTPONLY'] = False # JS accessible
34
+ app.config['SESSION_COOKIE_SAMESITE'] = None # Cross-site allowed
35
+ app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=365) # 1 year sessions!
36
+ ```
37
+
38
+ **CORS Misconfiguration (Vulnerable)**:
39
+ ```python
40
+ # VULNERABLE: Allow all origins
41
+ from flask_cors import CORS
42
+ CORS(app) # Default allows all origins
43
+
44
+ # VULNERABLE: Wildcard with credentials
45
+ CORS(app, origins='*', supports_credentials=True)
46
+
47
+ # SAFE: Specific origins
48
+ CORS(app, origins=['https://app.example.com'], supports_credentials=True)
49
+ ```
50
+
51
+ **Host Header (Vulnerable)**:
52
+ ```python
53
+ # VULNERABLE: Running on 0.0.0.0 without SERVER_NAME
54
+ app.run(host='0.0.0.0', port=5000)
55
+ # No SERVER_NAME set -- accepts any Host header
56
+ ```
57
+
58
+ ### Search Patterns
59
+
60
+ 1. `grep` for: `secret_key`, `SECRET_KEY` in app config
61
+ 2. `grep` for: `debug=True`, `DEBUG = True`, `FLASK_DEBUG`
62
+ 3. `grep` for: `SESSION_COOKIE_SECURE`, `SESSION_COOKIE_HTTPONLY`
63
+ 4. `grep` for: `CORS\\(`, `flask_cors`
64
+ 5. `grep` for: `app\\.run\\(` -- check for debug and host params
65
+
66
+ ### Severity Assessment
67
+
68
+ - **Critical**: DEBUG=True on public host (Werkzeug debugger = RCE)
69
+ - **High**: Hardcoded or weak SECRET_KEY (session forgery, cookie tampering)
70
+ - **Medium**: Missing cookie security flags
71
+ - **Medium**: CORS allowing all origins with credentials
72
+ - **Low**: Missing HTTPS enforcement headers
73
+ """
@@ -0,0 +1,65 @@
1
+ """
2
+ Flask SSRF detection prompt.
3
+ """
4
+
5
+ FLASK_SSRF_PROMPT = """## SSRF (Server-Side Request Forgery) in Flask
6
+
7
+ ### What to Look For
8
+
9
+ 1. **User-controlled URLs passed to requests/urllib/httpx**
10
+ 2. **Webhook/callback URL injection**
11
+ 3. **URL fetching in import, preview, or proxy features**
12
+
13
+ ### Flask-Specific Patterns
14
+
15
+ **Requests Library (Vulnerable)**:
16
+ ```python
17
+ # VULNERABLE: User controls URL
18
+ @app.route('/api/preview')
19
+ def preview():
20
+ url = request.args.get('url')
21
+ response = requests.get(url) # SSRF!
22
+ return jsonify({"content": response.text[:500]})
23
+
24
+ # VULNERABLE: Webhook callback
25
+ @app.route('/api/webhooks', methods=['POST'])
26
+ @login_required
27
+ def create_webhook():
28
+ url = request.json['callback_url']
29
+ Webhook.create(url=url, user_id=current_user.id)
30
+ # Later: requests.post(webhook.url, json=event) -- hits internal services
31
+ ```
32
+
33
+ **urllib (Vulnerable)**:
34
+ ```python
35
+ # VULNERABLE: urlopen with user URL
36
+ from urllib.request import urlopen
37
+ @app.route('/api/import')
38
+ def import_data():
39
+ url = request.form['source']
40
+ data = urlopen(url).read() # file://, http://169.254.169.254, etc.
41
+ return process(data)
42
+ ```
43
+
44
+ **httpx / aiohttp (Vulnerable)**:
45
+ ```python
46
+ # VULNERABLE: async HTTP client with user URL
47
+ import httpx
48
+ async with httpx.AsyncClient() as client:
49
+ r = await client.get(request.json['url'])
50
+ ```
51
+
52
+ ### Search Patterns
53
+
54
+ 1. `grep` for: `requests\\.get\\(`, `requests\\.post\\(`, `requests\\.head\\(`
55
+ 2. `grep` for: `urlopen\\(`, `urllib\\.request`
56
+ 3. `grep` for: `httpx`, `aiohttp`
57
+ 4. Trace whether the URL argument originates from `request.args`, `request.form`, `request.json`
58
+
59
+ ### Severity Assessment
60
+
61
+ - **High**: SSRF reaching internal services or cloud metadata
62
+ - **High**: SSRF with response body returned to attacker
63
+ - **Medium**: Blind SSRF (request sent, no response returned)
64
+ - **Low**: SSRF limited to specific protocols/hosts by validation
65
+ """