Skip to content

feat(accounts): Validate caller IA S3 keys on OTP service endpoints to restrict access to authorized Lenny instances #12840

Description

@mekarpeles

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.pyotp_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

Metadata

Metadata

Assignees

Labels

Lead: @cdriniIssues overseen by Drini (Staff: Team Lead & Solr, Library Explorer, i18n) [managed]Priority: 2Important, as time permits. [managed]Theme: Security

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions