Skip to content

[BUGFIX] OAI-PMH GetRecord always answered idDoesNotExist - #2148

Merged
sebastian-meyer merged 2 commits into
kitodo:mainfrom
stweil:fix/oai-getrecord-missing-uid
Sep 17, 2026
Merged

sebastian-meyer merged 2 commits into
kitodo:mainfrom
stweil:fix/oai-getrecord-missing-uid

Conversation

@stweil

@stweil stweil commented Sep 17, 2026

Copy link
Copy Markdown
Member

The OAI-PMH GetRecord verb failed for every valid identifier with the error "idDoesNotExist" because the record lookup query no longer selected the document's uid. The controller checks empty($document['uid']) to detect a missing record, so a found record without a uid column was treated as not existing.

Restore the uid to the SELECT list of getOaiRecord() and getOaiDocumentList(). Add functional tests for the GetRecord verb, including the success case and the unknown-identifier and unknown-metadataPrefix error cases, which previously had no coverage.

Assisted-by: OpenCode / qwen3.8-27b-thinking (Alibaba Cloud)
Fixes: 05c90ac ("[MAINTENANCE] Refactor OAI-PMH queries to...")

The OAI-PMH GetRecord verb failed for every valid identifier with the
error "idDoesNotExist" because the record lookup query no longer
selected the document's uid. The controller checks
empty($document['uid']) to detect a missing record, so a found record
without a uid column was treated as not existing.

Restore the uid to the SELECT list of getOaiRecord() and
getOaiDocumentList(). Add functional tests for the GetRecord verb,
including the success case and the unknown-identifier and
unknown-metadataPrefix error cases, which previously had no coverage.

Assisted-by: OpenCode / qwen3.8-27b-thinking (Alibaba Cloud)
Fixes: 05c90ac ("[MAINTENANCE] Refactor OAI-PMH queries to...")
Signed-off-by: Stefan Weil <sw@weilnetz.de>
@stweil

stweil commented Sep 17, 2026

Copy link
Copy Markdown
Member Author

@sebastian-meyer, yesterday we updated our installation on digi.bib.uni-mannheim.de and noticed the OAI-PMH regression (fixed now with this code).

This regression had an interesting side effect: it caused outages of our web server for several hours during last night, so users could no longer view our digitisations. The SLUB DFG viewer tried to access OAI records on our server. Because of the regression, this failed. Then the SLUB server retried the failed access many times (which amplified the load) before giving up. Normally our protection would have blocked external IP addresses which send several requests per second over a longer time, but I had put your server on the exception list.

Even with the bug fix, I see a remaining problem. Anyone can misuse DFG viewer (or maybe any installation of Kitodo.Presentation) for denial of service attacks against any institution which provides OAI/PMH by calling it with a valid OAI URL, but using an invalid record identifier.

Here is a typical example from the Apache access log (in this case triggered by me with a single request to the DFG viewer):

194.95.145.4 - - [17/Sep/2026:07:40:04 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5320 "-" "TYPO3"194.95.145.4 - - [17/Sep/2026:07:40:05 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:05 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5322 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:06 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:07 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:08 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:08 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5322 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:09 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5320 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:09 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5322 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:10 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5320 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:11 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5322 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:11 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:12 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5320 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:13 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5322 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:14 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:14 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:16 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:17 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5320 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:17 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:18 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:19 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:19 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:20 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:21 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:21 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:22 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:22 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5320 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:23 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:24 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:24 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5320 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:25 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:26 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5320 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:26 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5322 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:27 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5321 "-" "TYPO3"
194.95.145.4 - - [17/Sep/2026:07:40:27 +0200] "GET /oai/?verb=GetRecord&metadataPrefix=mets&identifier=1234567890 HTTP/1.1" 200 5322 "-" "TYPO3"

Update: see PR #2149 which fixes this now on our server.

@codecov

codecov Bot commented Sep 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0.00%. Comparing base (5ba4292) to head (d5d269c).

Additional details and impacted files
@@     Coverage Diff      @@
##   main   #2148   +/-   ##
============================
============================

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread Tests/Functional/Api/OaiPmhTest.php Outdated
@sebastian-meyer
sebastian-meyer merged commit 6b6b8c6 into kitodo:main Sep 17, 2026
10 checks passed
@stweil
stweil deleted the fix/oai-getrecord-missing-uid branch September 17, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

☇ bug A non-security related bug.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants