Skip to content

IBX-11681: Added filename validation in DownloadController and corresponding tests#756

Open
wiewiurdp wants to merge 4 commits into
4.6from
IBX-11681-Possibility-to-download-all-files-using-a-loop-which-may-cause-DDoS
Open

IBX-11681: Added filename validation in DownloadController and corresponding tests#756
wiewiurdp wants to merge 4 commits into
4.6from
IBX-11681-Possibility-to-download-all-files-using-a-loop-which-may-cause-DDoS

Conversation

@wiewiurdp

@wiewiurdp wiewiurdp commented May 25, 2026

Copy link
Copy Markdown
Contributor
🎫 Issue IBX-11681

Description:

Added filename validation to the content download endpoint for binary files.

Previously, /content/download/{contentId}/{fieldIdentifier}/{filename} accepted any filename value from the URL and still returned the file as long as contentId and fieldIdentifier matched an accessible field. This made it possible to enumerate downloadable files more easily by guessing content identifiers and reusing common field identifiers such as file.

This change makes the download controller verify that the filename provided in the URL matches the actual file name stored in the field value. If it does not match, the controller now returns a generic 404 response before loading the binary file from storage.

The error handling around download validation was also tightened to avoid leaking information about existing content. Invalid field identifiers, invalid filenames, missing content, unavailable versions, trashed content, and repository-level not found cases are now normalized to the same generic "File not found" response. This prevents the endpoint from revealing whether a guessed content ID exists or which part of the download URL was valid.

@wiewiurdp wiewiurdp force-pushed the IBX-11681-Possibility-to-download-all-files-using-a-loop-which-may-cause-DDoS branch 2 times, most recently from 1ba641c to 93d53c1 Compare May 25, 2026 13:10
@wiewiurdp wiewiurdp marked this pull request as ready for review May 25, 2026 13:49
@wiewiurdp wiewiurdp requested a review from a team May 25, 2026 13:49
@ibexa-workflow-automation-1 ibexa-workflow-automation-1 Bot requested review from Steveb-p, ViniTou, alongosz, barw4, bnowak, ciastektk, konradoboza, mikadamczyk and tbialcz and removed request for a team May 25, 2026 13:49

@mikadamczyk mikadamczyk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add an integration test for URL-encoded filenames here? Since the new check uses strict equality $field->value->fileName !== $filename, any encoding or decoding differences in the real request flow may cause valid downloads to be rejected as NotFound. Especially for spaces or special characters.

@konradoboza konradoboza left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good but I think providing the test case that Mikołaj has mentioned makes sense.

Comment thread tests/lib/MVC/Symfony/Controller/Controller/Content/DownloadControllerTest.php Outdated
@wiewiurdp wiewiurdp force-pushed the IBX-11681-Possibility-to-download-all-files-using-a-loop-which-may-cause-DDoS branch 4 times, most recently from be18b9b to 51d7f2c Compare June 1, 2026 13:26
Comment thread tests/lib/MVC/Symfony/Controller/Controller/Content/DownloadControllerTest.php Outdated
Comment thread tests/lib/MVC/Symfony/Controller/Controller/Content/DownloadControllerTest.php Outdated
Comment thread tests/lib/MVC/Symfony/Controller/Controller/Content/DownloadControllerTest.php Outdated
@konradoboza konradoboza requested a review from mikadamczyk June 1, 2026 14:18
@sonarqubecloud

sonarqubecloud Bot commented Jun 2, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
11.4% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@wiewiurdp wiewiurdp requested a review from konradoboza June 2, 2026 12:31
@konradoboza konradoboza added Bug Something isn't working Ready for QA and removed Ready for review labels Jun 8, 2026
@tomaszszopinski tomaszszopinski force-pushed the IBX-11681-Possibility-to-download-all-files-using-a-loop-which-may-cause-DDoS branch from f62054c to b3c2901 Compare June 30, 2026 09:50
@tomaszszopinski tomaszszopinski self-assigned this Jun 30, 2026
@wiewiurdp wiewiurdp force-pushed the IBX-11681-Possibility-to-download-all-files-using-a-loop-which-may-cause-DDoS branch from d5cfc8f to 0fc0fd4 Compare July 1, 2026 16:29
@sonarqubecloud

sonarqubecloud Bot commented Jul 1, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
9.1% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

throw $this->createFileNotFoundException($e);
}

return $this->downloadBinaryFileAction($contentId, $field->fieldDefIdentifier, $field->value->fileName, $request);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we also need to block or harden the /content/download/{contentId}/{fieldId} route? It seems to bypass the new filename validation because downloadBinaryFileByIdAction() forwards the persisted file name to downloadBinaryFileAction().

@wiewiurdp wiewiurdp Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Blocking/removing it in this PR would likely be BC.

For this PR, I would keep the route available and harden it by normalizing its validation/not-found responses in the same way as the filename-based route, so it does not reveal whether a guessed content/field combination exists.

I agree that deprecating it and eventually moving fully to the filename-based route would be worth considering, but I think that should be handled in a separate task. Wdyt @konradoboza

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

Labels

Bug Something isn't working Ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants