@qball-inc/the-bulwark 1.0.0
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.
- package/.claude-plugin/plugin.json +43 -0
- package/agents/bulwark-fix-validator.md +633 -0
- package/agents/bulwark-implementer.md +391 -0
- package/agents/bulwark-issue-analyzer.md +308 -0
- package/agents/bulwark-standards-reviewer.md +221 -0
- package/agents/plan-creation-architect.md +323 -0
- package/agents/plan-creation-eng-lead.md +352 -0
- package/agents/plan-creation-po.md +300 -0
- package/agents/plan-creation-qa-critic.md +334 -0
- package/agents/product-ideation-competitive-analyzer.md +298 -0
- package/agents/product-ideation-idea-validator.md +268 -0
- package/agents/product-ideation-market-researcher.md +292 -0
- package/agents/product-ideation-pattern-documenter.md +308 -0
- package/agents/product-ideation-segment-analyzer.md +303 -0
- package/agents/product-ideation-strategist.md +259 -0
- package/agents/statusline-setup.md +97 -0
- package/hooks/hooks.json +59 -0
- package/package.json +45 -0
- package/scripts/hooks/cleanup-stale.sh +13 -0
- package/scripts/hooks/enforce-quality.sh +166 -0
- package/scripts/hooks/implementer-quality.sh +256 -0
- package/scripts/hooks/inject-protocol.sh +52 -0
- package/scripts/hooks/suggest-pipeline.sh +175 -0
- package/scripts/hooks/track-pipeline-start.sh +37 -0
- package/scripts/hooks/track-pipeline-stop.sh +52 -0
- package/scripts/init-rules.sh +35 -0
- package/scripts/init.sh +151 -0
- package/skills/anthropic-validator/SKILL.md +607 -0
- package/skills/anthropic-validator/references/agents-checklist.md +131 -0
- package/skills/anthropic-validator/references/commands-checklist.md +102 -0
- package/skills/anthropic-validator/references/hooks-checklist.md +151 -0
- package/skills/anthropic-validator/references/mcp-checklist.md +136 -0
- package/skills/anthropic-validator/references/plugins-checklist.md +148 -0
- package/skills/anthropic-validator/references/skills-checklist.md +85 -0
- package/skills/assertion-patterns/SKILL.md +296 -0
- package/skills/bug-magnet-data/SKILL.md +284 -0
- package/skills/bug-magnet-data/context/cli-args.md +91 -0
- package/skills/bug-magnet-data/context/db-query.md +104 -0
- package/skills/bug-magnet-data/context/file-contents.md +103 -0
- package/skills/bug-magnet-data/context/http-body.md +91 -0
- package/skills/bug-magnet-data/context/process-spawn.md +123 -0
- package/skills/bug-magnet-data/data/booleans/boundaries.yaml +143 -0
- package/skills/bug-magnet-data/data/collections/arrays.yaml +114 -0
- package/skills/bug-magnet-data/data/collections/objects.yaml +123 -0
- package/skills/bug-magnet-data/data/concurrency/race-conditions.yaml +118 -0
- package/skills/bug-magnet-data/data/concurrency/state-machines.yaml +115 -0
- package/skills/bug-magnet-data/data/dates/boundaries.yaml +137 -0
- package/skills/bug-magnet-data/data/dates/invalid.yaml +132 -0
- package/skills/bug-magnet-data/data/dates/timezone.yaml +118 -0
- package/skills/bug-magnet-data/data/encoding/charset.yaml +79 -0
- package/skills/bug-magnet-data/data/encoding/normalization.yaml +105 -0
- package/skills/bug-magnet-data/data/formats/email.yaml +154 -0
- package/skills/bug-magnet-data/data/formats/json.yaml +187 -0
- package/skills/bug-magnet-data/data/formats/url.yaml +165 -0
- package/skills/bug-magnet-data/data/language-specific/javascript.yaml +182 -0
- package/skills/bug-magnet-data/data/language-specific/python.yaml +174 -0
- package/skills/bug-magnet-data/data/language-specific/rust.yaml +148 -0
- package/skills/bug-magnet-data/data/numbers/boundaries.yaml +161 -0
- package/skills/bug-magnet-data/data/numbers/precision.yaml +89 -0
- package/skills/bug-magnet-data/data/numbers/special.yaml +69 -0
- package/skills/bug-magnet-data/data/strings/boundaries.yaml +109 -0
- package/skills/bug-magnet-data/data/strings/injection.yaml +208 -0
- package/skills/bug-magnet-data/data/strings/special-chars.yaml +190 -0
- package/skills/bug-magnet-data/data/strings/unicode.yaml +139 -0
- package/skills/bug-magnet-data/references/external-lists.md +115 -0
- package/skills/bulwark-brainstorm/SKILL.md +563 -0
- package/skills/bulwark-brainstorm/references/at-teammate-prompts.md +60 -0
- package/skills/bulwark-brainstorm/references/role-critical-analyst.md +78 -0
- package/skills/bulwark-brainstorm/references/role-development-lead.md +66 -0
- package/skills/bulwark-brainstorm/references/role-product-delivery-lead.md +79 -0
- package/skills/bulwark-brainstorm/references/role-product-manager.md +62 -0
- package/skills/bulwark-brainstorm/references/role-project-sme.md +59 -0
- package/skills/bulwark-brainstorm/references/role-technical-architect.md +66 -0
- package/skills/bulwark-research/SKILL.md +298 -0
- package/skills/bulwark-research/references/viewpoint-contrarian.md +63 -0
- package/skills/bulwark-research/references/viewpoint-direct-investigation.md +62 -0
- package/skills/bulwark-research/references/viewpoint-first-principles.md +65 -0
- package/skills/bulwark-research/references/viewpoint-practitioner.md +62 -0
- package/skills/bulwark-research/references/viewpoint-prior-art.md +66 -0
- package/skills/bulwark-scaffold/SKILL.md +330 -0
- package/skills/bulwark-statusline/SKILL.md +161 -0
- package/skills/bulwark-statusline/scripts/statusline.sh +144 -0
- package/skills/bulwark-verify/SKILL.md +519 -0
- package/skills/code-review/SKILL.md +428 -0
- package/skills/code-review/examples/anti-patterns/linting.ts +181 -0
- package/skills/code-review/examples/anti-patterns/security.ts +91 -0
- package/skills/code-review/examples/anti-patterns/standards.ts +195 -0
- package/skills/code-review/examples/anti-patterns/type-safety.ts +108 -0
- package/skills/code-review/examples/recommended/linting.ts +195 -0
- package/skills/code-review/examples/recommended/security.ts +154 -0
- package/skills/code-review/examples/recommended/standards.ts +231 -0
- package/skills/code-review/examples/recommended/type-safety.ts +181 -0
- package/skills/code-review/frameworks/angular.md +218 -0
- package/skills/code-review/frameworks/django.md +235 -0
- package/skills/code-review/frameworks/express.md +207 -0
- package/skills/code-review/frameworks/flask.md +298 -0
- package/skills/code-review/frameworks/generic.md +146 -0
- package/skills/code-review/frameworks/react.md +152 -0
- package/skills/code-review/frameworks/vue.md +244 -0
- package/skills/code-review/references/linting-patterns.md +221 -0
- package/skills/code-review/references/security-patterns.md +125 -0
- package/skills/code-review/references/standards-patterns.md +246 -0
- package/skills/code-review/references/type-safety-patterns.md +130 -0
- package/skills/component-patterns/SKILL.md +131 -0
- package/skills/component-patterns/references/pattern-cli-command.md +118 -0
- package/skills/component-patterns/references/pattern-database.md +166 -0
- package/skills/component-patterns/references/pattern-external-api.md +139 -0
- package/skills/component-patterns/references/pattern-file-parser.md +168 -0
- package/skills/component-patterns/references/pattern-http-server.md +162 -0
- package/skills/component-patterns/references/pattern-process-spawner.md +133 -0
- package/skills/continuous-feedback/SKILL.md +327 -0
- package/skills/continuous-feedback/references/collect-instructions.md +81 -0
- package/skills/continuous-feedback/references/specialize-code-review.md +82 -0
- package/skills/continuous-feedback/references/specialize-general.md +98 -0
- package/skills/continuous-feedback/references/specialize-test-audit.md +81 -0
- package/skills/create-skill/SKILL.md +359 -0
- package/skills/create-skill/references/agent-conventions.md +194 -0
- package/skills/create-skill/references/agent-template.md +195 -0
- package/skills/create-skill/references/content-guidance.md +291 -0
- package/skills/create-skill/references/decision-framework.md +124 -0
- package/skills/create-skill/references/template-pipeline.md +217 -0
- package/skills/create-skill/references/template-reference-heavy.md +111 -0
- package/skills/create-skill/references/template-research.md +210 -0
- package/skills/create-skill/references/template-script-driven.md +172 -0
- package/skills/create-skill/references/template-simple.md +80 -0
- package/skills/create-subagent/SKILL.md +353 -0
- package/skills/create-subagent/references/agent-conventions.md +268 -0
- package/skills/create-subagent/references/content-guidance.md +232 -0
- package/skills/create-subagent/references/decision-framework.md +134 -0
- package/skills/create-subagent/references/template-single-agent.md +192 -0
- package/skills/fix-bug/SKILL.md +241 -0
- package/skills/governance-protocol/SKILL.md +116 -0
- package/skills/init/SKILL.md +341 -0
- package/skills/issue-debugging/SKILL.md +385 -0
- package/skills/issue-debugging/references/anti-patterns.md +245 -0
- package/skills/issue-debugging/references/debug-report-schema.md +227 -0
- package/skills/mock-detection/SKILL.md +511 -0
- package/skills/mock-detection/references/false-positive-prevention.md +402 -0
- package/skills/mock-detection/references/stub-patterns.md +236 -0
- package/skills/pipeline-templates/SKILL.md +215 -0
- package/skills/pipeline-templates/references/code-change-workflow.md +277 -0
- package/skills/pipeline-templates/references/code-review.md +336 -0
- package/skills/pipeline-templates/references/fix-validation.md +421 -0
- package/skills/pipeline-templates/references/new-feature.md +335 -0
- package/skills/pipeline-templates/references/research-brainstorm.md +161 -0
- package/skills/pipeline-templates/references/research-planning.md +257 -0
- package/skills/pipeline-templates/references/test-audit.md +389 -0
- package/skills/pipeline-templates/references/test-execution-fix.md +238 -0
- package/skills/plan-creation/SKILL.md +497 -0
- package/skills/product-ideation/SKILL.md +372 -0
- package/skills/product-ideation/references/analysis-frameworks.md +161 -0
- package/skills/session-handoff/SKILL.md +139 -0
- package/skills/session-handoff/references/examples.md +223 -0
- package/skills/setup-lsp/SKILL.md +312 -0
- package/skills/setup-lsp/references/server-registry.md +85 -0
- package/skills/setup-lsp/references/troubleshooting.md +135 -0
- package/skills/subagent-output-templating/SKILL.md +415 -0
- package/skills/subagent-output-templating/references/examples.md +440 -0
- package/skills/subagent-prompting/SKILL.md +364 -0
- package/skills/subagent-prompting/references/examples.md +342 -0
- package/skills/test-audit/SKILL.md +531 -0
- package/skills/test-audit/references/known-limitations.md +41 -0
- package/skills/test-audit/references/priority-classification.md +30 -0
- package/skills/test-audit/references/prompts/deep-mode-detection.md +83 -0
- package/skills/test-audit/references/prompts/synthesis.md +57 -0
- package/skills/test-audit/references/rewrite-instructions.md +46 -0
- package/skills/test-audit/references/schemas/audit-output.yaml +100 -0
- package/skills/test-audit/references/schemas/diagnostic-output.yaml +49 -0
- package/skills/test-audit/scripts/data-flow-analyzer.ts +509 -0
- package/skills/test-audit/scripts/integration-mock-detector.ts +462 -0
- package/skills/test-audit/scripts/package.json +20 -0
- package/skills/test-audit/scripts/skip-detector.ts +211 -0
- package/skills/test-audit/scripts/verification-counter.ts +295 -0
- package/skills/test-classification/SKILL.md +310 -0
- package/skills/test-fixture-creation/SKILL.md +295 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# Flask Framework Patterns
|
|
2
|
+
|
|
3
|
+
Security and quality patterns specific to Flask applications.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Security Patterns
|
|
8
|
+
|
|
9
|
+
### SQL Injection
|
|
10
|
+
|
|
11
|
+
| Pattern | Risk | Detection |
|
|
12
|
+
|---------|------|-----------|
|
|
13
|
+
| String formatting in query | Critical | `f"SELECT...{user_input}"` |
|
|
14
|
+
| `text()` with concat | Critical | `text("SELECT..." + user_input)` |
|
|
15
|
+
| Raw cursor with % format | Critical | `cursor.execute(query % params)` |
|
|
16
|
+
|
|
17
|
+
**Safe Pattern:**
|
|
18
|
+
```python
|
|
19
|
+
# BAD
|
|
20
|
+
db.execute(f"SELECT * FROM users WHERE id = {user_id}")
|
|
21
|
+
|
|
22
|
+
# GOOD - SQLAlchemy ORM
|
|
23
|
+
User.query.filter_by(id=user_id).first()
|
|
24
|
+
|
|
25
|
+
# GOOD - Parameterized query
|
|
26
|
+
db.execute(text("SELECT * FROM users WHERE id = :id"), {"id": user_id})
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### XSS Prevention
|
|
30
|
+
|
|
31
|
+
| Pattern | Risk | Detection |
|
|
32
|
+
|---------|------|-----------|
|
|
33
|
+
| `|safe` filter | High | `{{ user_input|safe }}` |
|
|
34
|
+
| `Markup()` | High | `Markup(user_content)` |
|
|
35
|
+
| `render_template_string` | Critical | With user input |
|
|
36
|
+
|
|
37
|
+
**Safe Pattern:**
|
|
38
|
+
```html
|
|
39
|
+
<!-- BAD -->
|
|
40
|
+
{{ user_comment|safe }}
|
|
41
|
+
|
|
42
|
+
<!-- GOOD - Jinja2 auto-escapes by default -->
|
|
43
|
+
{{ user_comment }}
|
|
44
|
+
|
|
45
|
+
<!-- If HTML needed -->
|
|
46
|
+
{% import 'macros.html' as macros %}
|
|
47
|
+
{{ macros.sanitized_html(user_comment) }}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
# In macros.py
|
|
52
|
+
import bleach
|
|
53
|
+
|
|
54
|
+
def sanitize_html(html):
|
|
55
|
+
return Markup(bleach.clean(html, tags=['p', 'br', 'strong']))
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### CSRF Protection
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from flask_wtf.csrf import CSRFProtect
|
|
62
|
+
|
|
63
|
+
csrf = CSRFProtect()
|
|
64
|
+
csrf.init_app(app)
|
|
65
|
+
|
|
66
|
+
# In templates
|
|
67
|
+
<form method="post">
|
|
68
|
+
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
|
69
|
+
...
|
|
70
|
+
</form>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Session Security
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
# BAD
|
|
77
|
+
app.secret_key = 'dev'
|
|
78
|
+
|
|
79
|
+
# GOOD
|
|
80
|
+
import os
|
|
81
|
+
app.secret_key = os.environ['SECRET_KEY']
|
|
82
|
+
|
|
83
|
+
# Session configuration
|
|
84
|
+
app.config.update(
|
|
85
|
+
SESSION_COOKIE_SECURE=True,
|
|
86
|
+
SESSION_COOKIE_HTTPONLY=True,
|
|
87
|
+
SESSION_COOKIE_SAMESITE='Lax',
|
|
88
|
+
)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Authentication
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from flask_login import login_required, current_user
|
|
95
|
+
from functools import wraps
|
|
96
|
+
|
|
97
|
+
# BAD - No auth check
|
|
98
|
+
@app.route('/admin')
|
|
99
|
+
def admin_panel():
|
|
100
|
+
return render_template('admin.html')
|
|
101
|
+
|
|
102
|
+
# GOOD - Login required
|
|
103
|
+
@app.route('/admin')
|
|
104
|
+
@login_required
|
|
105
|
+
def admin_panel():
|
|
106
|
+
return render_template('admin.html')
|
|
107
|
+
|
|
108
|
+
# GOOD - Role check
|
|
109
|
+
def admin_required(f):
|
|
110
|
+
@wraps(f)
|
|
111
|
+
def decorated_function(*args, **kwargs):
|
|
112
|
+
if not current_user.is_admin:
|
|
113
|
+
abort(403)
|
|
114
|
+
return f(*args, **kwargs)
|
|
115
|
+
return decorated_function
|
|
116
|
+
|
|
117
|
+
@app.route('/admin')
|
|
118
|
+
@login_required
|
|
119
|
+
@admin_required
|
|
120
|
+
def admin_panel():
|
|
121
|
+
return render_template('admin.html')
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### File Upload
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from werkzeug.utils import secure_filename
|
|
128
|
+
|
|
129
|
+
# BAD
|
|
130
|
+
@app.route('/upload', methods=['POST'])
|
|
131
|
+
def upload():
|
|
132
|
+
file = request.files['file']
|
|
133
|
+
file.save(f'/uploads/{file.filename}') # Path traversal risk
|
|
134
|
+
|
|
135
|
+
# GOOD
|
|
136
|
+
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg'}
|
|
137
|
+
|
|
138
|
+
def allowed_file(filename):
|
|
139
|
+
return '.' in filename and \
|
|
140
|
+
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
|
141
|
+
|
|
142
|
+
@app.route('/upload', methods=['POST'])
|
|
143
|
+
def upload():
|
|
144
|
+
file = request.files['file']
|
|
145
|
+
if file and allowed_file(file.filename):
|
|
146
|
+
filename = secure_filename(file.filename)
|
|
147
|
+
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Type Safety Patterns
|
|
153
|
+
|
|
154
|
+
### Route Typing
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from flask import Flask, Request, Response
|
|
158
|
+
from typing import Union
|
|
159
|
+
|
|
160
|
+
# BAD
|
|
161
|
+
@app.route('/users/<user_id>')
|
|
162
|
+
def get_user(user_id):
|
|
163
|
+
return User.query.get(user_id)
|
|
164
|
+
|
|
165
|
+
# GOOD
|
|
166
|
+
@app.route('/users/<int:user_id>')
|
|
167
|
+
def get_user(user_id: int) -> Union[Response, tuple[dict, int]]:
|
|
168
|
+
user = User.query.get_or_404(user_id)
|
|
169
|
+
return jsonify(user.to_dict())
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Request Data Typing
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from pydantic import BaseModel, ValidationError
|
|
176
|
+
from typing import Optional
|
|
177
|
+
|
|
178
|
+
class UserCreate(BaseModel):
|
|
179
|
+
name: str
|
|
180
|
+
email: str
|
|
181
|
+
age: Optional[int] = None
|
|
182
|
+
|
|
183
|
+
@app.route('/users', methods=['POST'])
|
|
184
|
+
def create_user() -> tuple[dict, int]:
|
|
185
|
+
try:
|
|
186
|
+
data = UserCreate(**request.json)
|
|
187
|
+
except ValidationError as e:
|
|
188
|
+
return {'error': e.errors()}, 400
|
|
189
|
+
|
|
190
|
+
user = User(name=data.name, email=data.email, age=data.age)
|
|
191
|
+
db.session.add(user)
|
|
192
|
+
db.session.commit()
|
|
193
|
+
return {'id': user.id}, 201
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Model Typing
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
from sqlalchemy.orm import Mapped, mapped_column
|
|
200
|
+
from typing import Optional
|
|
201
|
+
|
|
202
|
+
class User(db.Model):
|
|
203
|
+
id: Mapped[int] = mapped_column(primary_key=True)
|
|
204
|
+
name: Mapped[str] = mapped_column(String(100))
|
|
205
|
+
email: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
|
206
|
+
|
|
207
|
+
def to_dict(self) -> dict:
|
|
208
|
+
return {
|
|
209
|
+
'id': self.id,
|
|
210
|
+
'name': self.name,
|
|
211
|
+
'email': self.email,
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Linting Patterns
|
|
218
|
+
|
|
219
|
+
### Application Factory
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
# BAD - Global app
|
|
223
|
+
app = Flask(__name__)
|
|
224
|
+
db = SQLAlchemy(app)
|
|
225
|
+
|
|
226
|
+
# GOOD - Application factory
|
|
227
|
+
def create_app(config_class=Config):
|
|
228
|
+
app = Flask(__name__)
|
|
229
|
+
app.config.from_object(config_class)
|
|
230
|
+
|
|
231
|
+
db.init_app(app)
|
|
232
|
+
|
|
233
|
+
from app.routes import main
|
|
234
|
+
app.register_blueprint(main)
|
|
235
|
+
|
|
236
|
+
return app
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Blueprint Organization
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
# routes/users.py
|
|
243
|
+
from flask import Blueprint
|
|
244
|
+
|
|
245
|
+
users_bp = Blueprint('users', __name__, url_prefix='/users')
|
|
246
|
+
|
|
247
|
+
@users_bp.route('/')
|
|
248
|
+
def list_users():
|
|
249
|
+
...
|
|
250
|
+
|
|
251
|
+
@users_bp.route('/<int:user_id>')
|
|
252
|
+
def get_user(user_id: int):
|
|
253
|
+
...
|
|
254
|
+
|
|
255
|
+
# app/__init__.py
|
|
256
|
+
from routes.users import users_bp
|
|
257
|
+
app.register_blueprint(users_bp)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Coding Standards
|
|
263
|
+
|
|
264
|
+
### Naming Conventions
|
|
265
|
+
|
|
266
|
+
| Element | Convention | Example |
|
|
267
|
+
|---------|------------|---------|
|
|
268
|
+
| Blueprint | snake_case | `users_bp` |
|
|
269
|
+
| Route function | snake_case | `get_user` |
|
|
270
|
+
| Model | PascalCase | `UserProfile` |
|
|
271
|
+
| Config class | PascalCase | `ProductionConfig` |
|
|
272
|
+
|
|
273
|
+
### File Organization
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
app/
|
|
277
|
+
__init__.py
|
|
278
|
+
models/
|
|
279
|
+
user.py
|
|
280
|
+
routes/
|
|
281
|
+
users.py
|
|
282
|
+
auth.py
|
|
283
|
+
services/
|
|
284
|
+
user_service.py
|
|
285
|
+
templates/
|
|
286
|
+
static/
|
|
287
|
+
config.py
|
|
288
|
+
run.py
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## What to Skip
|
|
294
|
+
|
|
295
|
+
- Flask-Admin configuration
|
|
296
|
+
- Development server settings
|
|
297
|
+
- CLI commands
|
|
298
|
+
- Test fixtures with test client
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Generic Framework Patterns
|
|
2
|
+
|
|
3
|
+
Security and quality patterns applicable to any codebase when no specific framework is detected.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Security Patterns (OWASP Top 10)
|
|
8
|
+
|
|
9
|
+
### A01: Broken Access Control
|
|
10
|
+
|
|
11
|
+
| Pattern | Detection | Severity |
|
|
12
|
+
|---------|-----------|----------|
|
|
13
|
+
| Missing authorization | Resource access without permission check | Critical |
|
|
14
|
+
| IDOR | User ID from input used directly | Critical |
|
|
15
|
+
| Path traversal | User input in file paths | Critical |
|
|
16
|
+
|
|
17
|
+
**Check:**
|
|
18
|
+
- Every database query has a preceding authorization check
|
|
19
|
+
- User-supplied IDs are validated against session user
|
|
20
|
+
- File paths are restricted to allowed directories
|
|
21
|
+
|
|
22
|
+
### A02: Cryptographic Failures
|
|
23
|
+
|
|
24
|
+
| Pattern | Detection | Severity |
|
|
25
|
+
|---------|-----------|----------|
|
|
26
|
+
| Hardcoded secrets | Strings matching key/password patterns | Critical |
|
|
27
|
+
| Weak algorithms | MD5, SHA1 for passwords | Critical |
|
|
28
|
+
| Missing encryption | Sensitive data in plaintext | Critical |
|
|
29
|
+
|
|
30
|
+
**Check:**
|
|
31
|
+
- No API keys, passwords, or tokens in source
|
|
32
|
+
- Password hashing uses bcrypt, argon2, or scrypt
|
|
33
|
+
- Sensitive data encrypted at rest and in transit
|
|
34
|
+
|
|
35
|
+
### A03: Injection
|
|
36
|
+
|
|
37
|
+
| Pattern | Detection | Severity |
|
|
38
|
+
|---------|-----------|----------|
|
|
39
|
+
| SQL injection | String concatenation in queries | Critical |
|
|
40
|
+
| Command injection | User input in shell commands | Critical |
|
|
41
|
+
| XSS | User input in HTML output | Critical |
|
|
42
|
+
|
|
43
|
+
**Check:**
|
|
44
|
+
- All queries use parameterization
|
|
45
|
+
- Shell commands use array form or escape input
|
|
46
|
+
- Output is escaped for context (HTML, JS, URL)
|
|
47
|
+
|
|
48
|
+
### A04: Insecure Design
|
|
49
|
+
|
|
50
|
+
| Pattern | Detection | Severity |
|
|
51
|
+
|---------|-----------|----------|
|
|
52
|
+
| No rate limiting | Auth endpoints unrestricted | Important |
|
|
53
|
+
| Weak tokens | Predictable patterns | Critical |
|
|
54
|
+
| Missing business logic validation | Edge cases not handled | Important |
|
|
55
|
+
|
|
56
|
+
### A05: Security Misconfiguration
|
|
57
|
+
|
|
58
|
+
| Pattern | Detection | Severity |
|
|
59
|
+
|---------|-----------|----------|
|
|
60
|
+
| Debug mode | Verbose errors, stack traces | Important |
|
|
61
|
+
| Default credentials | admin/admin patterns | Critical |
|
|
62
|
+
| Unnecessary features | Unused endpoints exposed | Suggestion |
|
|
63
|
+
|
|
64
|
+
### A06: Vulnerable Components
|
|
65
|
+
|
|
66
|
+
**Note:** Defer to package audit tools:
|
|
67
|
+
- `npm audit` / `yarn audit`
|
|
68
|
+
- `pip-audit`
|
|
69
|
+
- `cargo audit`
|
|
70
|
+
|
|
71
|
+
### A07: Auth Failures
|
|
72
|
+
|
|
73
|
+
| Pattern | Detection | Severity |
|
|
74
|
+
|---------|-----------|----------|
|
|
75
|
+
| Session fixation | No regeneration after login | Critical |
|
|
76
|
+
| Weak passwords | No complexity requirements | Important |
|
|
77
|
+
| Credential exposure | Logging passwords | Critical |
|
|
78
|
+
|
|
79
|
+
### A08: Data Integrity
|
|
80
|
+
|
|
81
|
+
| Pattern | Detection | Severity |
|
|
82
|
+
|---------|-----------|----------|
|
|
83
|
+
| Insecure deserialization | Deserializing untrusted data | Critical |
|
|
84
|
+
| Missing integrity checks | Data modification undetected | Important |
|
|
85
|
+
|
|
86
|
+
### A09: Logging Failures
|
|
87
|
+
|
|
88
|
+
| Pattern | Detection | Severity |
|
|
89
|
+
|---------|-----------|----------|
|
|
90
|
+
| Missing audit logs | No security event logging | Important |
|
|
91
|
+
| Sensitive data logged | Passwords, tokens in logs | Critical |
|
|
92
|
+
| Log injection | Unsanitized input in logs | Important |
|
|
93
|
+
|
|
94
|
+
### A10: SSRF
|
|
95
|
+
|
|
96
|
+
| Pattern | Detection | Severity |
|
|
97
|
+
|---------|-----------|----------|
|
|
98
|
+
| Unvalidated URL fetch | User URL without allowlist | Critical |
|
|
99
|
+
| Internal access | Requests to internal services | Critical |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Type Safety Patterns
|
|
104
|
+
|
|
105
|
+
| Pattern | Issue | Fix |
|
|
106
|
+
|---------|-------|-----|
|
|
107
|
+
| `any` type | Bypasses type checking | Define proper interface |
|
|
108
|
+
| Missing null checks | Runtime null errors | Use optional chaining |
|
|
109
|
+
| Unsafe assertions | Type lies to compiler | Use type guards |
|
|
110
|
+
| Implicit any | Missing type annotations | Enable strict mode |
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Linting Patterns
|
|
115
|
+
|
|
116
|
+
| Pattern | Threshold | Action |
|
|
117
|
+
|---------|-----------|--------|
|
|
118
|
+
| Cyclomatic complexity | >15 | Refactor |
|
|
119
|
+
| Nesting depth | >4 | Use early returns |
|
|
120
|
+
| Function length | >50 lines | Split function |
|
|
121
|
+
| Magic numbers | Any | Use named constants |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Coding Standards
|
|
126
|
+
|
|
127
|
+
### CS1: Single Responsibility
|
|
128
|
+
Each function should have one purpose.
|
|
129
|
+
|
|
130
|
+
### CS2: No Magic
|
|
131
|
+
All values and behaviors should be explicit.
|
|
132
|
+
|
|
133
|
+
### CS3: Fail Fast
|
|
134
|
+
Validate inputs early, throw on errors.
|
|
135
|
+
|
|
136
|
+
### CS4: Clean Code
|
|
137
|
+
No unused code, no commented blocks.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## What to Skip
|
|
142
|
+
|
|
143
|
+
- Test fixtures with intentional issues
|
|
144
|
+
- Documentation examples
|
|
145
|
+
- Generated code
|
|
146
|
+
- Third-party integrations following external patterns
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# React Framework Patterns
|
|
2
|
+
|
|
3
|
+
Security and quality patterns specific to React applications.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Security Patterns
|
|
8
|
+
|
|
9
|
+
### XSS Prevention
|
|
10
|
+
|
|
11
|
+
| Pattern | Risk | Detection |
|
|
12
|
+
|---------|------|-----------|
|
|
13
|
+
| `dangerouslySetInnerHTML` | High | Direct use without sanitization |
|
|
14
|
+
| String interpolation in JSX | Medium | `{userInput}` in href, src attributes |
|
|
15
|
+
| `eval()` with props/state | Critical | Dynamic code execution |
|
|
16
|
+
|
|
17
|
+
**Safe Pattern:**
|
|
18
|
+
```tsx
|
|
19
|
+
// BAD
|
|
20
|
+
<div dangerouslySetInnerHTML={{ __html: userComment }} />
|
|
21
|
+
|
|
22
|
+
// GOOD
|
|
23
|
+
import DOMPurify from 'dompurify';
|
|
24
|
+
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userComment) }} />
|
|
25
|
+
|
|
26
|
+
// BETTER
|
|
27
|
+
<div>{userComment}</div> // React escapes by default
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### URL Injection
|
|
31
|
+
|
|
32
|
+
| Pattern | Risk | Detection |
|
|
33
|
+
|---------|------|-----------|
|
|
34
|
+
| `javascript:` in href | Critical | User input in anchor href |
|
|
35
|
+
| User-controlled `src` | High | Dynamic image/iframe sources |
|
|
36
|
+
|
|
37
|
+
**Safe Pattern:**
|
|
38
|
+
```tsx
|
|
39
|
+
// BAD
|
|
40
|
+
<a href={userProvidedUrl}>Link</a>
|
|
41
|
+
|
|
42
|
+
// GOOD
|
|
43
|
+
const sanitizeUrl = (url: string) => {
|
|
44
|
+
const parsed = new URL(url);
|
|
45
|
+
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
|
46
|
+
throw new Error('Invalid URL protocol');
|
|
47
|
+
}
|
|
48
|
+
return url;
|
|
49
|
+
};
|
|
50
|
+
<a href={sanitizeUrl(userProvidedUrl)}>Link</a>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### State Exposure
|
|
54
|
+
|
|
55
|
+
| Pattern | Risk | Detection |
|
|
56
|
+
|---------|------|-----------|
|
|
57
|
+
| Secrets in state | Critical | API keys, tokens in useState/Redux |
|
|
58
|
+
| PII in localStorage | High | User data persisted client-side |
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Type Safety Patterns
|
|
63
|
+
|
|
64
|
+
### Props Typing
|
|
65
|
+
|
|
66
|
+
| Pattern | Issue | Fix |
|
|
67
|
+
|---------|-------|-----|
|
|
68
|
+
| `props: any` | Bypasses type checking | Define interface |
|
|
69
|
+
| Missing children type | Unclear component API | Use `React.ReactNode` |
|
|
70
|
+
| Event handler `any` | Loses event type | Use specific event type |
|
|
71
|
+
|
|
72
|
+
**Example:**
|
|
73
|
+
```tsx
|
|
74
|
+
// BAD
|
|
75
|
+
function Button(props: any) {
|
|
76
|
+
return <button onClick={props.onClick}>{props.children}</button>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// GOOD
|
|
80
|
+
interface ButtonProps {
|
|
81
|
+
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
82
|
+
children: React.ReactNode;
|
|
83
|
+
disabled?: boolean;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function Button({ onClick, children, disabled }: ButtonProps) {
|
|
87
|
+
return <button onClick={onClick} disabled={disabled}>{children}</button>;
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Ref Typing
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
// BAD
|
|
95
|
+
const inputRef = useRef(null); // RefObject<null>
|
|
96
|
+
|
|
97
|
+
// GOOD
|
|
98
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Linting Patterns
|
|
104
|
+
|
|
105
|
+
### Component Complexity
|
|
106
|
+
|
|
107
|
+
| Metric | Threshold | Action |
|
|
108
|
+
|--------|-----------|--------|
|
|
109
|
+
| Lines per component | >150 | Split into sub-components |
|
|
110
|
+
| Props count | >7 | Consider composition or context |
|
|
111
|
+
| useEffect dependencies | >4 | Extract custom hook |
|
|
112
|
+
|
|
113
|
+
### Hook Rules
|
|
114
|
+
|
|
115
|
+
| Violation | Detection |
|
|
116
|
+
|-----------|-----------|
|
|
117
|
+
| Conditional hooks | `if (condition) { useEffect(...) }` |
|
|
118
|
+
| Loop hooks | `items.map(() => useState(...))` |
|
|
119
|
+
| Nested hooks | Hook called inside callback |
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Coding Standards
|
|
124
|
+
|
|
125
|
+
### Naming Conventions
|
|
126
|
+
|
|
127
|
+
| Element | Convention | Example |
|
|
128
|
+
|---------|------------|---------|
|
|
129
|
+
| Component | PascalCase | `UserProfile` |
|
|
130
|
+
| Hook | camelCase with `use` prefix | `useUserProfile` |
|
|
131
|
+
| Handler | `handle` prefix | `handleSubmit` |
|
|
132
|
+
| Boolean prop | `is`, `has`, `should` prefix | `isLoading` |
|
|
133
|
+
|
|
134
|
+
### File Organization
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
components/
|
|
138
|
+
Button/
|
|
139
|
+
Button.tsx # Component
|
|
140
|
+
Button.test.tsx # Tests
|
|
141
|
+
Button.module.css # Styles
|
|
142
|
+
index.ts # Re-export
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## What to Skip
|
|
148
|
+
|
|
149
|
+
- Third-party component library patterns
|
|
150
|
+
- React DevTools annotations
|
|
151
|
+
- Storybook-specific code
|
|
152
|
+
- Test utilities using `any` for mock flexibility
|