claude-code-kit 0.7.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 (209) hide show
  1. claude_code_kit-0.7.0.dist-info/METADATA +384 -0
  2. claude_code_kit-0.7.0.dist-info/RECORD +209 -0
  3. claude_code_kit-0.7.0.dist-info/WHEEL +4 -0
  4. claude_code_kit-0.7.0.dist-info/entry_points.txt +4 -0
  5. claude_code_kit-0.7.0.dist-info/licenses/LICENSE +21 -0
  6. claude_kit/__init__.py +10 -0
  7. claude_kit/__main__.py +8 -0
  8. claude_kit/_payload/agents/acceptance-reviewer.md +60 -0
  9. claude_kit/_payload/agents/auditor.md +76 -0
  10. claude_kit/_payload/agents/dependency-scanner.md +84 -0
  11. claude_kit/_payload/agents/developer.md +187 -0
  12. claude_kit/_payload/agents/devils-advocate.md +62 -0
  13. claude_kit/_payload/agents/devops-engineer.md +134 -0
  14. claude_kit/_payload/agents/e2e-tester.md +152 -0
  15. claude_kit/_payload/agents/em-reviewer.md +105 -0
  16. claude_kit/_payload/agents/incident-responder.md +64 -0
  17. claude_kit/_payload/agents/merge-reviewer.md +194 -0
  18. claude_kit/_payload/agents/observability-engineer.md +94 -0
  19. claude_kit/_payload/agents/orchestrator.md +551 -0
  20. claude_kit/_payload/agents/owasp-reviewer.md +76 -0
  21. claude_kit/_payload/agents/policy-validator.md +63 -0
  22. claude_kit/_payload/agents/pr-raiser.md +138 -0
  23. claude_kit/_payload/agents/risk-classifier.md +50 -0
  24. claude_kit/_payload/agents/sdlc-code-reviewer.md +196 -0
  25. claude_kit/_payload/agents/secret-scanner.md +70 -0
  26. claude_kit/_payload/agents/security-reviewer.md +80 -0
  27. claude_kit/_payload/agents/senior-backend-dev.md +199 -0
  28. claude_kit/_payload/agents/senior-frontend-dev.md +181 -0
  29. claude_kit/_payload/agents/senior-tester.md +206 -0
  30. claude_kit/_payload/agents/spec-doc-writer.md +331 -0
  31. claude_kit/_payload/agents/story-planner.md +56 -0
  32. claude_kit/_payload/agents/technical-architect.md +139 -0
  33. claude_kit/_payload/agents/tester.md +193 -0
  34. claude_kit/_payload/agents/ui-designer.md +73 -0
  35. claude_kit/_payload/agents/unit-tester.md +119 -0
  36. claude_kit/_payload/catalog/mcp.yaml +54 -0
  37. claude_kit/_payload/catalog/org.yaml +145 -0
  38. claude_kit/_payload/catalog/profiles.yaml +96 -0
  39. claude_kit/_payload/catalog/stacks.yaml +96 -0
  40. claude_kit/_payload/commands/init.md +36 -0
  41. claude_kit/_payload/commands/sdlc.md +18 -0
  42. claude_kit/_payload/commands/status.md +20 -0
  43. claude_kit/_payload/hooks/hooks.json +58 -0
  44. claude_kit/_payload/hooks/scripts/audit-log.sh +18 -0
  45. claude_kit/_payload/hooks/scripts/guard-secrets.sh +26 -0
  46. claude_kit/_payload/hooks/scripts/lint-fix.sh +38 -0
  47. claude_kit/_payload/hooks/scripts/load-continuity.sh +32 -0
  48. claude_kit/_payload/hooks/scripts/load-learnings.sh +40 -0
  49. claude_kit/_payload/hooks/scripts/type-check.sh +23 -0
  50. claude_kit/_payload/hooks/scripts/validate-frontmatter.sh +34 -0
  51. claude_kit/_payload/hooks/scripts/validate-settings.sh +21 -0
  52. claude_kit/_payload/hooks/scripts/warn-large-edits.sh +24 -0
  53. claude_kit/_payload/hooks/scripts/warn-missing-tests.sh +24 -0
  54. claude_kit/_payload/hooks/scripts/warn-sensitive-files.sh +30 -0
  55. claude_kit/_payload/hooks/scripts/warn-shared-modules.sh +33 -0
  56. claude_kit/_payload/rules/agent-guardrails.md +83 -0
  57. claude_kit/_payload/rules/agent-memory.md +106 -0
  58. claude_kit/_payload/rules/agent-resilience.md +61 -0
  59. claude_kit/_payload/rules/autonomy-levels.md +30 -0
  60. claude_kit/_payload/rules/code-organization.md +312 -0
  61. claude_kit/_payload/rules/continuity.md +84 -0
  62. claude_kit/_payload/rules/design-patterns.md +422 -0
  63. claude_kit/_payload/rules/devops-observability.md +57 -0
  64. claude_kit/_payload/rules/documentation.md +326 -0
  65. claude_kit/_payload/rules/evals.md +62 -0
  66. claude_kit/_payload/rules/frontend-best-practices.md +157 -0
  67. claude_kit/_payload/rules/goal-setting-and-monitoring.md +72 -0
  68. claude_kit/_payload/rules/human-in-the-loop.md +64 -0
  69. claude_kit/_payload/rules/linting-and-formatting.md +220 -0
  70. claude_kit/_payload/rules/mandatory-workflow.md +309 -0
  71. claude_kit/_payload/rules/model-tiers.md +34 -0
  72. claude_kit/_payload/rules/quality-gates.md +107 -0
  73. claude_kit/_payload/rules/rarv-cycle.md +31 -0
  74. claude_kit/_payload/rules/reasoning-techniques.md +62 -0
  75. claude_kit/_payload/rules/responsive-and-accessibility.md +353 -0
  76. claude_kit/_payload/rules/risk-classification.md +36 -0
  77. claude_kit/_payload/rules/testing.md +417 -0
  78. claude_kit/_payload/rules/tool-design.md +66 -0
  79. claude_kit/_payload/skills/_references/accessibility-checklist.md +160 -0
  80. claude_kit/_payload/skills/_references/orchestration-patterns.md +405 -0
  81. claude_kit/_payload/skills/_references/performance-checklist.md +153 -0
  82. claude_kit/_payload/skills/_references/security-checklist.md +134 -0
  83. claude_kit/_payload/skills/_references/testing-patterns.md +236 -0
  84. claude_kit/_payload/skills/accessibility-review/SKILL.md +56 -0
  85. claude_kit/_payload/skills/api-and-interface-design/SKILL.md +294 -0
  86. claude_kit/_payload/skills/api-integration/SKILL.md +348 -0
  87. claude_kit/_payload/skills/archive-sprint/SKILL.md +31 -0
  88. claude_kit/_payload/skills/backlog/SKILL.md +41 -0
  89. claude_kit/_payload/skills/backlog/item-template.md +20 -0
  90. claude_kit/_payload/skills/browser-testing-with-devtools/SKILL.md +302 -0
  91. claude_kit/_payload/skills/ci-cd-and-automation/SKILL.md +402 -0
  92. claude_kit/_payload/skills/code-review-and-quality/SKILL.md +347 -0
  93. claude_kit/_payload/skills/code-simplification/SKILL.md +331 -0
  94. claude_kit/_payload/skills/component-design/SKILL.md +171 -0
  95. claude_kit/_payload/skills/consolidate-learnings/SKILL.md +55 -0
  96. claude_kit/_payload/skills/context-engineering/SKILL.md +321 -0
  97. claude_kit/_payload/skills/debugging-and-error-recovery/SKILL.md +300 -0
  98. claude_kit/_payload/skills/decision/SKILL.md +46 -0
  99. claude_kit/_payload/skills/decision/adr-template.md +36 -0
  100. claude_kit/_payload/skills/deprecation-and-migration/SKILL.md +207 -0
  101. claude_kit/_payload/skills/documentation-and-adrs/SKILL.md +299 -0
  102. claude_kit/_payload/skills/doubt-driven-development/SKILL.md +243 -0
  103. claude_kit/_payload/skills/execute/SKILL.md +27 -0
  104. claude_kit/_payload/skills/frontend-ui-engineering/SKILL.md +328 -0
  105. claude_kit/_payload/skills/git-workflow-and-versioning/SKILL.md +300 -0
  106. claude_kit/_payload/skills/idea-refine/SKILL.md +178 -0
  107. claude_kit/_payload/skills/idea-refine/examples.md +238 -0
  108. claude_kit/_payload/skills/idea-refine/frameworks.md +99 -0
  109. claude_kit/_payload/skills/idea-refine/refinement-criteria.md +113 -0
  110. claude_kit/_payload/skills/idea-refine/scripts/idea-refine.sh +15 -0
  111. claude_kit/_payload/skills/incident-postmortem/SKILL.md +74 -0
  112. claude_kit/_payload/skills/incremental-implementation/SKILL.md +245 -0
  113. claude_kit/_payload/skills/interview-me/SKILL.md +221 -0
  114. claude_kit/_payload/skills/load-testing/SKILL.md +83 -0
  115. claude_kit/_payload/skills/manual-test/SKILL.md +516 -0
  116. claude_kit/_payload/skills/performance-optimization/SKILL.md +277 -0
  117. claude_kit/_payload/skills/planning-and-task-breakdown/SKILL.md +223 -0
  118. claude_kit/_payload/skills/playwright-verification/SKILL.md +205 -0
  119. claude_kit/_payload/skills/refresh-docs/SKILL.md +63 -0
  120. claude_kit/_payload/skills/remember/SKILL.md +96 -0
  121. claude_kit/_payload/skills/scope/SKILL.md +52 -0
  122. claude_kit/_payload/skills/scope/scope-template.md +82 -0
  123. claude_kit/_payload/skills/sdlc/SKILL.md +83 -0
  124. claude_kit/_payload/skills/security-and-hardening/SKILL.md +368 -0
  125. claude_kit/_payload/skills/security-verification/SKILL.md +209 -0
  126. claude_kit/_payload/skills/shipping-and-launch/SKILL.md +309 -0
  127. claude_kit/_payload/skills/smoke-test/SKILL.md +78 -0
  128. claude_kit/_payload/skills/source-driven-development/SKILL.md +195 -0
  129. claude_kit/_payload/skills/spec-driven-development/SKILL.md +200 -0
  130. claude_kit/_payload/skills/sprint/SKILL.md +67 -0
  131. claude_kit/_payload/skills/sprint/sprint-template.md +90 -0
  132. claude_kit/_payload/skills/test-driven-development/SKILL.md +383 -0
  133. claude_kit/_payload/skills/threat-model/SKILL.md +60 -0
  134. claude_kit/_payload/skills/triage/SKILL.md +87 -0
  135. claude_kit/_payload/skills/ui-ux-design/SKILL.md +71 -0
  136. claude_kit/_payload/skills/unit-test/SKILL.md +237 -0
  137. claude_kit/_payload/skills/using-agent-skills/SKILL.md +180 -0
  138. claude_kit/_payload/templates/CLAUDE.md +238 -0
  139. claude_kit/_payload/templates/CLAUDE.stack.md.tmpl +53 -0
  140. claude_kit/_payload/templates/CONTINUITY.template.md +35 -0
  141. claude_kit/_payload/templates/README.claude-sdlc.md.tmpl +219 -0
  142. claude_kit/_payload/templates/agent-memory/MEMORY.md +30 -0
  143. claude_kit/_payload/templates/agent-memory/api/.gitkeep +0 -0
  144. claude_kit/_payload/templates/agent-memory/architecture/.gitkeep +0 -0
  145. claude_kit/_payload/templates/agent-memory/debugging/.gitkeep +0 -0
  146. claude_kit/_payload/templates/agent-memory/gotchas/.gitkeep +0 -0
  147. claude_kit/_payload/templates/agent-memory/patterns/.gitkeep +0 -0
  148. claude_kit/_payload/templates/agent-memory/performance/.gitkeep +0 -0
  149. claude_kit/_payload/templates/artifacts/adr.md +18 -0
  150. claude_kit/_payload/templates/artifacts/feature-spec.md +29 -0
  151. claude_kit/_payload/templates/artifacts/release-plan.md +23 -0
  152. claude_kit/_payload/templates/artifacts/runbook.md +24 -0
  153. claude_kit/_payload/templates/artifacts/security-review.md +23 -0
  154. claude_kit/_payload/templates/artifacts/test-plan.md +22 -0
  155. claude_kit/_payload/templates/org/README.md +53 -0
  156. claude_kit/_payload/templates/org/agents/data-workflow-agent.md +59 -0
  157. claude_kit/_payload/templates/org/agents/founder-prototype-agent.md +61 -0
  158. claude_kit/_payload/templates/org/agents/internal-tools-builder.md +63 -0
  159. claude_kit/_payload/templates/org/agents/pm-copilot.md +60 -0
  160. claude_kit/_payload/templates/org/agents/support-ticket-engineer.md +63 -0
  161. claude_kit/_payload/templates/org/packs/devops-and-release/README.md +46 -0
  162. claude_kit/_payload/templates/org/packs/devops-and-release/pack.yaml +32 -0
  163. claude_kit/_payload/templates/org/packs/engineering-core/README.md +46 -0
  164. claude_kit/_payload/templates/org/packs/engineering-core/pack.yaml +44 -0
  165. claude_kit/_payload/templates/org/packs/non-engineer-builder/README.md +53 -0
  166. claude_kit/_payload/templates/org/packs/non-engineer-builder/pack.yaml +39 -0
  167. claude_kit/_payload/templates/org/packs/onboarding-and-docs/README.md +49 -0
  168. claude_kit/_payload/templates/org/packs/onboarding-and-docs/pack.yaml +26 -0
  169. claude_kit/_payload/templates/org/packs/product-to-code/README.md +50 -0
  170. claude_kit/_payload/templates/org/packs/product-to-code/pack.yaml +34 -0
  171. claude_kit/_payload/templates/org/packs/quality-and-review/README.md +53 -0
  172. claude_kit/_payload/templates/org/packs/quality-and-review/pack.yaml +40 -0
  173. claude_kit/_payload/templates/org/packs/security-and-compliance/README.md +50 -0
  174. claude_kit/_payload/templates/org/packs/security-and-compliance/pack.yaml +36 -0
  175. claude_kit/_payload/templates/org/rules/ai-working-agreement.md +45 -0
  176. claude_kit/_payload/templates/org/rules/ambiguity-resolution.md +36 -0
  177. claude_kit/_payload/templates/org/rules/branch-and-pr-policy.md +41 -0
  178. claude_kit/_payload/templates/org/rules/compliance-policy.md +50 -0
  179. claude_kit/_payload/templates/org/rules/non-engineer-safe-coding.md +37 -0
  180. claude_kit/_payload/templates/org/rules/pii-policy.md +46 -0
  181. claude_kit/_payload/templates/org/rules/production-data-policy.md +35 -0
  182. claude_kit/_payload/templates/org/rules/prompt-to-task-conversion.md +30 -0
  183. claude_kit/_payload/templates/org/rules/prototype-boundaries.md +40 -0
  184. claude_kit/_payload/templates/org/rules/secrets-policy.md +34 -0
  185. claude_kit/_payload/templates/org/skills/customer-issue-to-fix/SKILL.md +61 -0
  186. claude_kit/_payload/templates/org/skills/feature-from-idea/SKILL.md +56 -0
  187. claude_kit/_payload/templates/org/skills/prompt-to-safe-task/SKILL.md +59 -0
  188. claude_kit/_payload/templates/org/skills/prototype-to-production/SKILL.md +61 -0
  189. claude_kit/_payload/templates/org/skills/repo-onboarding/SKILL.md +60 -0
  190. claude_kit/_payload/templates/settings.json +53 -0
  191. claude_kit/_payload/templates/stacks/backend/python/fastapi/rules/fastapi-patterns.md +64 -0
  192. claude_kit/_payload/templates/stacks/db/mongodb/agents/migration-specialist.md +61 -0
  193. claude_kit/_payload/templates/stacks/db/mongodb/agents/mongodb-specialist.md +59 -0
  194. claude_kit/_payload/templates/stacks/db/mongodb/rules/mongodb-patterns.md +39 -0
  195. claude_kit/_payload/templates/stacks/db/postgres/agents/db-performance-reviewer.md +66 -0
  196. claude_kit/_payload/templates/stacks/db/postgres/agents/migration-specialist.md +56 -0
  197. claude_kit/_payload/templates/stacks/db/postgres/agents/postgres-specialist.md +58 -0
  198. claude_kit/_payload/templates/stacks/db/postgres/rules/database-performance.md +64 -0
  199. claude_kit/_payload/templates/stacks/db/postgres/rules/postgres-patterns.md +43 -0
  200. claude_kit/_payload/templates/stacks/frontend/react/rules/react-patterns.md +63 -0
  201. claude_kit/catalog.py +476 -0
  202. claude_kit/cli.py +327 -0
  203. claude_kit/hooks.py +246 -0
  204. claude_kit/models.py +205 -0
  205. claude_kit/prompts.py +209 -0
  206. claude_kit/render.py +146 -0
  207. claude_kit/scaffold.py +492 -0
  208. claude_kit/upgrader.py +294 -0
  209. claude_kit/validator.py +197 -0
