generated from bisco/codex-bootstrap
fix(security): separate booking and check-in tokens
This commit is contained in:
@@ -204,7 +204,7 @@ Response `200 OK`:
|
||||
"reservation_id": 123,
|
||||
"status": "confirmed",
|
||||
"party_size": 2,
|
||||
"qr_code_url": "https://example.org/api/reservations/123/qr-code/"
|
||||
"qr_code_url": "https://example.org/api/check-ins/preview/?token=opaque-check-in-token"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -222,13 +222,14 @@ Status codes:
|
||||
GET /api/reservations/{id}/qr-code/
|
||||
```
|
||||
|
||||
Returns the generated QR code for a confirmed reservation. Access must be protected by a valid QR token, signed URL, or equivalent control so that reservation IDs are not enough to retrieve QR codes.
|
||||
Returns the generated QR code for a confirmed reservation. Access must be protected by a valid opaque `check_in` token, signed URL, or equivalent control so that reservation IDs are not enough to retrieve QR codes.
|
||||
|
||||
Response `200 OK`:
|
||||
|
||||
```json
|
||||
{
|
||||
"reservation_id": 123,
|
||||
"qr_code_url": "https://example.org/api/check-ins/preview/?token=opaque-check-in-token",
|
||||
"qr_code_image": "data:image/png;base64,...",
|
||||
"printable": true
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ Availability shown to visitors is informational. The backend recalculates availa
|
||||
- requested seats do not exceed currently available seats.
|
||||
6. The backend creates a `pending` reservation.
|
||||
7. The backend creates a random opaque confirmation token.
|
||||
8. The backend sends an email with a confirmation link.
|
||||
8. After the transaction commits successfully, the backend sends an email with a confirmation link.
|
||||
9. The frontend tells the visitor to check their email.
|
||||
|
||||
The reservation is not confirmed at this stage.
|
||||
@@ -45,8 +45,8 @@ The reservation is not confirmed at this stage.
|
||||
6. The backend recalculates confirmed reservations for the performance.
|
||||
7. The backend confirms the reservation only if enough seats remain.
|
||||
8. The backend marks the confirmation token as used.
|
||||
9. The backend creates a QR verification token.
|
||||
10. The backend generates a QR code containing the opaque QR token or a verification URL.
|
||||
9. The backend creates a separate `check_in` token for QR verification.
|
||||
10. The backend generates a QR code containing only the opaque check-in token or a verification URL built from that token.
|
||||
11. The backend returns or sends the QR code to the visitor.
|
||||
|
||||
If there is no longer enough capacity, the backend must not confirm the reservation.
|
||||
@@ -111,7 +111,7 @@ This operational flow should still follow the same backend rules as the public b
|
||||
2. the backend validates booking availability and capacity;
|
||||
3. the backend creates a `pending` reservation;
|
||||
4. the backend creates the normal confirmation token;
|
||||
5. the backend sends the standard confirmation email;
|
||||
5. after the reservation transaction commits, the backend sends the standard confirmation email;
|
||||
6. the guest still confirms through the email link before the reservation becomes confirmed and usable for check-in.
|
||||
|
||||
## Duplicate Check-In
|
||||
|
||||
@@ -36,6 +36,9 @@ Rules:
|
||||
- do not encode personal data in tokens;
|
||||
- store token hashes when practical;
|
||||
- treat raw tokens as secrets;
|
||||
- keep confirmation tokens and check-in tokens separate by purpose;
|
||||
- allow confirmation tokens only for reservation confirmation;
|
||||
- allow check-in tokens only for QR retrieval and check-in validation;
|
||||
- mark one-time confirmation tokens as used after successful confirmation;
|
||||
- expire confirmation tokens after a reasonable period;
|
||||
- keep QR tokens valid only for the intended performance and check-in period where practical.
|
||||
@@ -165,7 +168,7 @@ Do not log:
|
||||
|
||||
Initial residual risks:
|
||||
|
||||
- synchronous email can make booking responses depend on SMTP availability;
|
||||
- synchronous email after commit can still add latency to booking requests even though it no longer runs inside the reservation transaction;
|
||||
- QR codes can be copied, so duplicate check-in prevention must be reliable;
|
||||
- staff account compromise would expose admin and check-in functionality;
|
||||
- retention and deletion rules for personal data still need a project policy.
|
||||
|
||||
Reference in New Issue
Block a user