| T-09-01-01 |
Elevation of Privilege |
GET /api/admin/overview |
mitigate |
_admin: User = Depends(get_current_admin) raises 401/403 for non-admin tokens; covered by test_overview_requires_admin + test_overview_non_admin_forbidden |
closed |
| T-09-01-02 |
Information Disclosure |
GET /api/admin/overview response |
mitigate |
Hand-rolled dict with only aggregate counts + whitelisted _audit_to_dict_with_handles rows; no password_hash/credentials_enc/extracted_text/totp_secret/api_key_enc ever serialized; covered by test_overview_no_sensitive_fields |
closed |
| T-09-01-03 |
Tampering |
_build_filtered_query_with_handles import |
accept |
Cross-module import from sibling api/audit.py is a stable existing helper already security-audited and tested; risk accepted because an ImportError fails loud on startup |
closed |
| T-09-02-01 |
Information Disclosure |
AdminOverviewView render |
accept |
Component renders only fields returned by backend; backend whitelist (T-09-01-02) is the authoritative gate; no v-html or innerHTML; Vue auto-escaping handles XSS |
closed |
| T-09-02-02 |
Elevation of Privilege |
AdminLayout shown to non-admin |
mitigate |
Router guard updated in 09-04 (to.matched.some(r => r.meta.requiresAdmin)) ensures layout never mounts for non-admin users |
closed |
| T-09-02-03 |
Spoofing |
Sidebar authStore.logout() |
accept |
Reuses existing logout flow audited in Phase 7.1; no new code path |
closed |
| T-09-03-01 |
Tampering |
Tab-to-view extraction |
mitigate |
Verbatim copy of template + script preserves behavior; npm run build catches resolution errors; line-count check ±10% verifies no accidental edits |
closed |
| T-09-03-02 |
Information Disclosure |
Orphaned emit handlers |
mitigate |
Action step audits every emit(...) for orphaned parent listeners and replaces them with direct re-fetches so no admin action silently no-ops |
closed |
| T-09-04-01 |
Elevation of Privilege |
beforeEach guard |
mitigate |
to.matched.some(r => r.meta.requiresAdmin) covers all child routes; backend get_current_admin deps on /api/admin/* are the authoritative second gate |
closed |
| T-09-04-02 |
Privilege Escalation |
LoginView ?redirect= query param |
mitigate |
D-08 puts role check FIRST; even ?redirect=/ for an admin routes through the D-09 guard — redirect manipulation cannot grant access to the wrong area |
closed |
| T-09-04-03 |
Information Disclosure |
Vite production build CSS purge |
mitigate |
Tailwind safelist covers sky (OneDrive) and amber (audit admin badge); build output confirms separate admin chunks; dynamic classes survive purge |
closed |
| T-09-04-04 |
Denial of Service |
D-09 admin redirect loop |
mitigate |
isAdminRoute short-circuit for /admin/* prevents admins on admin routes from being redirected back to /admin; auth-await before both guard branches prevents race on token refresh |
closed |
| T-09-05-01 |
Tampering |
Constraint comment erasure |
mitigate |
Explicit preservation list in purge task: NO-prefix invariants, HKDF domain separation, constant-time comparison, atomic UPDATE-RETURNING; grep assertions confirm anchor comments present post-purge |
closed |
| T-09-05-02 |
Denial of Service |
Accidental import removal during purge |
mitigate |
Post-purge python -c "from api.admin import router; …" import check run; full pytest -v is the second gate |
closed |
| T-09-05-03 |
Information Disclosure |
Comment leaking implementation details |
accept |
Purge removes more than it adds; no new comments introduced; existing WHY comments already reviewed in Phase 8 security agent runs |
closed |