jamesfredley opened a new pull request, #15664: URL: https://github.com/apache/grails-core/pull/15664
## Summary Adds an Apache Grails project threat model at the repository root, matching the section structure (§1-§15) and provenance-tagging discipline mandated by the ASF Security team's threat-model-producer rubric (public mirror: <https://gist.github.com/potiuk/da14a826283038ddfe38cc9fe6310573>). The document defines the *implicit contract* between the framework and its downstream users: - **What is in scope**: HTTP request ingress, controllers/interceptors, data binding, view rendering, codecs, GORM mapping integration, configuration loading, plugin/artefact discovery, compile-time AST transforms, and the `grails-shell-cli`. - **What is out**: interactive consoles (`grails-console`), the start.grails.org HTTP service, third-party plugins, scaffolded application output, build/CI hygiene, Spring/Hibernate/JDK internals, and side-channel attacks. - **What is claimed (§8)**: parameterized GORM queries, default GSP HTML encoding, tag-helper URL encoding, codecs, `useToken` CSRF, `bindable=false` enforcement, AST-transform input domain, configuration-load integrity, and bounded data-binding memory. - **What is disclaimed (§9)**: authentication/authorization, CSRF without `useToken`, XSS with codec disabled, HQL string concatenation, object-level authorization on guessable IDs, rate limiting, constant-time crypto, Groovy sandboxing, profile-JAR provenance, cross-tenant isolation, and transport security. False-friend properties (`@Secured`, `bindable=false`, `useToken`, `constraints {}`, GSP HTML comments, `grails.serverURL`) are called out separately - the rubric flags §9 as the highest-value section for integrators. - **Triage dispositions (§13)**: a closed set of nine outcomes (`VALID`, `VALID-HARDENING`, `OUT-OF-MODEL: trusted-input`, `OUT-OF-MODEL: adversary-not-in-scope`, `OUT-OF-MODEL: unsupported-component`, `OUT-OF-MODEL: non-default-build`, `BY-DESIGN: property-disclaimed`, `KNOWN-NON-FINDING`, `MODEL-GAP`), each citing the section that licenses it. ## Why The repository previously had only a disclosure-policy `SECURITY.md` (routes reporters to the ASF Security Team) and developer-facing guidance under `grails-doc/src/en/guide/security/`. Neither tells a triager or downstream integrator which threats the framework has taken on and which it has left to the application. Findings from SAST, fuzzers, and AI-assisted analyzers therefore lack a documented basis for closure - every report gets re-derived from scratch. This document fixes that. It also gives a downstream integrator the answer to "if I drop Grails into my system, which threats am I now responsible for, and which does the framework own?" ## Files added / changed - **`THREAT_MODEL.md`** (new, 501 lines) - the prose document. - **`threat-model.yaml`** (new) - machine-readable companion (§15), the suggested sidecar for automated triage tooling. Mirrors components, config knobs, entry points, properties, disclaimers, false friends, known non-findings, and disposition labels from the prose. - **`SECURITY.md`** - adds a one-paragraph cross-reference to `THREAT_MODEL.md`, per rubric §1. Existing security guidance in `grails-doc/src/en/guide/security/` is mined as the *(documented)* source-of-truth and back-mapped in Appendix A. Nothing in the existing documentation is dropped, weakened, or contradicted. ## Status: DRAFT This is a **draft-first** model in the rubric's sense (rubric §3.2). 22 open questions for the PMC are collected in §14, grouped into three waves of 3-7 questions each, and framed as proposed answers for the PMC to confirm, correct, or strike. Wave 1 covers scope and intended use - the load-bearing decisions for the rest of the document. Provenance count at draft: **46 documented / 0 maintainer / 58 inferred**. As maintainer answers land, `*(inferred)*` tags should be promoted to `*(maintainer)*` and the matching open questions removed. ## Review checklist - [ ] §2 component-family table - are the in/out-of-model assignments correct? Particularly `grails-console`, `grails-forge`, and `grails-test-examples` (all marked out of model). - [ ] §3 - is auth genuinely deferred to Spring Security plugin only, with no in-framework roadmap? - [ ] §5a - confirm `grails.views.default.codec=html` is the supported production posture (a deployment with codec disabled is then `OUT-OF-MODEL: non-default-build`). - [ ] §6 trust table - is any binding path that ignores `bindable=false` missing? - [ ] §8 properties - any property over- or under-claimed? - [ ] §9 false friends - the most consequential section for integrators. Additions welcome. - [ ] §11a known non-findings - SAST suppression input. Validate each entry. - [ ] §14 open questions - answer in waves; promote `*(inferred)*` -> `*(maintainer)*` as you go. ## Cross-references - Threat-model rubric: <https://gist.github.com/potiuk/da14a826283038ddfe38cc9fe6310573> - ASF Security index: <https://security.apache.org/projects/> - Existing security guide: [`grails-doc/src/en/guide/security/`](../tree/8.0.x/grails-doc/src/en/guide/security) ## Notes for the reviewer - The rubric forbids restating what code or README already says, forbids audit-style "we recommend" prose, and forbids build-hygiene checklists. This document tries to stay strictly inside that line; if any section drifts toward audit output, please flag. - The rubric requires every non-trivial claim to carry one of `*(documented)*` / `*(maintainer)*` / `*(inferred)*`. Do not strip these on accepting - they are the audit trail used when closing a report ("not a bug - §9, *(maintainer, 2026-01)*"). - The §13 disposition labels are intentionally taken verbatim from the rubric so cross-project triage uses the same vocabulary. Assisted-by: claude-code:claude-opus-4-7 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
