App password profile issuance returns 403 for the Owner #374

Open
opened 2026-09-28 20:38:26 +00:00 by kayg · 3 comments
Owner

Found during the single real-server adversarial round for motion-spring (#291) on 2026-09-28.

tests/adversarial/attack2.py::app_password_profile_probe issued a profile for the Owner's app password with POST /api/v1/auth/app-passwords/{id}/profiles. The probe expects HTTP 200 for the Owner, but received HTTP 403 and stopped the remaining profile endpoint checks.

This run did not include any generated password or token values in its report. The result needs a controlled reproduction because the adversarial server was under shared-host load. The profile setup flow was delivered under #318; this issue tracks the observed API response.

Found during the single real-server adversarial round for motion-spring (#291) on 2026-09-28. `tests/adversarial/attack2.py::app_password_profile_probe` issued a profile for the Owner's app password with `POST /api/v1/auth/app-passwords/{id}/profiles`. The probe expects HTTP 200 for the Owner, but received HTTP 403 and stopped the remaining profile endpoint checks. This run did not include any generated password or token values in its report. The result needs a controlled reproduction because the adversarial server was under shared-host load. The profile setup flow was delivered under #318; this issue tracks the observed API response.
Author
Owner

Finding on #374: profile issuance calls require_fresh(session.token_hash, User ID); it returns Forbidden (HTTP 403) after 300 seconds without a passkey assertion. The adversarial probe uses the setup installation session and does not refresh it before issuance. I am checking this on a fresh local server; no generated credential is logged.

Finding on #374: profile issuance calls require_fresh(session.token_hash, User ID); it returns Forbidden (HTTP 403) after 300 seconds without a passkey assertion. The adversarial probe uses the setup installation session and does not refresh it before issuance. I am checking this on a fresh local server; no generated credential is logged.
Author
Owner

#374 controlled result: the focused real-server app_profiles probe returned HTTP 200 for the Owner and zero findings on a newly issued installation session. The route explicitly requires a passkey assertion no older than 300 seconds; require_fresh returns HTTP 403 after that period. The campaign now refreshes the Owner installation and browser assertions immediately before profile issuance (a1fd2875). Rerun output: "owner installation and browser session assertions refreshed"; "server alive at end: True"; "==== ROUND 2 FINDINGS 0". One SLOW-only profile signing observation was 1.4 seconds. No authorization rule was weakened.

#374 controlled result: the focused real-server app_profiles probe returned HTTP 200 for the Owner and zero findings on a newly issued installation session. The route explicitly requires a passkey assertion no older than 300 seconds; require_fresh returns HTTP 403 after that period. The campaign now refreshes the Owner installation and browser assertions immediately before profile issuance (a1fd2875). Rerun output: "owner installation and browser session assertions refreshed"; "server alive at end: True"; "==== ROUND 2 FINDINGS 0". One SLOW-only profile signing observation was 1.4 seconds. No authorization rule was weakened.
Author
Owner

Final #374 finding from job/dedup-375 at f2c4cb39a0: On the quiet local server, the Owner created an app password, refreshed the Owner assertion, and POST /api/v1/auth/app-passwords/{id}/profiles returned HTTP 200. The campaign's prior 403 occurred after its assertion aged past the 300-second freshness window. tests/adversarial/attack2.py now refreshes the assertion immediately before this probe. No authorization code was changed. No generated password or token was printed. The clean branch was not rebuilt for a second live profile probe before the four-hour job limit; the earlier focused local-server probe passed.

Final #374 finding from job/dedup-375 at f2c4cb39a0e2c090b0cc3f725d1f2e0b6698beff: On the quiet local server, the Owner created an app password, refreshed the Owner assertion, and POST /api/v1/auth/app-passwords/{id}/profiles returned HTTP 200. The campaign's prior 403 occurred after its assertion aged past the 300-second freshness window. tests/adversarial/attack2.py now refreshes the assertion immediately before this probe. No authorization code was changed. No generated password or token was printed. The clean branch was not rebuilt for a second live profile probe before the four-hour job limit; the earlier focused local-server probe passed.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
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#374
No description provided.