@cassiomc1/forgeloop 0.1.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/.cursor/rules/project-loop.mdc +18 -0
- package/.forgeloop/.gitignore +2 -0
- package/.github/copilot-instructions.md +16 -0
- package/AGENTS.md +16 -0
- package/AGENT_COMPATIBILITY.md +147 -0
- package/CLAUDE.md +14 -0
- package/CONTRACT_COVERAGE.md +27 -0
- package/DELEGATION_PROTOCOL.md +91 -0
- package/ENG/accessibility-eng.md +155 -0
- package/ENG/clean-code-eng.md +223 -0
- package/ENG/design-code-eng.md +511 -0
- package/ENG/games-code-design-web-eng.md +751 -0
- package/ENG/perf-code-eng.md +441 -0
- package/ENG/premium-sites-studio-eng.md +320 -0
- package/ENG/sec-code-eng.md +706 -0
- package/ENG/test-code-eng.md +257 -0
- package/EXECUTION_STATE.md +107 -0
- package/GUIDE_ROUTER.md +274 -0
- package/LICENSE +21 -0
- package/LICENSE-DOCS.md +13 -0
- package/LOOP_ENGINEERING.md +551 -0
- package/LOOP_SYSTEM_DESIGN.md +394 -0
- package/ORCHESTRATOR_INTEGRATION.md +106 -0
- package/PROJECT_PROFILE.md +124 -0
- package/QUALITY_SCORECARD.md +54 -0
- package/README.md +492 -0
- package/TERMINOLOGY.md +21 -0
- package/THIRD_PARTY_NOTICES.md +129 -0
- package/THREAT_MODEL.md +35 -0
- package/package.json +51 -0
- package/schemas/delegated-result.schema.json +33 -0
- package/schemas/evidence.schema.json +15 -0
- package/schemas/execution-receipt.schema.json +46 -0
- package/schemas/routing-input.schema.json +17 -0
- package/schemas/routing-result.schema.json +17 -0
- package/schemas/task-brief.schema.json +24 -0
- package/schemas/work-state.schema.json +46 -0
- package/src/cli.js +341 -0
- package/src/commands/clear-state.js +11 -0
- package/src/commands/doctor.js +165 -0
- package/src/commands/init.js +42 -0
- package/src/commands/inspect.js +17 -0
- package/src/commands/route.js +32 -0
- package/src/commands/status.js +29 -0
- package/src/commands/update.js +109 -0
- package/src/commands/validate-protocol.js +133 -0
- package/src/commands/validate-receipt.js +19 -0
- package/src/commands/validate-state.js +30 -0
- package/src/core/agent-support.js +89 -0
- package/src/core/conformance.js +133 -0
- package/src/core/delegation.js +283 -0
- package/src/core/evidence.js +56 -0
- package/src/core/filesystem.js +122 -0
- package/src/core/inspect.js +115 -0
- package/src/core/json-safety.js +54 -0
- package/src/core/manifest.js +75 -0
- package/src/core/protocol.js +81 -0
- package/src/core/receipt.js +129 -0
- package/src/core/repository.js +19 -0
- package/src/core/router.js +296 -0
- package/src/core/schema-validation.js +179 -0
- package/src/core/templates.js +56 -0
- package/src/core/work-state.js +471 -0
|
@@ -0,0 +1,706 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sec-code-eng
|
|
3
|
+
language: en
|
|
4
|
+
description: "Verifiable security guidance for web, mobile, desktop, APIs, and the software supply chain."
|
|
5
|
+
version: "2026.09"
|
|
6
|
+
last-reviewed: "2026-08-10"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Security Guide for Web, Mobile, and Desktop Development
|
|
10
|
+
|
|
11
|
+
Practical secure-coding guidance for web, mobile (iOS/Android), and desktop
|
|
12
|
+
(Windows/macOS) development. Use this document to turn risks into testable
|
|
13
|
+
controls, evidence, and recorded decisions.
|
|
14
|
+
|
|
15
|
+
**Related documents**: for general code quality/structure, see
|
|
16
|
+
[`clean-code-eng.md`](./clean-code-eng.md). For testing frameworks and tools
|
|
17
|
+
(including SAST/DAST in the pipeline), see
|
|
18
|
+
[`test-code-eng.md`](./test-code-eng.md). For videos and HTML compositions,
|
|
19
|
+
see [HyperFrames](https://hyperframes.heygen.com) and treat scripts, assets,
|
|
20
|
+
and external URLs as attack surface. This file is the canonical security
|
|
21
|
+
reference; secrets, authorization, cryptography, and OWASP rules live here,
|
|
22
|
+
not in the other files.
|
|
23
|
+
|
|
24
|
+
**Tooling policy**: identify the stack, stage, and applicable checks; prefer an
|
|
25
|
+
already-available equivalent that produces compatible evidence. Ask for
|
|
26
|
+
authorization before installing a tool or changing the environment. If no
|
|
27
|
+
safe equivalent exists, record the required check as blocked and never claim
|
|
28
|
+
it passed. Do not install merely optional resources.
|
|
29
|
+
|
|
30
|
+
## General principles (valid for any platform)
|
|
31
|
+
|
|
32
|
+
- **Secure by design**: think about security during the design phase, not as a "review" at the end. Perform threat modeling for sensitive features (login, payment, file upload).
|
|
33
|
+
- **Least privilege**: users, processes, API keys, and database credentials must have only the permissions strictly necessary.
|
|
34
|
+
- **Defense in depth**: never rely on a single layer of protection (e.g., validation only on the frontend). Every critical validation/authorization decision must be enforced at a trusted boundary: a server-side or serverless service for remote authority, or a documented OS, process, or container boundary for local/offline authority.
|
|
35
|
+
- **Never trust the client**: data coming from the browser, mobile app, or desktop app can be manipulated. Authoritative decisions about remote authentication, authorization, price, or permission belong at a trusted service boundary. For local/offline authority, protect the documented OS/process/container boundary and protected local storage, Keychain, or credential vault with integrity, confidentiality, and capability checks. Input crossing either boundary remains untrusted; client-side checks are only defense in depth.
|
|
36
|
+
- **Fail secure / secure by default**: in case of an error or missing configuration, the system must deny access by default, never grant it.
|
|
37
|
+
- **Secrets never in source code**: API keys, passwords, tokens, and certificates belong in environment variables or secret management services (Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager) — never committed to git.
|
|
38
|
+
- **Compositions and media are inputs too**: validate generated HTML/JS, manifests, URLs, formats, sizes, and media origins; pin dependencies where possible and never embed secrets in a composition or video bundle.
|
|
39
|
+
- **Continuously update dependencies**: use automated scanners (Dependabot, Renovate, Snyk, `npm audit`, `pip-audit`, `bundler-audit`) and treat critical vulnerabilities as high-priority bugs.
|
|
40
|
+
- **Log security events, never sensitive data**: record login attempts, authorization failures, and permission changes; never log passwords, complete tokens, card numbers, or personal data in plain text.
|
|
41
|
+
- **Cryptography**: use a high-level library and a validated implementation;
|
|
42
|
+
choose the algorithm, mode, key size, and parameters for the use case, and
|
|
43
|
+
maintain an inventory and migration path. Never implement primitives or
|
|
44
|
+
mistake an algorithm name for a security guarantee.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Verifiable baseline: OWASP ASVS 5.0
|
|
49
|
+
|
|
50
|
+
- Adopt **OWASP ASVS 5.0.0 Level 1 (L1)** as the minimum baseline for web
|
|
51
|
+
applications and APIs. Adopt **L2** for sensitive applications, including
|
|
52
|
+
those handling material authentication, health, financial, regulated, or
|
|
53
|
+
high-impact operations. L3 requires specialist analysis and is not inferred
|
|
54
|
+
automatically.
|
|
55
|
+
- Use the OWASP Top 10 for awareness and risk prioritization, not as a
|
|
56
|
+
sufficient verification checklist. Record the ASVS level, applicable
|
|
57
|
+
requirements, exceptions, owner, evidence, and verification date.
|
|
58
|
+
- Cite requirements with the full version, for example
|
|
59
|
+
`v5.0.0-1.2.4`; unversioned IDs can change. Do not claim conformance just
|
|
60
|
+
because a scanner passed: every applicable requirement needs reproducible
|
|
61
|
+
evidence, manual review, or a not-applicable rationale.
|
|
62
|
+
- For mobile, complement this baseline with MASVS/MASTG; ASVS still applies to
|
|
63
|
+
the web backend and API controls used by the app.
|
|
64
|
+
|
|
65
|
+
### Minimum evidence map
|
|
66
|
+
|
|
67
|
+
| Control | Confirmed ASVS 5.0.0 references | Expected evidence |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| Server-side validation and authorization | `v5.0.0-2.2.2`, `v5.0.0-8.3.1` | negative tests per operation and resource |
|
|
70
|
+
| Parameterized SQL | `v5.0.0-1.2.4` | test/review showing no input concatenation |
|
|
71
|
+
| Cookies and headers | chapters V3.3 and V3.4 | captured responses and browser tests |
|
|
72
|
+
| File upload | chapters V5.1 through V5.4 | valid, invalid, compressed, and malicious corpus |
|
|
73
|
+
| Session | chapters V7.2 through V7.4 | verified rotation, expiry, and invalidation |
|
|
74
|
+
| OAuth/OIDC and tokens | chapters V9 and V10 | signature, claim, replay, and redirect cases |
|
|
75
|
+
| Secrets and dependencies | chapters V13.3 and V15.1/V15.2 | scans, inventory, SBOM, and rotation trail |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## High-risk input contracts
|
|
80
|
+
|
|
81
|
+
### Outbound requests and SSRF
|
|
82
|
+
|
|
83
|
+
Before untrusted input may influence an outbound request, define and test this
|
|
84
|
+
contract (`v5.0.0-1.3.6`, `v5.0.0-13.2.4`,
|
|
85
|
+
`v5.0.0-15.3.2`):
|
|
86
|
+
|
|
87
|
+
- accept only required schemes, normally `https`; parse and canonicalize with
|
|
88
|
+
a URL library, reject embedded credentials, fragments, and ambiguous syntax,
|
|
89
|
+
and compare scheme, host, and port with an exact business-destination
|
|
90
|
+
allowlist;
|
|
91
|
+
- resolve every A and AAAA record and reject any non-global result: private,
|
|
92
|
+
loopback, link-local, multicast, reserved, and cloud metadata endpoints.
|
|
93
|
+
Apply the same policy at the egress firewall/proxy;
|
|
94
|
+
- prevent **DNS rebinding**: validate every DNS answer immediately before the
|
|
95
|
+
connection, connect only to the validated address, and preserve TLS
|
|
96
|
+
validation of the expected hostname. Do not rely on textual domain
|
|
97
|
+
validation alone;
|
|
98
|
+
- disable redirects by default. If required, cap the number of hops and repeat
|
|
99
|
+
parsing, allowlisting, DNS resolution, and IP blocking for **every** target;
|
|
100
|
+
- do not forward internal cookies, tokens, or headers to the destination.
|
|
101
|
+
Define connect and total timeouts, response-size, concurrency, retry, and
|
|
102
|
+
bandwidth limits; fail closed and log the reason without secrets;
|
|
103
|
+
- test alternative URL syntax and IPv4/IPv6, redirects, DNS changes, internal
|
|
104
|
+
destinations, `169.254.169.254`/metadata, and slow or oversized responses.
|
|
105
|
+
|
|
106
|
+
If the product genuinely needs arbitrary destinations, isolate the fetcher
|
|
107
|
+
without credentials, enforce an egress proxy, and use a special-address
|
|
108
|
+
denylist as an additional defense; never present a denylist as an allowlist
|
|
109
|
+
replacement.
|
|
110
|
+
|
|
111
|
+
### File upload, processing, and download
|
|
112
|
+
|
|
113
|
+
Every file flow must document types and limits before implementation and meet,
|
|
114
|
+
according to its level, ASVS 5.0.0 chapters V5.1 through V5.4:
|
|
115
|
+
|
|
116
|
+
- allow only necessary extensions and verify extension, signature (*magic
|
|
117
|
+
bytes*), and content with a specialized parser; never trust the client-sent
|
|
118
|
+
`Content-Type`;
|
|
119
|
+
- generate the name/ID on the server, retain the original name only as
|
|
120
|
+
sanitized metadata, and never use user input to build paths;
|
|
121
|
+
- limit received bytes, dimensions/complexity, quantity per user, items in an
|
|
122
|
+
archive, and **post-decompression limits** before extraction
|
|
123
|
+
(`v5.0.0-5.1.1`, `v5.0.0-5.2.1` through `v5.0.0-5.2.3`);
|
|
124
|
+
- store files in a private service or outside the webroot, without execute
|
|
125
|
+
permission and with a server-defined content type. Isolate parsers and
|
|
126
|
+
converters;
|
|
127
|
+
- apply antivirus/sandboxing and CDR to compatible formats when risk requires
|
|
128
|
+
it. Quarantine the file until a result arrives and define behavior on
|
|
129
|
+
scanner timeout or failure;
|
|
130
|
+
- serve downloads only after authentication and per-object authorization,
|
|
131
|
+
through a handler that maps an internal ID, with
|
|
132
|
+
`Content-Disposition: attachment` and a sanitized name; never expose the
|
|
133
|
+
real path or permit active execution;
|
|
134
|
+
- test double extensions, false MIME, path traversal, zip slip, symlinks, ZIP
|
|
135
|
+
or XML bombs, polyglot files, unavailable parsers, and horizontal access.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## OWASP Top 10:2025 (Web) — overview and mitigation
|
|
140
|
+
|
|
141
|
+
1. **A01 – Broken Access Control (Broken access control)**: validate authorization on every route/endpoint, on the server, for every resource (including direct ID/IDOR). Never trust a `role` sent by the client. Apply deny-by-default.
|
|
142
|
+
2. **A02 – Security Misconfiguration**: remove default accounts/services, disable stack traces and detailed error messages in production, configure security headers (see HTTP section), and keep dev/staging/prod environments consistently hardened.
|
|
143
|
+
3. **A03 – Software Supply Chain Failures**: audit dependencies, use lockfiles (`package-lock.json`, `poetry.lock`), generate an SBOM (Software Bill of Materials), validate package integrity (checksums/signatures), and restrict CI/CD and publish-token permissions.
|
|
144
|
+
4. **A04 – Cryptographic Failures**: use modern HTTPS/TLS, calibrated password
|
|
145
|
+
hashing, and AEAD through a high-level library; keep keys outside code and
|
|
146
|
+
maintain a cryptographic inventory and migration plan.
|
|
147
|
+
5. **A05 – Injection**: use parameterized queries/ORMs (never concatenate SQL), validate and sanitize all input, escape output in templates (protection against XSS), and avoid `eval`/`exec` with external data.
|
|
148
|
+
6. **A06 – Insecure Design**: apply threat modeling, and review critical flows (password recovery, upload, payment) with a focus on abuse, not just the "happy path."
|
|
149
|
+
7. **A07 – Authentication Failures**: require MFA for sensitive accounts, apply rate limiting to login, block/delay after failed attempts, use session tokens with expiration and rotation, and never reveal whether the "user exists" in login error messages.
|
|
150
|
+
8. **A08 – Software or Data Integrity Failures**: validate update/package signatures, use CI/CD with protected pipelines (branch protection, commit signing), and never deserialize untrusted data without schema validation.
|
|
151
|
+
9. **A09 – Security Logging and Alerting Failures**: ensure security event logs (login, authorization failure, permission change) with automatic alerts for anomalies (multiple failures, access outside the usual pattern).
|
|
152
|
+
10. **A10 – Mishandling of Exceptional Conditions**: explicitly handle exceptions and resource limits (timeouts, quotas, payload/upload size limits), never expose a stack trace to the end user, and always "fail closed" on unexpected errors.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Web — Backend by language/technology
|
|
157
|
+
|
|
158
|
+
### Node.js / JavaScript / TypeScript
|
|
159
|
+
|
|
160
|
+
- **Helmet** (Express) or equivalent middleware to configure security headers automatically.
|
|
161
|
+
- Input validation with **Zod**, **Joi**, or **Yup** — never trust `req.body` without a schema.
|
|
162
|
+
- ORMs with parameterized queries (**Prisma**, **Drizzle**, **TypeORM**) instead of manually concatenated SQL.
|
|
163
|
+
- `npm audit` / **Snyk** / **Socket.dev** for dependencies; beware of *supply chain attacks* through malicious npm packages/typosquatting.
|
|
164
|
+
- Never use `eval()`, `new Function()`, or `child_process.exec()` with unsanitized input.
|
|
165
|
+
- Rate limiting with **express-rate-limit** or at the gateway/CDN (Cloudflare, etc.).
|
|
166
|
+
|
|
167
|
+
### Python
|
|
168
|
+
|
|
169
|
+
- ORMs with parameterized queries (**Django ORM**, **SQLAlchemy**) — never `cursor.execute(f"...{var}...")`.
|
|
170
|
+
- Schema validation with **Pydantic** (FastAPI already uses it natively).
|
|
171
|
+
- `pip-audit` / **Safety** / **Bandit** (static SAST for Python) in CI.
|
|
172
|
+
- Django: keep `DEBUG = False` in production, keep `SECRET_KEY` outside the code, restrict `ALLOWED_HOSTS`, and use `django-csp` for Content-Security-Policy.
|
|
173
|
+
- Never use `pickle` to deserialize data from an untrusted source (arbitrary code execution).
|
|
174
|
+
|
|
175
|
+
### .NET / C\#
|
|
176
|
+
|
|
177
|
+
- Use **Entity Framework** with LINQ/parameters (never `SqlCommand` with string concatenation).
|
|
178
|
+
- **ASP.NET Core Identity** or **Duende IdentityServer**/**Microsoft.Identity.Web** for authentication/OAuth2/OIDC.
|
|
179
|
+
- Data Protection API for encrypting data at rest and tokens.
|
|
180
|
+
- `dotnet list package --vulnerable` to check for vulnerable dependencies; enable **NuGet Audit**.
|
|
181
|
+
- Configure `[ValidateAntiForgeryToken]` on forms; use `HttpOnly`/`Secure`/`SameSite` on session cookies.
|
|
182
|
+
|
|
183
|
+
### Java
|
|
184
|
+
|
|
185
|
+
- **Prepared Statements**/parameterized JPA (never `Statement` with concatenation).
|
|
186
|
+
- **Spring Security** for declarative authentication/authorization; **OWASP Dependency-Check** or **Snyk** integrated with Maven/Gradle.
|
|
187
|
+
- Avoid insecure deserialization of Java objects (`ObjectInputStream` from untrusted sources) — use JSON with a validated schema instead of Java binary serialization whenever possible.
|
|
188
|
+
- Disable external entity resolution in XML parsers (protection against XXE): `setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)`.
|
|
189
|
+
|
|
190
|
+
### PHP
|
|
191
|
+
|
|
192
|
+
- **PDO with prepared statements** (never `mysqli_query` with concatenation).
|
|
193
|
+
- Modern frameworks (Laravel, Symfony) already perform automatic escaping in templates (Blade/Twig) — avoid `{!! !!}`/`|raw` without sanitization.
|
|
194
|
+
- `composer audit` for vulnerable dependencies.
|
|
195
|
+
- Configure `session.cookie_httponly`, `session.cookie_secure`, `session.cookie_samesite` in `php.ini`.
|
|
196
|
+
|
|
197
|
+
### Ruby / Rails
|
|
198
|
+
|
|
199
|
+
- ActiveRecord with parameters (never `where("... #{var}")`).
|
|
200
|
+
- **Brakeman** (SAST specific to Rails) in CI.
|
|
201
|
+
- `bundler-audit` for vulnerable gems.
|
|
202
|
+
- Rails protects against CSRF by default (`protect_from_forgery`) — never disable it without a justified need.
|
|
203
|
+
|
|
204
|
+
### Go
|
|
205
|
+
|
|
206
|
+
- `database/sql` with parameters (`?`/`$1`) — never use `fmt.Sprintf` to build SQL.
|
|
207
|
+
- **govulncheck** to check for known vulnerabilities in dependencies and the stdlib.
|
|
208
|
+
- Use `context.Context` with a timeout in every external call to avoid resource exhaustion.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Web — Frontend / Browser
|
|
213
|
+
|
|
214
|
+
- **XSS**: never insert unsanitized HTML through `innerHTML`,
|
|
215
|
+
`dangerouslySetInnerHTML`, or `v-html` with user data. Modern frameworks
|
|
216
|
+
escape by default; do not bypass that behavior without contextual
|
|
217
|
+
sanitization by a maintained library.
|
|
218
|
+
- **CSRF**: use an anti-CSRF token for state-changing operations and validate
|
|
219
|
+
`Origin`/`Referer` where applicable. `SameSite` helps but does not replace a
|
|
220
|
+
CSRF control when the flow permits cross-site requests.
|
|
221
|
+
- **Clickjacking**: use CSP `frame-ancestors`. `X-Frame-Options: DENY` may
|
|
222
|
+
remain for legacy clients, but is not the primary control
|
|
223
|
+
(`v5.0.0-3.4.6`).
|
|
224
|
+
- **Subresource Integrity (SRI)**: use `integrity` and `crossorigin` for static,
|
|
225
|
+
versioned CDN assets; prefer self-hosting when a resource changes without
|
|
226
|
+
versioning.
|
|
227
|
+
- **Client-side storage**: do not store tokens or sensitive data in
|
|
228
|
+
`localStorage`, `sessionStorage`, or IndexedDB when an `HttpOnly` session
|
|
229
|
+
cookie satisfies the flow. Assume XSS can read all JavaScript-accessible
|
|
230
|
+
storage.
|
|
231
|
+
- **Third parties**: every browser script, tag, widget, and SDK is part of the
|
|
232
|
+
supply chain; minimize, inventory, pin versions, and review data flows.
|
|
233
|
+
|
|
234
|
+
### CSP rollout and reporting
|
|
235
|
+
|
|
236
|
+
Start with `Content-Security-Policy-Report-Only`, correct legitimate
|
|
237
|
+
violations, and only then promote the same tested policy to
|
|
238
|
+
`Content-Security-Policy`. Nonces must be random, unpredictable, and new for
|
|
239
|
+
every response; never copy the placeholder below literally. Rate-limit the
|
|
240
|
+
reporting endpoint and apply retention and redaction because payloads can
|
|
241
|
+
contain URL data.
|
|
242
|
+
|
|
243
|
+
```http
|
|
244
|
+
Reporting-Endpoints: csp="https://example.com/security/csp-reports"
|
|
245
|
+
Content-Security-Policy-Report-Only: default-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'; script-src 'self' 'nonce-{RANDOM_PER_RESPONSE}'; report-to csp
|
|
246
|
+
X-Content-Type-Options: nosniff
|
|
247
|
+
Referrer-Policy: strict-origin-when-cross-origin
|
|
248
|
+
Permissions-Policy: geolocation=(), camera=(), microphone=()
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
`object-src 'none'` and `base-uri 'none'` are the minimum in
|
|
252
|
+
`v5.0.0-3.4.3`; fit `frame-ancestors`, `form-action`, `connect-src`,
|
|
253
|
+
`img-src`, `style-src`, and other directives to the architecture. Avoid
|
|
254
|
+
`unsafe-inline`, `unsafe-eval`, broad wildcards, and unnecessary hosts.
|
|
255
|
+
Collect and test reports, but do not treat `Report-Only` as enforcement.
|
|
256
|
+
|
|
257
|
+
### Exact-origin CORS
|
|
258
|
+
|
|
259
|
+
- Compare a canonicalized origin by the **scheme + host + port** tuple with an
|
|
260
|
+
explicit allowlist (`v5.0.0-3.4.2`). Reject `Origin: null`, subdomain
|
|
261
|
+
wildcards, and permissive regexes; `example.com.attacker.tld` is not part of
|
|
262
|
+
`example.com`.
|
|
263
|
+
- If the response reflects an allowlisted origin, return exactly that origin
|
|
264
|
+
and include `Vary: Origin` so caches do not share the wrong variant. Never
|
|
265
|
+
reflect the header before the comparison.
|
|
266
|
+
- Use `Access-Control-Allow-Credentials: true` only for trusted origins with a
|
|
267
|
+
documented need. `*` is only for a genuinely public response without
|
|
268
|
+
credentials or sensitive data.
|
|
269
|
+
- Restrict methods and headers, validate preflight, and keep authentication and
|
|
270
|
+
authorization at the endpoint: CORS is a browser policy, not access control
|
|
271
|
+
against non-browser clients.
|
|
272
|
+
|
|
273
|
+
### Staged HSTS
|
|
274
|
+
|
|
275
|
+
Send HSTS only over HTTPS. Start in a controlled environment with a short
|
|
276
|
+
`max-age`, monitor failures, and gradually increase it to at least one year
|
|
277
|
+
(`v5.0.0-3.4.1`). Add `includeSubDomains` only after inventorying **every**
|
|
278
|
+
current and future subdomain and confirming valid HTTPS on each one.
|
|
279
|
+
|
|
280
|
+
```http
|
|
281
|
+
Strict-Transport-Security: max-age=300
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
The example is the initial stage and does not yet satisfy ASVS verification.
|
|
285
|
+
After a validated rollout, the L1 target is `max-age=31536000` or greater; at
|
|
286
|
+
L2+, the policy must also cover every subdomain.
|
|
287
|
+
|
|
288
|
+
Preload is an explicit L3 decision (`v5.0.0-3.7.4`) with impact that is hard
|
|
289
|
+
to reverse. Use `max-age=63072000; includeSubDomains; preload` only after the
|
|
290
|
+
inventory, domain-owner approval, a recovery plan, and compliance with the
|
|
291
|
+
preload-list requirements. Sending the directive does not submit the domain.
|
|
292
|
+
|
|
293
|
+
### Cookies and session lifecycle
|
|
294
|
+
|
|
295
|
+
Use `SameSite=Strict` or `Lax` by default. `SameSite=None` is an exception for
|
|
296
|
+
a documented cross-site flow and requires `Secure` plus compatible CSRF
|
|
297
|
+
protection. Prefer the `__Host-` prefix, which requires `Secure`, `Path=/`, and
|
|
298
|
+
no `Domain`; session tokens also use `HttpOnly` (`v5.0.0-3.3.1` through
|
|
299
|
+
`v5.0.0-3.3.4`).
|
|
300
|
+
|
|
301
|
+
```http
|
|
302
|
+
Set-Cookie: __Host-Session=<opaque>; Path=/; Secure; HttpOnly; SameSite=Lax
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Generate opaque IDs with a CSPRNG, rotate them at login, reauthentication, and
|
|
306
|
+
privilege change, and invalidate the old value (`v5.0.0-7.2.3`,
|
|
307
|
+
`v5.0.0-7.2.4`). Define and enforce server-side **idle** and **absolute**
|
|
308
|
+
timeouts based on risk (`v5.0.0-7.3.1`, `v5.0.0-7.3.2`). Logout, expiry,
|
|
309
|
+
account disablement, and revocation must prevent reuse, not merely delete the
|
|
310
|
+
browser cookie.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## REST / GraphQL APIs / Identity
|
|
315
|
+
|
|
316
|
+
- **Authorization**: enforce RBAC/ABAC in the backend for every operation,
|
|
317
|
+
object, and field; deny by default and test horizontal and vertical access.
|
|
318
|
+
Hiding buttons is not authorization.
|
|
319
|
+
- **Rate limits and schemas**: limit by user, credential, and operation, not
|
|
320
|
+
only by IP; validate payloads against OpenAPI/JSON Schema and impose size,
|
|
321
|
+
depth, pagination, and time limits.
|
|
322
|
+
- **Service-to-service communication**: use workload identities, short-lived
|
|
323
|
+
tokens, or least-privilege certificates. Avoid shared static credentials
|
|
324
|
+
(`v5.0.0-13.2.1`). Use mTLS or message signing when the risk analysis
|
|
325
|
+
requires it.
|
|
326
|
+
|
|
327
|
+
### OAuth 2.0 and OpenID Connect
|
|
328
|
+
|
|
329
|
+
- Use **Authorization Code + PKCE** with `S256` for public and confidential
|
|
330
|
+
clients. Bind `code_verifier`, `state`, and, for OIDC, `nonce` to the
|
|
331
|
+
initiating transaction and session; each value is unpredictable and
|
|
332
|
+
single-use (`v5.0.0-10.1.2`, `v5.0.0-10.2.1`,
|
|
333
|
+
`v5.0.0-10.5.1`).
|
|
334
|
+
- Compare redirect URIs with the registered allowlist by exact string; do not
|
|
335
|
+
use wildcards, prefixes, or open redirectors (`v5.0.0-10.4.1`). Validate the
|
|
336
|
+
expected issuer and protect multi-issuer clients against mix-up.
|
|
337
|
+
- At the authorization server, issue short-lived, single-use authorization
|
|
338
|
+
codes. Reject a second exchange of the same code and revoke tokens already
|
|
339
|
+
issued from it; limit lifetime to at most 10 minutes at L1/L2 and 1 minute at
|
|
340
|
+
L3 (`v5.0.0-10.4.2`, `v5.0.0-10.4.3`).
|
|
341
|
+
- Authenticate every confidential client on backchannel requests to the
|
|
342
|
+
authorization server, including the token endpoint, PAR, and revocation
|
|
343
|
+
(`v5.0.0-10.4.10`, L2). PKCE binds the transaction to the `code_verifier`,
|
|
344
|
+
but it **does not replace** confidential-client authentication.
|
|
345
|
+
- Identify and link an OIDC account only by the stable (`iss`, `sub`) pair;
|
|
346
|
+
validate that `sub` is valid in that issuer's context. Never use email or an
|
|
347
|
+
isolated `sub` as an identity key across issuers (`v5.0.0-10.5.2`, L2).
|
|
348
|
+
- Do not use the implicit grant (`response_type=token`) or Resource Owner
|
|
349
|
+
Password Credentials/password grant. Tokens leave through the token
|
|
350
|
+
endpoint, never through a front-channel URL. Restrict scopes and audiences
|
|
351
|
+
to the minimum required.
|
|
352
|
+
|
|
353
|
+
### JWTs, revocation, and refresh tokens
|
|
354
|
+
|
|
355
|
+
- Allowlist algorithms per context and reject `none`; prefer only symmetric
|
|
356
|
+
**or** only asymmetric algorithms in each context. If both are unavoidable,
|
|
357
|
+
explicitly separate keys, configuration, and validation paths to prevent
|
|
358
|
+
key/algorithm confusion (`v5.0.0-9.1.2`).
|
|
359
|
+
- Bind every key to exactly one allowed algorithm and confirm that the received
|
|
360
|
+
`alg` matches the operation performed. Validate the signature/MAC before
|
|
361
|
+
claims and obtain keys only from trusted issuer configuration; headers such
|
|
362
|
+
as `jku`, `x5u`, and `jwk` must not select an arbitrary source or key
|
|
363
|
+
(`v5.0.0-9.1.1` through `v5.0.0-9.1.3`; RFC 8725 §3.1).
|
|
364
|
+
- Validate token type and purpose, `iss`, `aud`, `exp`, and `nbf`, with minimal,
|
|
365
|
+
explicit clock skew (`v5.0.0-9.2.1` through `v5.0.0-9.2.3`). Do not use an
|
|
366
|
+
ID Token as an access token.
|
|
367
|
+
- For replay-sensitive operations, validate a unique identifier/`jti` and use
|
|
368
|
+
state, or adopt sender-constrained tokens (mTLS/DPoP). Short expiration
|
|
369
|
+
reduces the window but does not detect replay by itself.
|
|
370
|
+
- Plan revocation: reference tokens can use **token introspection**;
|
|
371
|
+
self-contained JWTs require a denylist, a per-user key/version, or a cutoff
|
|
372
|
+
timestamp. On logout, incident, or loss of authorization, invalidate the
|
|
373
|
+
corresponding state (`v5.0.0-7.4.1`).
|
|
374
|
+
- Refresh tokens are rotated and protected like credentials. On every
|
|
375
|
+
exchange, invalidate the previous one; reuse of an already rotated token
|
|
376
|
+
revokes the family, terminates the session, and raises an alert. For public
|
|
377
|
+
clients, use rotation or sender constraint as required by RFC 9700.
|
|
378
|
+
|
|
379
|
+
### GraphQL
|
|
380
|
+
|
|
381
|
+
Enforce authorization at every resolver/operation/field, validate input,
|
|
382
|
+
limit depth, quantity, batching, and cost (`v5.0.0-4.3.1`), and apply timeouts
|
|
383
|
+
and rate limits. Disabling or restricting **introspection** can reduce schema
|
|
384
|
+
exposure where it is not public (`v5.0.0-4.3.2`), but it is optional hardening
|
|
385
|
+
only: it replaces neither authorization nor anti-abuse controls, and fields
|
|
386
|
+
can still be guessed. Keep it when the public contract requires it and protect
|
|
387
|
+
data independently of that choice.
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## Database
|
|
392
|
+
|
|
393
|
+
- Always use **parameterized queries/prepared statements** — never concatenate strings with user input (protection against SQL Injection).
|
|
394
|
+
- **Least privilege**: the application user in the database must not have `DROP`/`ALTER` permission or access to unused schemas; the migration user is separate from the runtime user.
|
|
395
|
+
- **Encryption at rest** for sensitive data (PII, payment data) through native database encryption (TDE) or at the column/field level.
|
|
396
|
+
- **Encrypted backups** tested periodically (restore drill).
|
|
397
|
+
- **Connection secrets** (connection string, password) outside the code, through a secret manager or an environment variable injected at runtime.
|
|
398
|
+
- Audit access to sensitive tables (logs of who accessed customer data).
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## Cryptography and passwords
|
|
403
|
+
|
|
404
|
+
- **Passwords**: use **Argon2id** first and calibrate memory, iterations, and
|
|
405
|
+
parallelism on production hardware to retain defensive cost without causing
|
|
406
|
+
DoS. If unavailable, use scrypt; keep bcrypt for legacy only, accounting for
|
|
407
|
+
its input limit; use PBKDF2 when FIPS requires it. Store the algorithm and
|
|
408
|
+
parameters with the hash and rehash after authentication when policy evolves
|
|
409
|
+
(`v5.0.0-11.4.2`).
|
|
410
|
+
- **Data at rest**: prefer AEAD, such as AES-GCM or
|
|
411
|
+
**ChaCha20-Poly1305**, through a high-level API. Never reuse a nonce with the
|
|
412
|
+
same key; authenticate relevant metadata as AAD and fail closed on tag
|
|
413
|
+
failure. Do not use ECB, unauthenticated encryption, or keys derived by a
|
|
414
|
+
fast hash (`v5.0.0-11.3.1` through `v5.0.0-11.3.3`). Specific evidence of
|
|
415
|
+
nonce generation and uniqueness is L3 (`v5.0.0-11.3.4`).
|
|
416
|
+
- **Keys**: generate with a CSPRNG, separate by environment and purpose, store
|
|
417
|
+
in an appropriate KMS/HSM/Keystore, restrict access, and document generation,
|
|
418
|
+
activation, rotation, revocation, backup, and destruction. Never log a key
|
|
419
|
+
or plaintext.
|
|
420
|
+
- **Algorithm agility**: maintain an inventory of algorithms, keys, and
|
|
421
|
+
certificates, a versioned format, and a tested path to change algorithms,
|
|
422
|
+
parameters, and keys and to re-encrypt data (`v5.0.0-11.1.2`,
|
|
423
|
+
`v5.0.0-11.2.1`, `v5.0.0-11.2.2`). Agility does not mean accepting an
|
|
424
|
+
attacker-selected algorithm.
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Infrastructure, DevOps, and CI/CD
|
|
429
|
+
|
|
430
|
+
### Secrets and workload identities
|
|
431
|
+
|
|
432
|
+
- Centralize secrets in an appropriate service; separate
|
|
433
|
+
dev/test/staging/prod, enforce least privilege, and prefer workload
|
|
434
|
+
identities, OIDC federation, certificates, or short-lived dynamic
|
|
435
|
+
credentials to static keys (`v5.0.0-13.2.1`, `v5.0.0-13.3.1`).
|
|
436
|
+
- Run secret scanning in the IDE or **pre-commit**, block in CI/PR, and
|
|
437
|
+
periodically scan all Git history, artifacts, images, and logs. Use
|
|
438
|
+
recognizable fake values in examples and tests; do not rely only on regexes
|
|
439
|
+
or log redaction.
|
|
440
|
+
- Track the owner, consumers, environment, purpose, expiry, and rotation
|
|
441
|
+
schedule. Audit reads, changes, failures, and anomalous use without logging
|
|
442
|
+
the value; test rotation and revocation without downtime.
|
|
443
|
+
- On exposure, treat it as an incident: contain, **revoke first**, rotate every
|
|
444
|
+
dependent, investigate logs/artifacts/clones, notify owners, and document the
|
|
445
|
+
cause. Deleting the file or making another commit does not invalidate the
|
|
446
|
+
secret.
|
|
447
|
+
- Remove a value from Git history only after revocation and coordinated impact
|
|
448
|
+
analysis; rewriting affects SHAs, branches, forks, and clones and requires
|
|
449
|
+
communication plus reintroduction prevention. Treat the secret as
|
|
450
|
+
compromised even after cleanup.
|
|
451
|
+
|
|
452
|
+
### Supply chain and promotion
|
|
453
|
+
|
|
454
|
+
- Use lockfiles and allowlisted, trusted registries/proxies. Reserve internal
|
|
455
|
+
namespaces and names, configure explicit scopes, and verify the origin of
|
|
456
|
+
direct and transitive dependencies to prevent **dependency confusion**
|
|
457
|
+
(`v5.0.0-15.1.2`, `v5.0.0-15.2.4`).
|
|
458
|
+
- Pin GitHub Actions and reusable workflows to a full commit; pin plugins and
|
|
459
|
+
tools to an immutable version or verified digest as supported by their
|
|
460
|
+
ecosystem, and pin images/artifacts by digest. Mutable tags and branches are
|
|
461
|
+
not identity evidence. Automate update proposals, but require review and run
|
|
462
|
+
with a minimal token.
|
|
463
|
+
- Generate SBOMs and provenance/attestations in the isolated builder; sign when
|
|
464
|
+
applicable and verify builder identity, source, commit, and digest before
|
|
465
|
+
deployment. A checksum from the same compromised channel is insufficient.
|
|
466
|
+
- Build once and promote the **same immutable artifact** between environments;
|
|
467
|
+
do not rebuild for production. Record approvals and associate release, SBOM,
|
|
468
|
+
attestation, tests, and configuration with the digest.
|
|
469
|
+
- Roll out gradually (canary/percentage), monitor technical and security
|
|
470
|
+
signals, provide automatic abort, and roll back to a previously verified
|
|
471
|
+
digest. Never “fix” production by modifying the running artifact.
|
|
472
|
+
|
|
473
|
+
### Pipeline verification
|
|
474
|
+
|
|
475
|
+
- Integrate SAST, SCA, secret scanning, IaC scanning, container scanning, and
|
|
476
|
+
DAST according to the architecture; critical failures block merge/deploy or
|
|
477
|
+
receive a time-bound exception with an owner and documented risk.
|
|
478
|
+
- Use ephemeral runners, branch protection, mandatory workflow review, minimum
|
|
479
|
+
permissions, and approved environments. Do not expose production secrets to
|
|
480
|
+
untrusted pull-request builds.
|
|
481
|
+
- Base images must be minimal, must not run as `root`, and must be rebuilt in a
|
|
482
|
+
controlled way when fixes arrive; verify signature/attestation at
|
|
483
|
+
admission/deploy, not only during the build.
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
## Mobile — OWASP Mobile Top 10:2024 and best practices
|
|
488
|
+
|
|
489
|
+
1. **M1 – Improper Credential Usage**: never hardcode API keys/secrets in the app binary (they can be extracted through reverse engineering); use the backend as a proxy for calls that require a secret.
|
|
490
|
+
2. **M2 – Inadequate Supply Chain Security**: audit third-party SDKs (analytics, ads) for permissions and collected data; pin dependency versions (lockfiles).
|
|
491
|
+
3. **M3 – Insecure Authentication/Authorization**: for remote or service-backed features, every authorization decision belongs at the backend/trusted service boundary; for local/offline authority, enforce the documented OS/process/container capability boundary. Use tokens with short expiration; biometrics (Face ID/Touch ID, BiometricPrompt) only as a *convenience* for accessing an already protected secret, never as the sole authentication factor for a backend.
|
|
492
|
+
4. **M4 – Insufficient Input/Output Validation**: validate all input (deep links, intents, forms) in the app and again at the applicable trusted service or local boundary.
|
|
493
|
+
5. **M5 – Insecure Communication**: HTTPS is mandatory (App Transport Security
|
|
494
|
+
on iOS, `usesCleartextTraffic=false` on Android); use platform TLS
|
|
495
|
+
validation. Pinning requires a threat model and operational plan.
|
|
496
|
+
6. **M6 – Inadequate Privacy Controls**: request only the necessary permissions (camera, location, contacts), explain the reason (App Tracking Transparency on iOS), and minimize personal-data collection.
|
|
497
|
+
7. **M7 – Insufficient Binary Protections**: code obfuscation (ProGuard/R8 on Android, symbol obfuscation on iOS), jailbreak/root detection for sensitive apps, and binary integrity verification.
|
|
498
|
+
8. **M8 – Security Misconfiguration**: disable debug/verbose logs in production builds, and remove test/staging endpoints from the published app.
|
|
499
|
+
9. **M9 – Insecure Data Storage**: never save sensitive data in plaintext in
|
|
500
|
+
`SharedPreferences`, `UserDefaults`, or flat files; use **Keychain** on iOS
|
|
501
|
+
and keys in the **Android Keystore**, with storage encryption appropriate
|
|
502
|
+
for the data.
|
|
503
|
+
10. **M10 – Insufficient Cryptography**: use native cryptographic APIs or a
|
|
504
|
+
maintained high-level library with authenticated encryption; never
|
|
505
|
+
implement a cipher.
|
|
506
|
+
|
|
507
|
+
### iOS — specific
|
|
508
|
+
|
|
509
|
+
- **Keychain Services** for tokens, passwords, and keys — never `UserDefaults` for sensitive data.
|
|
510
|
+
- **App Transport Security (ATS)** enabled (blocks insecure HTTP by default); exceptions only with documented justification.
|
|
511
|
+
- Prefer platform TLS validation; adopt pinning only after threat modeling,
|
|
512
|
+
with backup pins, expiry, telemetry, and tested recovery.
|
|
513
|
+
- Review `Info.plist` permissions (`NSCameraUsageDescription`, etc.) — request only what is necessary, with a clear description for the user.
|
|
514
|
+
- Use **Data Protection** (`NSFileProtectionComplete`) for sensitive files on disk.
|
|
515
|
+
|
|
516
|
+
### Android — specific
|
|
517
|
+
|
|
518
|
+
- Use the **Android Keystore System** to generate and retain non-exportable
|
|
519
|
+
keys, hardware/StrongBox-backed where available and necessary. Encrypt data
|
|
520
|
+
with AEAD and store only ciphertext in a file/database; Keystore stores the
|
|
521
|
+
key, not arbitrary data.
|
|
522
|
+
- Prefer platform TLS and Certificate Transparency. Android does not recommend
|
|
523
|
+
certificate pinning by default; use it only when the threat model outweighs
|
|
524
|
+
outage risk, with multiple backup pins (at least one under your control), a
|
|
525
|
+
short expiration, telemetry, recovery, and tested updates. Never implement a
|
|
526
|
+
`TrustManager` that accepts every certificate.
|
|
527
|
+
- `EncryptedSharedPreferences` is deprecated. Retain it only during
|
|
528
|
+
legacy/migration work with a removal plan and verified backup rules; do not
|
|
529
|
+
recommend it for new code and never put secrets in plain
|
|
530
|
+
`SharedPreferences`.
|
|
531
|
+
- Use **Network Security Config** for cleartext policy and trusted CAs.
|
|
532
|
+
Certificate Transparency is unavailable through API 35; it is opt-in on API
|
|
533
|
+
36 and enabled by default on API 37+, unless an exception is configured. Set
|
|
534
|
+
pins only when exceptionally approved.
|
|
535
|
+
- **ProGuard/R8** for obfuscation and removal of unused code in release builds.
|
|
536
|
+
- Be careful with **implicit Intents** and **Deep Links** — validate the origin and sanitize data received through `Intent`/`Deep Link`; never trust them as a secure source.
|
|
537
|
+
- `android:exported="false"` on components (Activities/Services/Receivers) that do not need to be accessed by other apps.
|
|
538
|
+
- Check **runtime permissions** with the minimum necessary and an explanation for the user.
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
## Desktop — Windows and macOS
|
|
543
|
+
|
|
544
|
+
### Windows
|
|
545
|
+
|
|
546
|
+
- **DPAPI (Data Protection API)** or **Windows Credential Manager** to store local secrets (never in plain-text configuration files).
|
|
547
|
+
- **Code signing** with a valid certificate — unsigned builds trigger SmartScreen/Defender alerts.
|
|
548
|
+
- Run with the lowest possible privilege; avoid requiring administrator elevation unless strictly necessary (UAC).
|
|
549
|
+
- Validate update integrity (digital signature) before applying updates — never download/execute a binary without verification.
|
|
550
|
+
- Sandboxing where possible (**AppContainer**, MSIX with restricted capabilities).
|
|
551
|
+
|
|
552
|
+
### macOS
|
|
553
|
+
|
|
554
|
+
- **Keychain Services** (the same conceptual API as iOS) to store credentials and keys.
|
|
555
|
+
- **Apple notarization** and **code signing (codesign)** required for distribution outside the App Store without triggering Gatekeeper blocking.
|
|
556
|
+
- **App Sandbox** and **Hardened Runtime** enabled, requesting only the necessary *entitlements* (network, camera, file access).
|
|
557
|
+
- Never disable **App Transport Security**/TLS validation to "make" production debugging easier.
|
|
558
|
+
- Validate the integrity of auto-updates (e.g., **Sparkle** framework) with an EdDSA signature before installing.
|
|
559
|
+
|
|
560
|
+
### Common rules (Windows + macOS)
|
|
561
|
+
|
|
562
|
+
- Never store passwords, tokens, or API keys in plain-text configuration files (`.ini`, `.json`, `.xml`) in the user directory — use the OS's native credential vault.
|
|
563
|
+
- Every auto-update channel must use HTTPS + package signature verification before installation.
|
|
564
|
+
- Minimize permissions requested from the OS (file, network, automation access) and explain the reason to the user.
|
|
565
|
+
- Treat the user's machine as an untrusted environment: any secret embedded in the binary can be extracted by a user with local privileges.
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
## Cross-cutting: Hybrid and cross-platform apps (Electron, React Native, Flutter, .NET MAUI)
|
|
570
|
+
|
|
571
|
+
- **Electron**: keep `nodeIntegration: false` and `contextIsolation: true` in `BrowserWindow`; use `preload` scripts with explicitly exposed APIs (`contextBridge`); update Electron/Chromium frequently (browser vulnerabilities affect the entire app).
|
|
572
|
+
- **React Native**: follow the same secure-storage rules as native mobile (use `react-native-keychain`, not plain `AsyncStorage` for secrets); validate deep links.
|
|
573
|
+
- **Flutter**: use `flutter_secure_storage` (which uses Keychain/Keystore underneath) instead of `shared_preferences` for sensitive data.
|
|
574
|
+
- In all cases: sensitive business logic and API secrets must never live only on the client. Remote or service-backed authority requires a trusted server-side or serverless enforcement boundary; local/offline authority requires the documented OS/process/container boundary, protected local storage/Keychain/credential vault, and integrity, confidentiality, and capability controls.
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
578
|
+
## Instruction template for inclusion in CLAUDE.md / AGENTS.md
|
|
579
|
+
|
|
580
|
+
```
|
|
581
|
+
## Security
|
|
582
|
+
|
|
583
|
+
- Web/API baseline: OWASP ASVS 5.0.0 L1; use L2 for sensitive applications.
|
|
584
|
+
Record the requirement, evidence, and exception, not only a scanner result.
|
|
585
|
+
- Never commit secrets (keys, passwords, tokens, certificates). Use a secret
|
|
586
|
+
manager and short-lived identity. Scan pre-commit, CI, and history.
|
|
587
|
+
- All client and externally supplied input is untrusted: validate and sanitize
|
|
588
|
+
it at the trusted service boundary or, for local/offline paths, at the
|
|
589
|
+
documented OS/process/container/storage boundary, even if the frontend/app
|
|
590
|
+
already validated it.
|
|
591
|
+
- Every outbound URL uses an exact allowlist, blocks non-global/metadata
|
|
592
|
+
networks and DNS rebinding, and revalidates redirects; set timeouts/limits.
|
|
593
|
+
- Uploads use generated names, validate type/content and post-decompression
|
|
594
|
+
size, stay outside the webroot, and are downloaded only after authorization.
|
|
595
|
+
- Every database query uses parameters/prepared statements or an ORM.
|
|
596
|
+
Never concatenate SQL strings.
|
|
597
|
+
- Enforce every authorization decision at the appropriate trusted boundary: a
|
|
598
|
+
service boundary for remote authority or a documented OS/process/container
|
|
599
|
+
capability boundary for local/offline authority. Never trust
|
|
600
|
+
roles/permissions sent by the client.
|
|
601
|
+
- Passwords: calibrated Argon2id; scrypt fallback, bcrypt legacy, PBKDF2/FIPS.
|
|
602
|
+
Data: AEAD AES-GCM/ChaCha20-Poly1305 through a high-level library.
|
|
603
|
+
- Cookies: __Host- + Path=/ + HttpOnly + Secure + SameSite=Lax/Strict;
|
|
604
|
+
document SameSite=None. Apply idle/absolute timeouts and rotation.
|
|
605
|
+
- Deploy CSP through Report-Only/reporting. Stage HSTS; never enable
|
|
606
|
+
includeSubDomains/preload without an inventory and explicit decision.
|
|
607
|
+
- OAuth/OIDC: Authorization Code + PKCE S256, state, nonce, exact redirect;
|
|
608
|
+
short/single-use code and confidential-client authentication. PKCE does not
|
|
609
|
+
replace it; OIDC accounts use (iss, sub), never email or isolated sub.
|
|
610
|
+
- JWT: one symmetric or asymmetric family per context; every key belongs to
|
|
611
|
+
one algorithm. Separate keys/config/paths if both are unavoidable.
|
|
612
|
+
- Dependencies: run vulnerability audits (npm audit, pip-audit,
|
|
613
|
+
govulncheck, dotnet list package --vulnerable) and resolve high-severity
|
|
614
|
+
issues; pin actions by commit and plugins/artifacts by an immutable version
|
|
615
|
+
or verified digest.
|
|
616
|
+
- Mobile: sensitive data only in Keychain (iOS) or encrypted with a key in
|
|
617
|
+
Keystore (Android). EncryptedSharedPreferences is legacy/migration only.
|
|
618
|
+
- Desktop: secrets only in the OS's native credential vault (DPAPI/Credential
|
|
619
|
+
Manager on Windows, Keychain on macOS). Never in a flat config file.
|
|
620
|
+
- Logs never contain passwords, complete tokens, card data, or PII in
|
|
621
|
+
plain text.
|
|
622
|
+
- Every new feature that handles sensitive data (login, payment,
|
|
623
|
+
upload, permissions) receives a threat review before implementation.
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
## Security Review Checklist
|
|
629
|
+
|
|
630
|
+
- [ ] Scope, ASVS 5.0.0 level (L1 or L2), exceptions, and evidence are
|
|
631
|
+
recorded; the Top 10 was not used as a replacement checklist.
|
|
632
|
+
- [ ] Untrusted input is validated and authorization is enforced at the
|
|
633
|
+
appropriate trusted boundary: a server/service for remote or service-backed
|
|
634
|
+
authority, or the documented OS/process/container/storage boundary for
|
|
635
|
+
local/offline authority; SQL is parameterized (`v5.0.0-2.2.2`,
|
|
636
|
+
`v5.0.0-8.3.1`, `v5.0.0-1.2.4`).
|
|
637
|
+
- [ ] SSRF cases cover allowlists, non-global/metadata IPs, DNS rebinding,
|
|
638
|
+
redirects, timeouts, and limits (`v5.0.0-1.3.6`).
|
|
639
|
+
- [ ] Uploads cover generated names, type/content, post-decompression limits,
|
|
640
|
+
private storage, applicable AV/CDR, and authorized download (ASVS 5.0.0,
|
|
641
|
+
V5.1–V5.4).
|
|
642
|
+
- [ ] CSP passed through `Report-Only`, CORS matches an exact origin and sends
|
|
643
|
+
`Vary: Origin`, and HSTS shipped without automatic preload (ASVS 5.0.0,
|
|
644
|
+
V3.4).
|
|
645
|
+
- [ ] The `__Host-` cookie and session lifecycle were tested for SameSite,
|
|
646
|
+
rotation, idle/absolute timeout, logout, and revocation (ASVS 5.0.0, V3.3
|
|
647
|
+
and V7).
|
|
648
|
+
- [ ] OAuth/OIDC uses Code + PKCE, `state`, `nonce`, and exact redirects; JWTs
|
|
649
|
+
and refresh tokens have validation, replay, rotation, and revocation tests.
|
|
650
|
+
Short/single-use codes, confidential-client backchannel authentication, and
|
|
651
|
+
(`iss`, `sub`) OIDC accounts are verified (ASVS 5.0.0, V9/V10).
|
|
652
|
+
- [ ] JWT separates symmetric/asymmetric algorithms by context and binds each
|
|
653
|
+
key to one algorithm; any exception separates keys, configuration, and
|
|
654
|
+
paths (`v5.0.0-9.1.1` through `v5.0.0-9.1.3`).
|
|
655
|
+
- [ ] Secret scanning covers pre-commit, CI, and history; exposure has a
|
|
656
|
+
revocation, rotation, audit, and Git remediation playbook (ASVS 5.0.0,
|
|
657
|
+
V13.3).
|
|
658
|
+
- [ ] Dependencies come from a trusted registry; actions use full commits,
|
|
659
|
+
plugins/artifacts use an immutable version or verified digest, provenance is
|
|
660
|
+
verified, and dependency confusion is tested.
|
|
661
|
+
- [ ] Passwords use Argon2id/scrypt or a documented exception; data uses AEAD,
|
|
662
|
+
and there is a cryptographic inventory/agility plan (ASVS 5.0.0, V11).
|
|
663
|
+
- [ ] Android uses Keystore and platform TLS; any pinning has a threat model,
|
|
664
|
+
backups, expiration, telemetry, and recovery. Legacy
|
|
665
|
+
`EncryptedSharedPreferences` has a migration.
|
|
666
|
+
- [ ] GraphQL enforces authorization and anti-abuse independently of
|
|
667
|
+
introspection (`v5.0.0-4.3.1`, `v5.0.0-4.3.2`).
|
|
668
|
+
- [ ] Logs and alerts prove security events without exposing secrets or PII;
|
|
669
|
+
code, dependency, IaC, image, and runtime scans have a failure policy.
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
673
|
+
## Sources and References
|
|
674
|
+
|
|
675
|
+
- OWASP ASVS 5.0.0: https://owasp.org/www-project-application-security-verification-standard/
|
|
676
|
+
- Official OWASP ASVS 5.0.0 CSV: https://github.com/OWASP/ASVS/raw/v5.0.0/5.0/docs_en/OWASP_Application_Security_Verification_Standard_5.0.0_en.csv
|
|
677
|
+
- OWASP Top 10:2025 (Web): https://owasp.org/Top10/2025/
|
|
678
|
+
- OWASP Mobile Top 10:2024: https://owasp.org/www-project-mobile-top-10/
|
|
679
|
+
- OWASP Mobile Application Security Verification Standard (MASVS) / MASTG: https://owasp.org/www-project-mobile-app-security/
|
|
680
|
+
- OWASP Cheat Sheet Series: https://cheatsheetseries.owasp.org/
|
|
681
|
+
- OWASP SSRF Prevention: https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
|
|
682
|
+
- OWASP File Upload: https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html
|
|
683
|
+
- OWASP Content Security Policy: https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html
|
|
684
|
+
- OWASP HTTP Strict Transport Security: https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Strict_Transport_Security_Cheat_Sheet.html
|
|
685
|
+
- OWASP HTTP Headers: https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html
|
|
686
|
+
- OWASP Session Management: https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
|
|
687
|
+
- OWASP Password Storage: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
|
|
688
|
+
- OWASP Cryptographic Storage: https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html
|
|
689
|
+
- OWASP OAuth2: https://cheatsheetseries.owasp.org/cheatsheets/OAuth2_Cheat_Sheet.html
|
|
690
|
+
- OWASP GraphQL: https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html
|
|
691
|
+
- OWASP Secrets Management: https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html
|
|
692
|
+
- OWASP Software Supply Chain Security: https://cheatsheetseries.owasp.org/cheatsheets/Software_Supply_Chain_Security_Cheat_Sheet.html
|
|
693
|
+
- OWASP GitHub Actions Security: https://cheatsheetseries.owasp.org/cheatsheets/GitHub_Actions_Security_Cheat_Sheet.html
|
|
694
|
+
- Android TLS and certificate pinning: https://developer.android.com/privacy-and-security/security-ssl
|
|
695
|
+
- Android Network Security Config and Certificate Transparency: https://developer.android.com/privacy-and-security/security-config
|
|
696
|
+
- Android cryptography and Keystore: https://developer.android.com/privacy-and-security/cryptography
|
|
697
|
+
- Android `EncryptedSharedPreferences` (deprecated): https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences
|
|
698
|
+
- OAuth 2.0 Security Best Current Practice, RFC 9700: https://www.rfc-editor.org/rfc/rfc9700
|
|
699
|
+
- JWT Best Current Practices, RFC 8725: https://www.rfc-editor.org/rfc/rfc8725
|
|
700
|
+
- Web Origin, RFC 6454: https://www.rfc-editor.org/rfc/rfc6454
|
|
701
|
+
- OAuth 2.0 Token Introspection, RFC 7662: https://www.rfc-editor.org/rfc/rfc7662
|
|
702
|
+
- ChaCha20-Poly1305, RFC 8439: https://www.rfc-editor.org/rfc/rfc8439
|
|
703
|
+
- GitHub Actions: use full-length commit SHA: https://docs.github.com/en/actions/reference/security/secure-use
|
|
704
|
+
- GitHub artifact attestations: https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/use-artifact-attestations
|
|
705
|
+
- Apple Platform Security Guide: https://support.apple.com/guide/security/
|
|
706
|
+
- Microsoft Security Development Lifecycle (SDL): https://www.microsoft.com/sdl
|