Summary
The OTP service endpoints (POST /account/otp/issue and POST /account/otp/redeem) are used by Lenny to implement patron passwordless login. Lenny already sends Authorization: LOW <access>:<secret> headers on every OTP call (via ol_auth_headers()), but OL currently ignores these headers.
This means any caller — including rogue or unconfigured Lenny instances — can use OL's OTP service to send unsolicited OTP emails to any address.
Proposed Change
Add S3 key validation at the start of both OTP handler methods. Use the existing InternetArchiveAccount.s3auth() to validate the caller's IA credentials before processing the request.
Required: Authorization: LOW <access>:<secret> header with valid IA S3 keys.
If the header is missing or the keys are invalid, return {"error": "unauthorized"} (HTTP 403).
This ensures that only Lenny instances that have been configured with valid IA S3 credentials (i.e., linked to an IA/OL account via make ol-login) can trigger OTP emails.
Files to Change
openlibrary/plugins/upstream/account.py — otp_service_issue.POST() and otp_service_redeem.POST()
- (optional) Extract
_parse_s3_auth_header() as a module-level helper (same pattern already exists on account_anonymize._parse_auth_header())
Companion Issue
Related
Summary
The OTP service endpoints (
POST /account/otp/issueandPOST /account/otp/redeem) are used by Lenny to implement patron passwordless login. Lenny already sendsAuthorization: LOW <access>:<secret>headers on every OTP call (viaol_auth_headers()), but OL currently ignores these headers.This means any caller — including rogue or unconfigured Lenny instances — can use OL's OTP service to send unsolicited OTP emails to any address.
Proposed Change
Add S3 key validation at the start of both OTP handler methods. Use the existing
InternetArchiveAccount.s3auth()to validate the caller's IA credentials before processing the request.Required:
Authorization: LOW <access>:<secret>header with valid IA S3 keys.If the header is missing or the keys are invalid, return
{"error": "unauthorized"}(HTTP 403).This ensures that only Lenny instances that have been configured with valid IA S3 credentials (i.e., linked to an IA/OL account via
make ol-login) can trigger OTP emails.Files to Change
openlibrary/plugins/upstream/account.py—otp_service_issue.POST()andotp_service_redeem.POST()_parse_s3_auth_header()as a module-level helper (same pattern already exists onaccount_anonymize._parse_auth_header())Companion Issue
Related
/account/login/otp/*endpoints, unaffected by this change)