Skip to content

Commit 2436a8f

Browse files
committed
docs: finalize v2.1.2 security verification
1 parent 81d17b3 commit 2436a8f

3 files changed

Lines changed: 45 additions & 6 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,17 @@ All notable changes are recorded here. The project follows semantic versioning.
9999
Composer/npm or vendored dependencies, and outdated PHP, OpenSSL, curl,
100100
SQLite, and libxml2 runtime packages in the review environment were updated
101101
with the backend regression suite passing afterwards.
102+
- Completed the v2.1.2 static security analysis and remediated, documented,
103+
or accepted findings SSA-01 through SSA-12: deny-by-default routine and
104+
query-source registries (reconciled with the sources used by the frontend),
105+
Admin-only setup and identity/API-key/role management, registered-source
106+
checks for SQL Resource runtime filters, production ODBC Driver 18/17
107+
transport hardening and warnings, a `GENERIC_MAX_RESULT_ROWS` limit for
108+
unpaginated reads, Windows PHP runtime provenance and checksums, and security
109+
regression coverage. The exposed administrator credential (SSA-05) was
110+
rotated and verified to no longer match the historical hash. Authored SQL
111+
Resource SQL is not validated table by table, and SSA-13 through SSA-20
112+
remain deferred.
102113

103114
## [1.0.0] - Initial release
104115

‎docs/Roadmap.md‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,10 +395,26 @@ the development/security-review environment were updated and the backend
395395
regression suite passed. See the
396396
[Dependency security review](security/Dependency-Security-Review.md).
397397

398+
## v2.1.2 — Static Security Analysis
399+
400+
Status: Completed
401+
402+
A manual static review of the backend, Admin Console, SQL Parser, deployment
403+
templates, and repository history found 20 findings (SSA-01 – SSA-20). The
404+
approved remediation scope, SSA-01 – SSA-12, is complete: deny-by-default
405+
routine and query-source registries, public-API removal of setup and identity
406+
management, SQL Resource runtime-filter source checks, production ODBC
407+
transport hardening, an unpaginated result-row limit, regression coverage, and
408+
documented or accepted limitations. The exposed administrator credential
409+
(SSA-05) was rotated and verified. Authored SQL Resource SQL is not validated
410+
table by table, the widget SQL Resources referenced by the frontend but absent
411+
from the backend remain unresolved, and SSA-13 – SSA-20 are deferred. See the
412+
[Static security analysis inventory](security/Static-Security-Analysis-Inventory.md).
413+
398414
## Security Verification
399415

400416
- Dependency security review (completed in v2.1.1)
401-
- Static security analysis
417+
- Static security analysis (completed in v2.1.2)
402418
- Authorization security testing
403419
- API security testing
404420
- DAST / security scanning
@@ -574,6 +590,7 @@ consume this API.
574590
| v2.0.0 Production Hardening | Production Phases 1–5 and production documentation | Completed |
575591
| v2.1 | Security Verification & Operational Hardening | Planned |
576592
| v2.1.1 | Dependency Security Review | Completed |
593+
| v2.1.2 | Static Security Analysis | Completed |
577594
| v3.0 | Multi-Database Support | Planned |
578595
| v3.1 | Developer Experience & API Integration | Planned |
579596
| v4.0 | Backend Platform & Enterprise Capabilities | Planned / Uncommitted |

‎docs/security/Static-Security-Analysis-Inventory.md‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
# Static security analysis inventory (v2.1.2)
22

3-
Review status: **Remediation in progress — v2.1.2 not yet completed** — 2026-10-06
3+
Review status: **Completed** — 2026-10-06
44

55
This report records roadmap phase v2.1.2 (Static Security Analysis) of
66
[v2.1 — Security Verification & Operational Hardening](../Roadmap.md#v21--security-verification--operational-hardening).
77
The original read-only inventory is preserved below the
88
[remediation status](#remediation-status); findings whose analysis changed
9-
after deeper tracing carry a **Correction** note. Phase v2.1.2 stays open until
10-
the remaining operator action for SSA-05 is complete.
9+
after deeper tracing carry a **Correction** note. Phase v2.1.2 is complete:
10+
every finding in the approved remediation scope (SSA-01 – SSA-12) is fixed,
11+
documented, or accepted, and the SSA-05 operator action (credential rotation)
12+
was completed and verified on 2026-10-06. SSA-13 – SSA-20 remain deferred.
1113

1214
## Method and scope
1315

@@ -77,7 +79,7 @@ SSA-20. Deployment-dependent: SSA-08. No exploitable path: SSA-10.
7779
| SSA-02 | High | **Fixed** | `setup.createAdmin` removed from the public API (404). It runs only through the Admin API, where `LocalAdminMiddleware` requires loopback and `GENERIC_ADMIN_ENABLED=1`. Setup stays permanently unavailable after initialization; `setup.status` stays public. |
7880
| SSA-03 | Medium | **Implemented for the current enforcement boundary; frontend sources reconciled** | Deny-by-default `config/query-sources.php` + `QuerySourcePolicy`, enforced for every physical table/view of JSON Query Mode (source, join, subquery, union branch, CTE body) in `ScopedMetadataRepository`, for metadata listings, and for SQL Resource runtime source filters; CTE names stay local and must be plain identifiers. Authored SQL Resource SQL is not validated table by table. See [SSA-03 frontend source reconciliation](#ssa-03-frontend-source-reconciliation). |
7981
| SSA-04 | Medium | **Fixed** | `auth.users.*`, `auth.apiKeys.*`, and `auth.roles.list` removed from the public API (404) and served only by the loopback Admin API with the Admin flag. `auth.frontendUsers.*` is unchanged. |
80-
| SSA-05 | High | **Open — operator action** | The historical hash is identical to the current hash of an enabled System Administrator in the review installation, and both GitHub remotes are publicly readable. The administrator password must be rotated (and anywhere it was reused). Git history is not rewritten. See [SSA-05](#ssa-05--an-administrator-password-hash-is-present-in-pushed-git-history-medium). |
82+
| SSA-05 | High | **Cleared — credential rotated** | The affected System Administrator password was rotated through the Admin Console on 2026-10-06 and login with the new password was confirmed by the operator. A `hash_equals` comparison of the current stored hash for the same account against the historical hash returned no match; no other stored record matches it either. The historical hash remains in public Git history but no longer corresponds to the account's credential. Git history is not rewritten. See [SSA-05](#ssa-05--an-administrator-password-hash-is-present-in-pushed-git-history-medium). |
8183
| SSA-06 | Low | **Accepted limitation** | Documented in `docs/Limitations.md`; a regression test pins the current behavior (frontend access is not narrowed by SQL Resource scopes, backend roles are). |
8284
| SSA-07 | Low | **Fixed** | SQL Resource runtime filters resolve only against registered query sources; explicit `source`/`having` mappings must reference a registered top-level source (derived-table aliases are denied). |
8385
| SSA-08 | Low | **Documented** | `docs/Production-Security-and-Deployment.md` forbids same-host proxies in front of the loopback/`REMOTE_ADDR` gates. No proxy-header trust was added. |
@@ -265,7 +267,16 @@ warnings, literal edge cases, and the SSA-06 accepted limitation).
265267
matches the historical hash.
266268
- Git history is intentionally not rewritten: the hash is already public in
267269
clones and forks, and rotation is what removes the risk.
268-
- Status: open until rotation is confirmed.
270+
- Rotation completed (2026-10-06): the operator rotated the affected System
271+
Administrator password through the Admin Console and confirmed login with
272+
the new password. The current stored hash for the same account was then
273+
compared locally against the historical hash with `hash_equals`; the
274+
result was **no match** (and no other stored record matches it). Only the
275+
boolean result was produced; neither value was displayed or recorded.
276+
- Status: **Cleared — credential rotated.** The historical hash remains in
277+
public Git history, but it no longer corresponds to the account's
278+
credential. Any other system where the same password was reused is outside
279+
this repository and remains the operator's responsibility.
269280

270281
### SSA-06 — `frontend.read` skips SQL Resource scope checks (Low)
271282

0 commit comments

Comments
 (0)