Files
RenewCMS/features/user_response_field_hygiene.feature
T

62 lines
3.8 KiB
Gherkin

Feature: API responses never expose a user's secret fields
As the maintainer of RenewCMS
I want every HTTP response that includes user data to carry only public fields, never a
password hash, a verification or password-reset code hash, or their expiry timestamps
So that a bug, a future endpoint, or a client inspecting a response body can never recover a
credential or a still-valid reset/verification secret
Background:
Given the public shape of a user in any API response is exactly six fields: id, username,
email, is_verified, created_at and updated_at
And password, password_reset_code, verification_code, verification_expiration and
password_reset_expiration never appear in any response body, under any key name, regardless
of their value or whether they are set
Scenario: A successful verification response carries only public fields
Given a user repository containing user id 7, username "alice", email "alice@example.com",
is_verified false, whose stored VerificationCode is the bcrypt hash of "abc123" and whose
VerificationExpiration is one hour from now
And a valid jwt cookie for user id 7
When the client sends POST /v1/auth/verify with body {"code": "abc123"}
Then the response status is 200
And the response body is a JSON object with exactly the keys id, username, email,
is_verified, created_at and updated_at
And the response body does not contain the keys password, password_reset_code,
verification_code, verification_expiration or password_reset_expiration
And the response body's is_verified is true
Scenario: A rejected verification attempt never echoes any user field
Given a user repository containing user id 7, username "alice", is_verified false, whose
stored VerificationCode is the bcrypt hash of "abc123" and whose VerificationExpiration is
one hour from now
And a valid jwt cookie for user id 7
When the client sends POST /v1/auth/verify with body {"code": "wrong-code"}
Then the response status is 403
And the response body is the plain-text apperr.VerificationFailedErrorMessage, not JSON, and
contains no user field at all
Scenario: Registering while no verified account exists never echoes any user field
Given the user repository is empty
When the client sends POST /v1/auth/register with username "bob", password "hunter2example12",
email "bob@example.com"
Then the response status is 200
And the response body contains no key named password, password_reset_code,
verification_code, verification_expiration or password_reset_expiration
Scenario Outline: No other auth endpoint under /v1/auth leaks a user field
Given a user repository containing user id 7, username "alice", email "alice@example.com",
is_verified true, with a non-empty PasswordResetCode or VerificationCode where the endpoint
under test would set one
When the client sends <method> <path> with <body>
Then the response status is <status>
And the response body contains no key named password, password_reset_code,
verification_code, verification_expiration or password_reset_expiration
Examples:
| method | path | body | status |
| POST | /v1/auth/login | {"username":"alice","password":"hunter2example12"} | 200 |
| POST | /v1/auth/logout | {} | 200 |
| POST | /v1/auth/password-reset | {"email":"alice@example.com"} | 200 |
| POST | /v1/auth/password-reset/confirm | {"email":"alice@example.com","code":"wrong","password":"hunter2example12"} | 403 |