Block SSRF on ExternalProvider fetches - #40
Open
jzongker wants to merge 2 commits into
Open
Conversation
Co-authored-by: Jeremy Zongker <jzongker@users.noreply.github.com>
Co-authored-by: Jeremy Zongker <jzongker@users.noreply.github.com>
jzongker
marked this pull request as ready for review
August 16, 2026 19:44
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Anonymous ExternalProvider routes were doing
axios.get(ep.apiUrl)and a second hop tovenue.apiUrlfrom that JSON, with no scheme/host checks, no private-IP block, and default redirect following.What changed
fetchProviderJson.maxRedirects: 0).*.lessons.churchhost.Why this shape
LessonsApp portal/player callers use
/externalProviders/:id/lessons,/playlist/..., and venue plan/action routes. First-party trees and venue feeds live onapi.lessons.church(and staging). Churches can also add Open Lesson Format feeds on their own hosts, so the first hop allows any public HTTPS DNS name after the IP checks. A hostile provider document cannot send the Lambda to an internal URL or to a different public host.Public playlist/player routes stay anonymous; they only fetch URLs that pass the same checks.
Not in this PR
FreeShow and SignPresenter are untouched.
Do not merge until reviewed.