@@ -0,0 +1,368 @@
1
+ ---
2
+ name: security-and-hardening
3
+ description: Hardens code against vulnerabilities. Use when handling user input, authentication, data storage, or external integrations. Use when building any feature that accepts untrusted data, manages user sessions, or interacts with third-party services.
4
+ ---
5
+
6
+ # Security and Hardening
7
+
8
+ ## Overview
9
+
10
+ Security-first development for any stack. Treat every external input as hostile, every secret as sacred, and every authorization check as mandatory — and in a multi-tenant system (if applicable), treat **every tenant-scoped query without proper scoping as a data breach**. Security isn't a phase; it's a constraint on every line that touches user data, auth, or external systems.
11
+
12
+ Companion rules: `.claude/rules/code-organization.md` (auth & dependency patterns), `.claude/rules/design-patterns.md` (service/repository boundaries), `.claude/rules/documentation.md` (security documentation). The `security-reviewer` agent (Phase 5.4 in `.claude/rules/mandatory-workflow.md`) enforces what this skill teaches.
13
+
14
+ ## When to Use
15
+
16
+ - Building anything that accepts user input
17
+ - Implementing authentication or authorization
18
+ - Storing or transmitting sensitive data
19
+ - Integrating with external APIs or services
20
+ - Adding file uploads, webhooks, or callbacks
21
+ - Handling PII
22
+
23
+ ## The Three-Tier Boundary System
24
+
25
+ ### Always Do (No Exceptions)
26
+
27
+ - **Validate all external input** with typed schemas at the boundary (route handlers) — use the project's validation framework to enforce constraints, types, enums for constrained strings
28
+ - **Scope every tenant-restricted query appropriately** — filter by tenant/organization/account ID for multi-tenant systems
29
+ - **Parameterize all queries** — use the ORM's binding mechanism or prepared statements; never string interpolation with user input
30
+ - **Hash passwords with a strong algorithm** — argon2id, bcrypt, or scrypt; never MD5/SHA for new code
31
+ - **Keep async paths fully async** (if applicable) — async database sessions, async HTTP clients, async cache clients (blocking calls stall the event loop)
32
+ - **Set session cookies securely** — `HttpOnly=True`, `SameSite="lax"`, `Secure=True` in production
33
+ - **Restrict CORS** to an explicit origin allowlist
34
+ - **Rate-limit auth endpoints** (register, login, forgot/reset)
35
+ - **Run dependency audits** before every release
36
+
37
+ ### Ask First (Requires Human Approval)
38
+
39
+ - Adding or changing authentication / session logic
40
+ - Storing new categories of sensitive data (PII)
41
+ - Adding new external service integrations
42
+ - Changing CORS origins or cookie/session settings
43
+ - Adding file upload handlers
44
+ - Modifying rate limiting or throttling
45
+ - Granting elevated roles (admin, superuser, etc.)
46
+
47
+ ### Never Do
48
+
49
+ - **Never commit secrets** — config goes through environment variables or a secrets manager (gitignored)
50
+ - **Never log sensitive data** — no passwords, hashes, full session ids, tokens, or PII in logs
51
+ - **Never trust client-side validation** as a security boundary
52
+ - **Never run a query on a scoped model without the appropriate tenant filter** (multi-tenant systems)
53
+ - **Never use debug print statements** in app code, or render user input as raw HTML without sanitization
54
+ - **Never store auth tokens in browser localStorage** — sessions are cookie-based
55
+ - **Never expose stack traces** or internal errors to clients
56
+
57
+ ## OWASP Top 10 Prevention
58
+
59
+ ### 1. Injection (SQL / Command)
60
+
61
+ ```python
62
+ # BAD — string-built SQL
63
+ stmt = text(f"SELECT * FROM users WHERE email = '{email}'")
64
+
65
+ # GOOD — ORM with bound params, async
66
+ stmt = select(User).where(User.email == email.lower())
67
+ result = await db.execute(stmt)
68
+ user = result.scalar_one_or_none()
69
+ ```
70
+
71
+ ```javascript
72
+ // BAD — string-built query (example for SQL-like ORMs)
73
+ const query = `SELECT * FROM users WHERE email = '${email}'`;
74
+
75
+ // GOOD — parameterized query
76
+ const user = await db.query('SELECT * FROM users WHERE email = $1', [email]);
77
+ ```
78
+
79
+ ### 2. Broken Authentication
80
+
81
+ ```python
82
+ # Password hashing — argon2id
83
+ from argon2 import PasswordHasher
84
+
85
+ _ph = PasswordHasher() # argon2id defaults
86
+
87
+ def hash_password(password: str) -> str:
88
+ return _ph.hash(password)
89
+
90
+ def verify_password(password: str, password_hash: str) -> bool:
91
+ from argon2.exceptions import VerifyMismatchError
92
+ try:
93
+ return _ph.verify(password_hash, password)
94
+ except VerifyMismatchError:
95
+ return False
96
+
97
+ # Session cookie (set on login) — flags from settings
98
+ response.set_cookie(
99
+ key=settings.SESSION_COOKIE_NAME,
100
+ value=session_id,
101
+ httponly=True,
102
+ samesite="lax",
103
+ secure=not settings.DEBUG, # Secure in production
104
+ max_age=settings.SESSION_TTL_SECONDS,
105
+ )
106
+ ```
107
+
108
+ ### 3. Cross-Site Scripting (XSS) — frontend
109
+
110
+ ```tsx
111
+ // BAD — renders user input as HTML
112
+ <div dangerouslySetInnerHTML={{ __html: userInput }} />
113
+
114
+ // GOOD — framework auto-escapes by default (React, Vue, Angular)
115
+ <div>{userInput}</div>
116
+
117
+ // If you MUST render HTML, sanitize first
118
+ import DOMPurify from "dompurify";
119
+ <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
120
+ ```
121
+
122
+ ### 4. Broken Access Control — authn + authz + tenant isolation
123
+
124
+ ```python
125
+ @router.patch("/v1/tasks/{task_id}", response_model=TaskRead)
126
+ async def update_task(
127
+ task_id: uuid.UUID,
128
+ payload: TaskUpdate,
129
+ current_user: User = Depends(require_auth), # authenticated
130
+ db: AsyncSession = Depends(get_db_session),
131
+ ) -> TaskRead:
132
+ # Tenant isolation: scope the lookup to the caller's org — never just by id
133
+ stmt = select(Task).where(
134
+ Task.id == task_id,
135
+ Task.organization_id == current_user.organization_id,
136
+ )
137
+ task = (await db.execute(stmt)).scalar_one_or_none()
138
+ if task is None:
139
+ raise HTTPException(status.HTTP_404_NOT_FOUND, "task not found")
140
+ ...
141
+ ```
142
+
143
+ ```javascript
144
+ // Example for Node.js / Express-style backend
145
+ app.patch('/v1/tasks/:taskId', authenticate, async (req, res) => {
146
+ const task = await db.tasks.findOne({
147
+ id: req.params.taskId,
148
+ organizationId: req.user.organizationId // tenant scoping
149
+ });
150
+ if (!task) {
151
+ return res.status(404).json({ error: 'task not found' });
152
+ }
153
+ ...
154
+ });
155
+ ```
156
+
157
+ ### 5. Security Misconfiguration
158
+
159
+ ```python
160
+ # CORS — allowlist from settings, never "*" with credentials
161
+ app.add_middleware(
162
+ CORSMiddleware,
163
+ allow_origins=settings.CORS_ORIGINS, # e.g. ["http://localhost:3000"]
164
+ allow_credentials=True,
165
+ allow_methods=["*"],
166
+ allow_headers=["*"],
167
+ )
168
+
169
+ # Security headers (middleware)
170
+ response.headers["X-Content-Type-Options"] = "nosniff"
171
+ response.headers["X-Frame-Options"] = "DENY"
172
+ response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
173
+ # Strict-Transport-Security + Content-Security-Policy at the edge / in prod
174
+ ```
175
+
176
+ ### 6. Sensitive Data Exposure
177
+
178
+ ```python
179
+ # Never expose password_hash / tokens — separate Read schema
180
+ class UserRead(UserBase):
181
+ id: uuid.UUID
182
+ organization_id: uuid.UUID
183
+ created_at: datetime
184
+ model_config = ConfigDict(from_attributes=True)
185
+ # password_hash deliberately absent
186
+
187
+ # Secrets only via environment or settings framework
188
+ from config.settings import settings
189
+ key = settings.SECRET_KEY # never hardcoded
190
+ ```
191
+
192
+ ## Input Validation Patterns
193
+
194
+ ### Schema Validation at Boundaries
195
+
196
+ Use the project's schema validation framework (e.g., Pydantic for Python, Zod/Yup for TypeScript, JSR-303 for Java):
197
+
198
+ ```python
199
+ # Python example
200
+ from pydantic import BaseModel, EmailStr, Field, field_validator
201
+
202
+ class UserCreate(BaseModel):
203
+ email: EmailStr
204
+ password: str = Field(min_length=12, max_length=128)
205
+ first_name: str = Field(min_length=1, max_length=100)
206
+
207
+ @field_validator("password")
208
+ @classmethod
209
+ def password_strength(cls, v: str) -> str:
210
+ if not any(c.isupper() for c in v):
211
+ raise ValueError("must contain an uppercase letter")
212
+ if not any(c.isdigit() for c in v):
213
+ raise ValueError("must contain a digit")
214
+ return v
215
+ # The framework returns 422 automatically on validation failure.
216
+ ```
217
+
218
+ ```typescript
219
+ // TypeScript example with Zod
220
+ import { z } from 'zod';
221
+
222
+ const UserCreateSchema = z.object({
223
+ email: z.string().email(),
224
+ password: z.string().min(12).max(128).refine(
225
+ (val) => /[A-Z]/.test(val) && /[0-9]/.test(val),
226
+ { message: "must contain uppercase letter and digit" }
227
+ ),
228
+ firstName: z.string().min(1).max(100),
229
+ });
230
+ ```
231
+
232
+ ### File Upload Safety
233
+
234
+ ```python
235
+ ALLOWED_TYPES = {"image/jpeg", "image/png", "image/webp"}
236
+ MAX_SIZE = 5 * 1024 * 1024 # 5 MB
237
+
238
+ def validate_upload(content_type: str, size: int) -> None:
239
+ if content_type not in ALLOWED_TYPES:
240
+ raise HTTPException(status.HTTP_422_UNPROCESSABLE_ENTITY, "file type not allowed")
241
+ if size > MAX_SIZE:
242
+ raise HTTPException(status.HTTP_413_REQUEST_ENTITY_TOO_LARGE, "file too large (max 5MB)")
243
+ # Don't trust the extension — verify magic bytes if it matters
244
+ ```
245
+
246
+ ## Triaging Dependency Audit Results
247
+
248
+ Not every finding is an emergency. Decision tree:
249
+
250
+ ```
251
+ Vulnerability reported (dependency audit)
252
+ ├── Severity: critical or high
253
+ │ ├── Is the vulnerable code path reachable in your app?
254
+ │ │ ├── YES --> Fix immediately (upgrade / patch / replace)
255
+ │ │ └── NO (dev-only dep, unused path) --> Fix soon, not a release blocker
256
+ │ └── Is a fix available?
257
+ │ ├── YES --> Upgrade to the patched version (flag major bumps as breaking)
258
+ │ └── NO --> Workaround, replace the dep, or allowlist with a review date
259
+ ├── Severity: moderate
260
+ │ ├── Reachable in prod? --> Fix next release cycle
261
+ │ └── Dev-only? --> Track in backlog
262
+ └── Severity: low --> Fix during regular dependency updates
263
+ ```
264
+
265
+ Editing dependency manifests requires user approval — the `dependency-scanner` recommends, the developer lane applies. Document any deferral with a reason and a review date.
266
+
267
+ ## Rate Limiting (Cache-backed)
268
+
269
+ Apply rate limiting to authentication and public endpoints:
270
+
271
+ ```python
272
+ # Example with Redis-backed rate limiting
273
+ @router.post("/v1/auth/login", response_model=...)
274
+ async def login(
275
+ payload: LoginRequest,
276
+ _: None = Depends(rate_limit("auth:login", max_calls=10, window_seconds=900)), # 10 / 15 min
277
+ db: AsyncSession = Depends(get_db_session),
278
+ ) -> ...:
279
+ ...
280
+ ```
281
+
282
+ - Key unauthenticated endpoints by **client IP**; authenticated by **user id**.
283
+ - Cover `register`, `login`, `forgot-password`, `reset-password`.
284
+
285
+ ## Secrets Management
286
+
287
+ ```
288
+ .env files:
289
+ ├── .env.example → committed (placeholder values only)
290
+ ├── .env → NOT committed (real secrets)
291
+ └── .env.*.local → NOT committed
292
+
293
+ .gitignore must include: .env, .env.local, .env.*.local, *.pem, *.key
294
+ All config is read via the project's settings framework — never scattered environment reads.
295
+ ```
296
+
297
+ ```bash
298
+ # Before committing — check for staged secrets
299
+ git diff --cached | grep -iE "password|secret|api_key|token|SECRET_KEY|DATABASE_URL"
300
+ ```
301
+
302
+ ## Security Review Checklist
303
+
304
+ ```markdown
305
+ ### Authentication
306
+ - [ ] Passwords hashed with a strong algorithm (argon2id, bcrypt, scrypt)
307
+ - [ ] Session cookies HttpOnly + SameSite=Lax + Secure(prod)
308
+ - [ ] Login + forgot/reset rate-limited
309
+ - [ ] Password-reset tokens expire
310
+
311
+ ### Authorization & Tenancy
312
+ - [ ] Every endpoint uses the auth chain (authentication + authorization)
313
+ - [ ] EVERY tenant-scoped query filters by tenant/organization/account ID (multi-tenant systems)
314
+ - [ ] Users cannot reach another tenant's resources (no IDOR)
315
+ - [ ] Create schemas don't accept server-owned fields (id, tenant_id, etc.)
316
+
317
+ ### Input
318
+ - [ ] All request bodies validated with typed schemas and constraints
319
+ - [ ] Queries parameterized (no string interpolation with user input)
320
+ - [ ] Frontend: no raw HTML rendering with user data
321
+
322
+ ### Data & Logging
323
+ - [ ] No secrets in code or git history (environment variables / secrets manager)
324
+ - [ ] Read schemas exclude password_hash / tokens
325
+ - [ ] Logs never contain passwords, hashes, session ids, or PII
326
+
327
+ ### Infrastructure
328
+ - [ ] CORS origins allowlist (no "*")
329
+ - [ ] Security headers set (X-Content-Type-Options, X-Frame-Options, HSTS, CSP)
330
+ - [ ] Dependency audits clean of Critical/High
331
+ - [ ] Error responses don't leak internals
332
+ ```
333
+
334
+ See `.claude/skills/_references/security-checklist.md` for the full pre-commit checklist.
335
+
336
+ ## Common Rationalizations
337
+
338
+ | Rationalization | Reality |
339
+ |---|---|
340
+ | "This is an internal tool, security doesn't matter" | Internal tools get compromised. Attackers target the weakest link. |
341
+ | "We'll add security later" | Retrofitting is 10x harder. Add it now. |
342
+ | "No one would try to exploit this" | Automated scanners will find it. Obscurity is not security. |
343
+ | "The framework handles security" | Frameworks provide tools, not guarantees — raw queries and missing tenant filters still leak. |
344
+ | "It's just a prototype" | Prototypes become production. Security habits from day one. |
345
+
346
+ ## Red Flags
347
+
348
+ - A query on a scoped model with no tenant/organization/account filter (multi-tenant systems)
349
+ - Raw SQL or string interpolation building queries; user input in system commands
350
+ - Secrets in source, config files, or commit history
351
+ - Endpoints missing authentication / authorization enforcement
352
+ - CORS origins set to `*`, or no rate limiting on auth endpoints
353
+ - Logs that include passwords, tokens, or PII
354
+ - Blocking calls in async request paths (if async architecture)
355
+ - Stack traces or internal errors returned to clients
356
+
357
+ ## Verification
358
+
359
+ After implementing security-relevant code:
360
+
361
+ - [ ] Run dependency audit — no Critical/High vulnerabilities
362
+ - [ ] No secrets in source or git history
363
+ - [ ] Every tenant-scoped query filters by tenant/organization/account ID (multi-tenant systems)
364
+ - [ ] All input validated via typed schemas at the boundary
365
+ - [ ] Auth + authz enforced on every protected endpoint
366
+ - [ ] Passwords hashed with strong algorithm; session cookies HttpOnly/SameSite/Secure
367
+ - [ ] Logs contain no secrets/PII; error responses don't expose internals
368
+ - [ ] Rate limiting active on auth endpoints
@@ -0,0 +1,209 @@
1
+ ---
2
+ name: security-verification
3
+ description: Verify and enforce input sanitization and security best practices across all user input surfaces — forms, textareas, query params, URL params, and external data, for any web stack.
4
+ argument-hint: [component, page, or "all"]
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ Run security verification on: $ARGUMENTS.
9
+
10
+ ## Steps
11
+
12
+ 1. **Identify all input surfaces**: Search the target code for every point where user input enters the application.
13
+
14
+ ### Input Sources to Check
15
+ Adjust patterns to match your project's framework/language:
16
+ ```bash
17
+ # Search for all input surfaces (examples for web frontends)
18
+ grep -rn '<Input\|<input\|<textarea\|<Textarea' src/
19
+ grep -rn 'useForm\|useSearchParams\|useParams\|queryParam' src/ # React/React Router
20
+ grep -rn 'params\|request.args\|request.form' . # Flask/Django/FastAPI
21
+ grep -rn 'dangerouslySetInnerHTML\|innerHTML\|outerHTML' src/
22
+ grep -rn 'window.location\|document.cookie\|localStorage\|sessionStorage' src/
23
+ grep -rn 'eval\|new Function\|document.write' src/
24
+ ```
25
+
26
+ 2. **Audit each input source against the checklist**:
27
+
28
+ ### Form Inputs (`<input>`, `<Input>`, or framework equivalents)
29
+ | Check | Status | Fix |
30
+ |-------|--------|-----|
31
+ | Schema validation on submit (Zod/Joi/Yup/Pydantic/etc.) | | Add validation schema with `.trim().min(1)` or equivalent |
32
+ | `maxLength` attribute/constraint set | | Add length limit |
33
+ | HTML entities escaped (auto in most modern frameworks) | | Verify template engine auto-escapes |
34
+ | No raw value used in `href` or `src` | | Validate URL format before use |
35
+ | Input type matches expected data | | Use semantic types (email, number, etc.) |
36
+
37
+ ### Textareas (multi-line input fields)
38
+ | Check | Status | Fix |
39
+ |-------|--------|-----|
40
+ | Schema validation on submit with max length | | Add `.trim().max(N)` or equivalent |
41
+ | `maxLength` attribute/constraint set | | Add length limit |
42
+ | Content not rendered as raw HTML | | Use text rendering, never HTML injection |
43
+
44
+ ### Form Submissions (validation libraries: react-hook-form, Formik, WTForms, etc.)
45
+ | Check | Status | Fix |
46
+ |-------|--------|-----|
47
+ | Schema validation attached to form handler | | Add validator integration |
48
+ | All fields validated before processing | | Use framework's validation wrapper |
49
+ | Error messages shown for invalid input | | Display validation errors to user |
50
+ | Submit button disabled during submission | | Use framework's submission state |
51
+
52
+ ### URL Query Parameters (framework routing/request parsing)
53
+ | Check | Status | Fix |
54
+ |-------|--------|-----|
55
+ | Parsed with safe API (URLSearchParams, framework request parsers) | | Never parse `window.location` or raw query strings manually |
56
+ | Values validated/cast before use | | Coerce to expected type with validation |
57
+ | Default values for missing params | | Use `.get('key', default)` or equivalent |
58
+ | Not used in `href`/`src` without validation | | Validate URL format |
59
+
60
+ ### URL Path Parameters (framework routing)
61
+ | Check | Status | Fix |
62
+ |-------|--------|-----|
63
+ | Type-checked after extraction | | Cast/validate params after extraction |
64
+ | Validated against expected pattern | | Check format/range before use |
65
+ | Not interpolated into URLs unsafely | | Use URL encoding (encodeURIComponent or equivalent) |
66
+
67
+ ### Dangerous Patterns (universal across web stacks)
68
+ | Pattern | Risk | Fix |
69
+ |---------|------|-----|
70
+ | `dangerouslySetInnerHTML` (React), `{% autoescape off %}` (Jinja), `{!! $var !!}` (Blade) | XSS | Remove or sanitize with DOMPurify/bleach/equivalent |
71
+ | `innerHTML` / `outerHTML` | XSS | Use framework's safe template rendering |
72
+ | `document.write` | XSS | Never use |
73
+ | `eval()` / `new Function()` / `exec()` / `system()` | Code injection | Never use with user input |
74
+ | `window.location = userInput` | Open redirect | Validate against allowlist |
75
+ | Template literals in `href` without validation | XSS via `javascript:` protocol | Validate URL scheme |
76
+
77
+ 3. **Check for OWASP Top 10 frontend/API concerns**:
78
+
79
+ | # | Vulnerability | Check |
80
+ |---|--------------|----------------|
81
+ | A03 | Injection (XSS, SQL, Command) | No raw HTML rendering of user input; parameterized queries; no shell command interpolation |
82
+ | A05 | Security Misconfiguration | No secrets in client-side code or version control |
83
+ | A07 | Cross-Site Scripting | All outputs escaped, no unsafe HTML injection |
84
+ | A08 | Software Integrity | Dependencies from trusted sources, audit tools clean (npm audit, pip-audit, etc.) |
85
+ | A09 | Logging Failures | No sensitive data in logs (passwords, tokens, PII) |
86
+
87
+ 4. **Verify sanitization utilities exist**: Check the project's utility module for sanitization helpers. If missing, add stack-appropriate versions:
88
+
89
+ **Example (TypeScript/JavaScript):**
90
+ ```typescript
91
+ // Sanitize user input for display
92
+ export function sanitizeInput(input: string): string {
93
+ return input.trim().replace(/[<>]/g, '');
94
+ }
95
+
96
+ // Validate URL is safe (no javascript: protocol)
97
+ export function isSafeUrl(url: string): boolean {
98
+ try {
99
+ const parsed = new URL(url, window.location.origin);
100
+ return ['http:', 'https:'].includes(parsed.protocol);
101
+ } catch {
102
+ return false;
103
+ }
104
+ }
105
+
106
+ // Encode value for URL parameter
107
+ export function safeParam(value: string): string {
108
+ return encodeURIComponent(value.trim());
109
+ }
110
+ ```
111
+
112
+ **Example (Python):**
113
+ ```python
114
+ from urllib.parse import urlparse, quote
115
+ from bleach import clean
116
+
117
+ def sanitize_input(input: str) -> str:
118
+ return clean(input.strip(), tags=[], strip=True)
119
+
120
+ def is_safe_url(url: str) -> bool:
121
+ try:
122
+ parsed = urlparse(url)
123
+ return parsed.scheme in {'http', 'https'}
124
+ except Exception:
125
+ return False
126
+
127
+ def safe_param(value: str) -> str:
128
+ return quote(value.strip(), safe='')
129
+ ```
130
+
131
+ 5. **Report findings**: Output a security audit table:
132
+
133
+ | File | Line | Input Source | Vulnerability | Severity | Fix |
134
+ |------|------|-------------|---------------|----------|-----|
135
+
136
+ Severity levels:
137
+ - **Critical**: Direct XSS vector or code injection
138
+ - **High**: Missing validation on user input that affects application state
139
+ - **Medium**: Missing sanitization on display-only input
140
+ - **Low**: Missing length limit or type attribute
141
+
142
+ 6. **Apply fixes**: For each finding, apply the recommended fix. Prioritize Critical and High first.
143
+
144
+ 7. **Verify**: Run the project's linter, type checker, and build to confirm the changes are valid.
145
+
146
+ ## Quick Reference: Secure Input Pattern (React + Zod example)
147
+
148
+ ```tsx
149
+ import { useForm } from 'react-hook-form';
150
+ import { zodResolver } from '@hookform/resolvers/zod';
151
+ import { z } from 'zod';
152
+ import { Input } from '@/components/ui';
153
+
154
+ const schema = z.object({
155
+ name: z.string().trim().min(1, 'Name is required').max(100),
156
+ email: z.string().trim().email('Invalid email').max(255),
157
+ notes: z.string().trim().max(1000).optional(),
158
+ });
159
+
160
+ type FormData = z.infer<typeof schema>;
161
+
162
+ function SecureForm() {
163
+ const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<FormData>({
164
+ resolver: zodResolver(schema),
165
+ });
166
+
167
+ const onSubmit = (data: FormData) => {
168
+ // data is validated and typed — safe to use
169
+ };
170
+
171
+ return (
172
+ <form onSubmit={handleSubmit(onSubmit)}>
173
+ <Input {...register('name')} maxLength={100} />
174
+ {errors.name && <p className="text-sm text-red-600">{errors.name.message}</p>}
175
+
176
+ <Input {...register('email')} type="email" maxLength={255} />
177
+ {errors.email && <p className="text-sm text-red-600">{errors.email.message}</p>}
178
+
179
+ <textarea {...register('notes')} maxLength={1000} />
180
+ {errors.notes && <p className="text-sm text-red-600">{errors.notes.message}</p>}
181
+
182
+ <button type="submit" disabled={isSubmitting}>Submit</button>
183
+ </form>
184
+ );
185
+ }
186
+ ```
187
+
188
+ ## Quick Reference: Secure Input Pattern (Python/FastAPI + Pydantic example)
189
+
190
+ ```python
191
+ from pydantic import BaseModel, EmailStr, Field
192
+
193
+ class UserCreate(BaseModel):
194
+ name: str = Field(min_length=1, max_length=100)
195
+ email: EmailStr = Field(max_length=255)
196
+ notes: str | None = Field(None, max_length=1000)
197
+
198
+ @router.post("/users", response_model=UserRead, status_code=201)
199
+ async def create_user(payload: UserCreate) -> UserRead:
200
+ # payload is validated and typed — safe to use
201
+ # Pydantic auto-trims and validates
202
+ ...
203
+ ```
204
+
205
+ ## References
206
+
207
+ - OWASP Top 10: https://owasp.org/www-project-top-ten/
208
+ - OWASP XSS Prevention Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
209
+ - Validation libraries: Zod (TS/JS), Joi (JS), Pydantic (Python), WTForms (Python), Bean Validation (Java)