Skip to content

fix(opds): add request bounds and Argon2 concurrency limits - #154

Draft
phildenhoff wants to merge 1 commit into
opds-9-genresfrom
opds-10-hardening
Draft

phildenhoff wants to merge 1 commit into
opds-9-genresfrom
opds-10-hardening

Conversation

@phildenhoff

@phildenhoff phildenhoff commented Sep 18, 2026 •

Copy link
Copy Markdown
Member

Why

The v1 server had no limits. Every Basic-auth attempt ran a fresh Argon2 hash, requests had no size or time bounds, and nothing capped concurrent work — one busy or hostile client could pin the CPU or pile up connections indefinitely.

What changed

  • Feeds time out after 30 seconds with a 503. Asset downloads are deliberately untimed — a slow reader pulling a large book shouldn't be cut off mid-transfer.
  • Request bodies are capped at 16 KiB; feeds are GETs, so anything shipping a body is malformed.
  • A pool of 64 request permits is shared across every listener; exhausted requests get 503 + Retry-After instead of stacking up.
  • Argon2 password verification runs under a 3-permit semaphore. Excess auth attempts are rejected with 503 + Retry-After without hashing — covered by a test that drains the permits and asserts no hash runs and no result is cached.
  • Path-traversal tests pin book-file format handling (..%2f, %2e%2e%2f… must not escape the book directory), and bind failures map PermissionDenied to its own error code instead of a generic unexpected.

Honest note: all of these guards engage after headers arrive, so slowloris-style slow-header connections are a known, deferred gap.

Validation: the stack tip runs 62 citadel-opds tests + 348 workspace tests, all green.

Stack: #146 → #147 → #148 → #149 → #150 → #151 → #152 → #153 → #154 (this) → #155

@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 83.86%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 83.86%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 83.86%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 84.01%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 84.01%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 84.01%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 84.01%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 84.01%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 84.01%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

fix(opds): cap Argon2 concurrency and request pressure

Merge-blocking hardening from the v1 review:
- Limit concurrent password verifications to 3 permits; excess requests
  get 503 with Retry-After without hashing or caching the header
- Bound catalog feeds with a 30s timeout, 16KiB request-body limit, and a
  shared 64-request permit pool; asset downloads stay untimed
- Reject link-local explicit listener addresses in the headless server and
  assert advertised URLs are IPv4-first without link-local entries
- Note in the Sharing pane that generated passwords are shown once and
  travel unencrypted
@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 84.01%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

@github-actions

Copy link
Copy Markdown

libcalibre Test Coverage Report

Overall coverage: 84.01%

📊 Download HTML Report

Coverage breakdown available in the artifacts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant