Security: Admin feature flag updates lack cross-User classification #1297

Open
opened 2026-10-07 01:59:49 +00:00 by kayg · 2 comments
Owner

Severity: minor (security test coverage; no authorization bypass found).

Defensive test steps:

  1. Use origin/dev 3601719b80.
  2. Run XUSER_CLASSIFY_ONLY=1 python3 tests/adversarial/xuser_matrix.py. No credentials or server are needed.

Expected: each route has an explicit identifier meaning before live fixtures are created.

Actual: the gate stops with OpenAPI path ID has no resource classification: PUT /api/v1/admin/features/{id} (admin_feature_flag_put).

The Admin role policy is present and agrees with the Rust guard. The missing part is the cross-User path identifier class for the Instance feature flag key. This prevents the defensive runner from reaching its live checks.

Evidence: artifacts/bash-security/findings.md. Found after the required origin/dev merge on job/bash-security. Add an explicit Instance-level flag classification and a regression check. Do not treat the flag key as a User-owned UUID.

Severity: minor (security test coverage; no authorization bypass found). Defensive test steps: 1. Use origin/dev 3601719b80a39f712daf07b37879b22929dfffa0. 2. Run `XUSER_CLASSIFY_ONLY=1 python3 tests/adversarial/xuser_matrix.py`. No credentials or server are needed. Expected: each route has an explicit identifier meaning before live fixtures are created. Actual: the gate stops with `OpenAPI path ID has no resource classification: PUT /api/v1/admin/features/{id} (admin_feature_flag_put)`. The Admin role policy is present and agrees with the Rust guard. The missing part is the cross-User path identifier class for the Instance feature flag key. This prevents the defensive runner from reaching its live checks. Evidence: artifacts/bash-security/findings.md. Found after the required origin/dev merge on job/bash-security. Add an explicit Instance-level flag classification and a regression check. Do not treat the flag key as a User-owned UUID.
Author
Owner

Fixed on branch in 23418ea5c: explicit Instance feature-key classification and fresh-Admin policy regression, plus direct cookie-origin and three-User/anonymous denial cases. The source catalog is empty at the merged revision, so positive writes to a real active flag are not available; the live probe will check valid-body unknown-key refusal and every real key if a future catalog contains one. Focused regression: Ran 1 test in 0.059s; OK.

Fixed on branch in 23418ea5c: explicit Instance feature-key classification and fresh-Admin policy regression, plus direct cookie-origin and three-User/anonymous denial cases. The source catalog is empty at the merged revision, so positive writes to a real active flag are not available; the live probe will check valid-body unknown-key refusal and every real key if a future catalog contains one. Focused regression: Ran 1 test in 0.059s; OK.
Author
Owner

Consistency hunt on origin/dev 3601719b80a39f712daf07b37879b22929dfffa0 (2026-10-07): I ran XUSER_MATRIX_ONLY=1 ADVERSARIAL_SKIP_WEB_BUILD=1 ADVERSARIAL_SERVER_BIN=/home/kayg/build/targets/hunt-20261006/debug/calternal-server tests/adversarial/run.sh. The runner stopped in its classify-only preflight, before it started a server, with OpenAPI path ID has no resource classification: PUT /api/v1/admin/features/{id} (admin_feature_flag_put). This is the existing gap from #1297; the live two-User checks did not run, so this provides no new isolation verdict or leak result. I left the classifier and route behavior unchanged in this audit job.

Consistency hunt on origin/dev `3601719b80a39f712daf07b37879b22929dfffa0` (2026-10-07): I ran `XUSER_MATRIX_ONLY=1 ADVERSARIAL_SKIP_WEB_BUILD=1 ADVERSARIAL_SERVER_BIN=/home/kayg/build/targets/hunt-20261006/debug/calternal-server tests/adversarial/run.sh`. The runner stopped in its classify-only preflight, before it started a server, with `OpenAPI path ID has no resource classification: PUT /api/v1/admin/features/{id} (admin_feature_flag_put)`. This is the existing gap from #1297; the live two-User checks did not run, so this provides no new isolation verdict or leak result. I left the classifier and route behavior unchanged in this audit job.
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal-v0#1297
No description provided.